Thread: Read file name at console and pass to CreatFile

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    77

    Read file name at console and pass to CreatFile

    Hi,
    I'm working on a C COM/.Net application which requires the use of char and widechar types. One problem I have is to pick-up the name of a file as character (char mandatory) from the console and pass it to CreateFile(), which requires a widechar of LPCTSTR type. I've used the mbstowcs() function, I did all the checks with what I enter and what I get, it gives me back a wrong file handle from CreateFile() (error 123 - file length issue). If I initialize the file name in code - as char - then use the conversion, it works. Therefore there is a problem with the console read, but it's strange. Any idea? Many thanks!

  2. #2
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    How are you reading the file name? Chances are you've got a stray new line or carriage return at the end of the buffer, or some other illegal characters in the file name.

    Without knowing what is input, and how it is read from the console, it's gonna be impossible to give a concrete answer.

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    77
    Many thanks for your meaningful message. The following validates your assumption and I think there’s a capital mistake I’m doing somewhere with fgets(); I have also tried fgetws() and have same problem.
    This is the code that works :

    char filePathString[MAX_PATH];// The file name I should enter from console
    wchar_t *logFileString; // The file name (LPCTSTR type) for CreateFile()
    ……………………………..
    char tasty[] = "c:\\myfilepath.dat"; // To make it working I hardcode the file name

    logFileString = (wchar_t *)malloc(((strlen(tasty) + 1) * sizeof(wchar_t) )); // Make room for the file name to pass to CreateFile()

    mbstowcs(logFileString, tasty, (strlen(tasty) + 1)); // This function converts from character string to wide character string. Works fine

    hLogFile = CreateFile(logFileString,// Name of the Log file to open/create
    GENERIC_WRITE,// Open for writing
    0, // Do not share
    NULL, // Default security
    OPEN_ALWAYS, // Open file in all cases
    FILE_ATTRIBUTE_NORMAL |// Normal file
    FILE_FLAG_NO_BUFFERING | // No System buffer
    FILE_FLAG_WRITE_THROUGH, // Write straight to the disk
    NULL); // That's all folks!
    ………………………………………
    This is the code that doesn’t work (however it should be developed around it):
    char filePathString[MAX_PATH];// The file name I should enter from console
    wchar_t *logFileString; // The file name (LPCTSTR type) for CreateFile()
    ……………………………..
    fgets (filePathString , MaxFilePathName , stdin); // Read from console the full log file name (in fact this way it doesn’t work)

    logFileString = (wchar_t *)malloc(((strlen(tasty) + 1) * sizeof(wchar_t) )); // Make room for the file name to pass to CreateFile()

    mbstowcs(logFileString, tasty, (strlen(tasty) + 1)); // This function converts from character string to wide character string. Works fine

    hLogFile = CreateFile(logFileString,// Name of the Log file to open/create
    GENERIC_WRITE,// Open for writing
    0, // Do not share
    NULL, // Default security
    OPEN_ALWAYS, // Open file in all cases
    FILE_ATTRIBUTE_NORMAL |// Normal file
    FILE_FLAG_NO_BUFFERING | // No System buffer
    FILE_FLAG_WRITE_THROUGH, // Write straight to the disk
    NULL); // That's all folks!
    ………………………………………
    If I print the fgets() output value - i.e. filePathString – I have displayed the “right” name I entered, but CreateFile() returns a code error 123 which says that file name length is incorrect.
    If it were by me I would have all coded in widechar, but the application already exists with a lot of code in char. As I said, using mbstowcs()solves me half of the migration to Unicode. The other half is to properly use the console data acquisition functions.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Posts
    77
    Oups! In the second example - which doesn' work - of course that "tasty" sould be replaced with "filePathString". Sorry for inconvenience (typing error).

  5. #5
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Like adeyblue said, you have the newline stuck to the end of the buffer read from the console, which causes your error. This works just fine:
    Code:
    #include <windows.h>
    #include <stdio.h>
    
    int main()
    {
    	char fileName[MAX_PATH] = { 0 };
    	printf("Enter filename to create: ");
    	fgets(fileName, ARRAYSIZE(fileName), stdin);
    	// Without the following line, the newline is still attached.
    	fileName[strlen(fileName) - 1] = '\0';
    	wchar_t wideFileName[MAX_PATH];
    	mbstowcs(wideFileName, fileName, ARRAYSIZE(wideFileName));
    
    	HANDLE h = CreateFile(wideFileName, 
    		GENERIC_WRITE,// Open for writing
    		0, // Do not share
    		NULL, // Default security
    		OPEN_ALWAYS, // Open file in all cases
    		FILE_ATTRIBUTE_NORMAL |// Normal file
    		FILE_FLAG_NO_BUFFERING | // No System buffer
    		FILE_FLAG_WRITE_THROUGH, // Write straight to the disk
    		NULL); // That's all folks!
    	if (INVALID_HANDLE_VALUE == h)
    	{
    		printf("Error: %lu\n", GetLastError());
    	}
    	return 0;
    }

  6. #6
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Do you have to use fgets? You could do away with the char->wchar conversion completely if you use fgetws, which will get the input as wide characters.

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    77
    Thanks gents!
    Rags points to what had to be done, and it works fine since ... it's obvious! Only that we need sometime to be restful for a right reasoning ;-).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. writing to a binary file
    By Inver28 in forum C Programming
    Replies: 4
    Last Post: 03-02-2008, 02:36 AM
  2. need help on how to start
    By tezr87 in forum C++ Programming
    Replies: 3
    Last Post: 06-01-2006, 10:46 AM