Создать файл и что-то в него записать не получается так, как я хотел

Я пишу следующий код:

      #include <windows.h>
      #include "stdbool.h"
      #include <winuser.h>
      #include <WinDef.h>
      #include <Winerror.h>
      #include <stdio.h>
      #include <Strsafe.h>

      #define MAX_SIZE 100


         void DisplayError(LPTSTR lpszFunction) 
         // Routine Description:
        // Retrieve and output the system error message for the   last-error code
        { 
          LPVOID lpMsgBuf;
          LPVOID lpDisplayBuf;
          DWORD dw = GetLastError(); 

         FormatMessage(
                    FORMAT_MESSAGE_ALLOCATE_BUFFER | 
                    FORMAT_MESSAGE_FROM_SYSTEM |
                    FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    dw,
                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                    (LPTSTR) &lpMsgBuf,
                     0, 
                     NULL );

            lpDisplayBuf = 
               (LPVOID)LocalAlloc( LMEM_ZEROINIT, 
                        ( lstrlen((LPCTSTR)lpMsgBuf)
                          + lstrlen((LPCTSTR)lpszFunction)
                          + 40) // account for format string
                        * sizeof(TCHAR) );

if (FAILED( StringCchPrintf((LPTSTR)lpDisplayBuf, 
                 LocalSize(lpDisplayBuf) / sizeof(TCHAR),
                 TEXT("%s failed with error code %d as follows:\n%s"), 
                 lpszFunction, 
                 dw, 
                 lpMsgBuf)))
{
    printf("FATAL ERROR: Unable to output error code.\n");
}

printf(TEXT("ERROR: %s\n"), (LPCTSTR)lpDisplayBuf);

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);

   }


   int main(){
    //parameters of CreateFile()
     HANDLE hFile;  
     LPCTSTR lpFileName; 
     DWORD dwDesiredAccess; 
     DWORD dwShareMode;
     LPSECURITY_ATTRIBUTES lpSecurityAttributes;
     DWORD dwCreationDisposition; 
     DWORD dwFlagsAndAttributes; 
     HANDLE hTemplateFile; 

     //parameters of WriteFile()

     DWORD nNumberOfBytesToWrite;
     DWORD numberOfBytesWritten;
     LPOVERLAPPED lpOverlapped;
     char DataBuffer[MAX_SIZE];

     //others
     BOOL bErrorFlag; 

     //initialize args of CreateFile()
     lpFileName = "C:\\file.txt";
     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
     dwShareMode = 0;
     lpSecurityAttributes = NULL;
     dwCreationDisposition = CREATE_NEW;
     dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; 
     hTemplateFile = NULL; 

     //initialize args of WriteFile()
     strcpy(DataBuffer, "This is the test file");
     nNumberOfBytesToWrite = (DWORD)strlen(DataBuffer);
     numberOfBytesWritten = 0;
     lpOverlapped = NULL;





   hFile = CreateFile(lpFileName, dwDesiredAccess, dwShareMode,
                    lpSecurityAttributes, dwCreationDisposition, 
                    dwFlagsAndAttributes, hTemplateFile);


if (hFile == INVALID_HANDLE_VALUE) 
{ 
    DisplayError(TEXT("CreateFile"));
    printf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), lpFileName);
    return;
}

printf(TEXT("Writing %d bytes to %s.\n"), nNumberOfBytesToWrite, lpFileName);

bErrorFlag = WriteFile(hFile, DataBuffer, nNumberOfBytesToWrite,
         &numberOfBytesWritten, lpOverlapped);
if (FALSE == bErrorFlag)
{
    DisplayError(TEXT("WriteFile"));
    printf("Terminal failure: Unable to write to file.\n");
}
else
{
    if (numberOfBytesWritten != nNumberOfBytesToWrite)
    {
        // This is an error because a synchronous write that results in
        // success (WriteFile returns TRUE) should write all data as
        // requested. This would not necessarily be the case for
        // asynchronous writes.
        printf("Error: dwBytesWritten != dwBytesToWrite\n");
    }
    else
    {
        printf(TEXT("Wrote %d bytes to %s successfully.\n"), numberOfBytesWritten, lpFileName);
    }
}

CloseHandle(hFile);
}

Итак, как видите. Программа, которая должна создать на рабочем столе файл с именем file.txt и записать в него небольшой текст. Я использую Microsoft Visual C++ Express, он компилируется без ошибок.. но когда я запускаю его, нажав зеленую кнопку воспроизведения, я вижу, что на моем рабочем столе не создан такой файл.

При поиске возможных ошибок я также прочитал https://msdn.microsoft.com/en-us/library/windows/desktop/bb540534%28v=vs.85%29.aspx, что они используют почти один и тот же код. За исключением того, что я не включаю отображение частей ошибок.

Итак, мой вопрос: в чем может быть причина, почему он не работает? Нужны ли мне (программе) какие-то дополнительные разрешения для этого? Например, я написал то же самое в Ubuntu с помощью open() и write(), за исключением того, что я использую «/tmp/file.txt» в качестве каталога назначения. И работает без дополнительных разрешений.

с уважением,


person user3097712    schedule 14.03.2015    source источник
comment
Просто для удовольствия сделайте включение отображаемых частей ошибки. Что они говорят вам?   -  person Jongware    schedule 14.03.2015
comment
поэтому я добавил части ошибки отображения по ссылке. Но опять же, программа.exe будет завершена с 0 (0x0). ничего не отображается   -  person user3097712    schedule 14.03.2015
comment
Вы должны выполнить компиляцию со всеми предупреждениями и информацией об отладке (например, gcc -Wall -Wextra -g), а затем научиться использовать отладчик (например, gdb).   -  person Basile Starynkevitch    schedule 14.03.2015
comment
я думаю, вы неправильно поняли вопрос. Я не использую Linux Ubuntu для этого. если бы я хотел, поверь мне, я бы ничего не спрашивал :) я пробую то же самое, что я делаю в линуксе, теперь и в винде... но это не работает.... все это отстой в винде   -  person user3097712    schedule 14.03.2015
comment
эта функция: 'void DisplayError(LPTSTR lpszFunction)' может быть заменена на perror() и/или strerror(), обе из которых доступны во всех современных версиях C   -  person user3629249    schedule 14.03.2015


Ответы (2)


Код использует неверный путь к каталогу вашего рабочего стола.

Для Windows 7 (и большинства версий Windows) путь будет таким:

обязательно используйте две обратные косые черты на каждом уровне каталога

C:\Пользователи\имя_пользователя\Рабочий стол

person user3629249    schedule 14.03.2015
comment
черт возьми .... да, это работает !!! Спасибо за ваш полезный комментарий/ответ. Забудьте о чеках или о чем бы то ни было... я понял, что дьявол кроется в деталях. - person user3097712; 14.03.2015
comment
Если это была ошибка, стоящая за вопросом, вам может быть интересно найти рабочий стол программно: stackoverflow.com/questions/17933917/ - person Jongware; 15.03.2015

Это неправильный способ написать имя файла

"C:\Desktop\file.txt";

вам нужно экранировать '\', \f на самом деле является escape-последовательностью

"C:\\Desktop\\file.txt";

а также, по-видимому, файл не будет создан на вашем рабочем столе, попробуйте вместо этого

"C:\\file.txt";

и проверьте свой диск C:, чтобы увидеть файл.

person Iharob Al Asimi    schedule 14.03.2015
comment
спасибо, я добавил это (оба ваших ответа), но в обоих случаях это все еще не работает. Я не вижу файла на C или на рабочем столе. В окне отладки я все еще получаю сообщение о том, что загружены все dll, такие как ntdll и т. д., но в последней строке говорится, что код завершается с 0 (0x0) - person user3097712; 14.03.2015
comment
0 (0x0) означает успех, должно произойти что-то еще, я вижу, что в вашем коде отсутствует проверка успеха после CreateFile(), а также, если вы учитесь, вы должны использовать стандартные функции, такие как fopen(filename, "w");, чтобы открыть файл для записи, который будет создан, если он не существует . - person Iharob Al Asimi; 14.03.2015
comment
хм, так я получаю сообщение об успешном завершении IDE, хотя оно не создано? странный. Да, я опускаю чеки, потому что хотел, чтобы они были как можно меньше, не создавая больших накладных расходов при первой попытке с окнами. - person user3097712; 14.03.2015
comment
Среде IDE все равно, была ли она создана или нет, это ваша программа, которая сообщает об успехе, и вы должны проверить ее на наличие ошибок самостоятельно. - person Iharob Al Asimi; 14.03.2015
comment
теперь я немного отредактировал свой код. Я поставил оператор if, как вы можете видеть. Теперь в окне отладки написано, что программа.exe завершается с кодом 259 (0x103). - person user3097712; 14.03.2015