Запись в .txt с помощью файла записи() C

#c #winapi

Вопрос:

(С использованием C , Windows 10, Microsoft Visual Studio 2017)

Здравствуйте, я новичок в последовательных портах, но пытаюсь научиться открывать, закрывать, читать и писать с их помощью

Прямо сейчас я пытаюсь использовать функции CreateFile() и WriteFile() для записи в txt-файл.

Я создал файл .txt под названием «write.txt» и сохранил его в своей папке «Документы». Затем я добавил его в исходные файлы своего проекта с помощью «Добавить» —> «Существующий элемент». Файл пуст.

Я написал программу ниже, надеясь, что смогу записать ее в файл, но после запуска и последующей проверки файла файл все еще пуст. Программа компилируется, но я предполагаю, что где-то у меня есть ошибка. Правильно ли я собираюсь писать в файл?

 #include <iostream>
#include <Windows.h>
#include <string>
using namespace std;

int main() {
HANDLE write;
    write = CreateFile(TEXT("\write.txt"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (write == INVALID_HANDLE_VALUE) {
        DWORD errorWrite = GetLastError();
        printf("Error in opening filen");
        printf("Error = 0x%xn", errorWrite);
    }
    else {
        printf("Opening file successfuln");
    }
    WriteFile(write, "hello", 5, 0, 0);

    CloseHandle(write);

    return 0;
}

 

Вывод говорит, что файл был успешно открыт, но write.txt файл остается пустым. Есть какие-нибудь советы?

Заранее благодарю вас 😀

Комментарии:

1. Вы не получаете доступ к текстовому файлу, расположенному в папке «Документы». Вы получаете доступ к текстовому файлу, расположенному в корневом каталоге диска, на который в данный момент указывает текущий рабочий каталог вызывающего процесса. Вам необходимо явно запросить у операционной системы путь к папке «Документы» (т. Е. через SHGetFolderPath() или SHGetKnownFolderPath() ), а затем добавить имя файла к этому пути.

2. Хм, так стоит ли мне добавить файл .txt в папку, содержащую мои исходные файлы? Я попытался добавить файл .txt в опцию Добавить новый файл, но не смог найти опцию для .txt. Редактировать, только что нашел возможность добавления .txt, должен ли я согласиться с этим ? Попробуйте это сейчас

3. Добавление файла в ваш проект НИКАК НЕ ВЛИЯЕТ на этот код. Похоже, вам нужно узнать, что такое текущий рабочий каталог и как работают относительные пути к файлам во время выполнения.

4. Я вижу, я очень новичок в этом, у вас есть какие-нибудь статьи, которые, как вы знаете, могли бы помочь? Последние пару недель я просматривал веб-страницы в поисках такого рода информации, но трудно понять, что именно искать, поскольку я изучаю это самостоятельно. Кроме того, имеет ли это прямое отношение к последовательным портам? Если я научусь писать в файл .txt, будет ли тот же набор навыков использоваться для записи в порт ? Еще раз спасибо

5. Можно использовать те же API ( CreateFile() для открытия, WriteFile() записи и т. Д.), Но есть и другие требования. Вам следует прочитать о коммуникационных ресурсах на MSDN.

Ответ №1:

Вы не получаете доступ к текстовому файлу, расположенному в папке «Документы». Вы получаете доступ к текстовому файлу, расположенному в корневом каталоге диска, на который в данный момент указывает текущий рабочий каталог вызывающего процесса.

Вам необходимо явно запросить у операционной системы путь к папке «Документы» (т. Е. через SHGetFolderPath() или SHGetKnownFolderPath() ), а затем добавить имя файла к этому пути.

Кроме того, вы звоните WriteFile() неправильно. В частности, lpNumberOfBytesWritten параметр неверен:

lpnumberofbytesписано

Указатель на переменную, которая получает количество байтов, записанных при использовании синхронного hFile параметра. WriteFile устанавливает это значение равным нулю перед выполнением какой-либо работы или проверкой ошибок. Используйте значение NULL для этого параметра, если это асинхронная операция, чтобы избежать потенциально ошибочных результатов.

Этот параметр может быть равен НУЛЮ только в том случае, если lpOverlapped параметр не равен НУЛЮ.

И вы также не выполняете никакой обработки ошибок WriteFile() :

Если функция выполняется успешно, возвращаемое значение не равно нулю (TRUE).

Если функция завершается неудачно или выполняется асинхронно, возвращаемое значение равно нулю (ЛОЖЬ). Чтобы получить расширенную информацию об ошибке, вызовите GetLastError функцию.

Попробуйте вместо этого что-нибудь более похожее:

 #include <iostream>
#include <string>
#include <Windows.h>
#include <Shlobj.h>
#include <shlwapi.h>
using namespace std;

int main() {

    TCHAR path[MAX_PATH] = {};

    HRESULT hRes = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path);
    if (FAILED(hRes)) {
        printf("Can't get Documents folder pathnError = 0xxn", hRes);
    }
    else {
        PathAppend(path, TEXT("write.txt"));

        HANDLE write = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (write == INVALID_HANDLE_VALUE) {
            DWORD errorWrite = GetLastError();
            printf("Can't open filenError = %un", errorWrite);
        }
        else {
            printf("File opened successfuln");

            DWORD written;
            if (!WriteFile(write, "hello", 5, amp;written, NULL)) {
                DWORD errorWrite = GetLastError();
                printf("Can't write to filenError = %un", errorWrite);
            } else {
                printf("File written successfuln");
            }
            CloseHandle(write);
        }
    }

    return 0;
}