簡體   English   中英

當我使用 gcc 時,一個函數可以工作,但是當我使用 Microsoft Visual Studio 的編譯器時,它什么也不做

[英]A function works when I use gcc, but when I use Microsoft Visual Studio's compiler it does nothing

當我使用 code:blocks 使用gcc運行它時,如果它不存在,它會在 F 上創建registration.txt並寫入密碼和用戶名,但是當我使用 Microsoft Visual Studio 的編譯器在我的項目中使用它時,它什么也不做。

例如,如果我調用這個函數,例如: Write("JohnDoe", "password123") ,在文件registration.txt 中應該出現在一行中: JohnDoe, password123

const char *FILEPATH = "F:\\registration.txt";

int Write(char *username, char *password) {
    if (username == NULL || password == NULL) {
        return -1;
    }
    BOOL error = TRUE;
    size_t lengthUsername = strlen(username);
    size_t lengthPassword = strlen(password);
    LPDWORD bytesUsernameWritten = 0;
    char comma[2] = ",";
    char newLine[3] = "\r\n";
    LPDWORD bytesPasswordWritten = 0;
    LPDWORD bytesWrittenComma = 0;
    //if the file doesn't exist, we create it
    HANDLE file = CreateFile((LPCWSTR)FILEPATH, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    if (file == INVALID_HANDLE_VALUE) {
        if (GetLastError() != ERROR_FILE_EXISTS) {
            printf("0x%x", GetLastError());
            CloseHandle(file);
            return -1;
        }  //the file exist, we try to create it
        file = CreateFile((LPCWSTR)FILEPATH, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (file == INVALID_HANDLE_VALUE) {
            printf("Couldn't open the file. Error : 0x%x", GetLastError());
            CloseHandle(file);
            return -1;
        }
    }

    //We try to write the username and the password in file, each combination on each line, in this format: username, password

    error = WriteFile(file, username, (DWORD)lengthUsername, bytesUsernameWritten, NULL);
    if (error == FALSE) {
        printf("The username couldn't have been written. Error 0x%x\n", GetLastError());
        CloseHandle(file);
        return -1;
    }
    error = WriteFile(file, comma, 1, bytesWrittenComma, NULL);
    if (error == FALSE) {
        printf("The comma couldn't have been written. Error 0x%x\n", GetLastError());
        CloseHandle(file);
        return -1;
    }
    error = WriteFile(file, password, (DWORD)lengthPassword, bytesPasswordWritten, NULL);
    if (error == FALSE) {
        printf("The password couldn't have been written. Error 0x%x\n", GetLastError());
        CloseHandle(file);
        return -1;
    }
    error = WriteFile(file, newLine, 2, bytesPasswordWritten, NULL);
    if (error == FALSE) {
        printf("The endline couldn't have been written. Error 0x%x\n", GetLastError());
        CloseHandle(file);

        return -1;
    }
    CloseHandle(file);
    return 0;
}

您的主要問題是使用 Unicode 和 ASCII 之間的混淆。

所有采用字符串參數的 Windows API 函數都有兩種版本:一種適用於LPCSTR ,另一種適用於LPCWSTR

你可以投char *LPCSTR和使用ASCII版本CreateFileA ,但你不能將它轉換為LPCWSTR並使用CreateFileW - Unicode版本CreateFile ,因為它預計UCS-16編碼,其中每個字符占用2個字節的字符串。

調用哪個版本的函數取決於編譯器標志。 對於 Windows 上的 CodeBlocks,默認使用 ASCII 版本,因此您的函數可以工作。 對於 VS,默認值是 Unicode,因此文件路徑字符串會混亂並且不會創建文件。

此外,您還有另外兩個錯誤:

  1. 您錯誤地使用了WriteFile
    第四個參數是一個指針, WriteFile存儲寫入的字節數。

    您正在傳遞 NULL 指針,因為您將bytesUsernameWritten等變量設置為 0。但根據MS 文檔,如果最后一個參數lpOverlapped不是 NULL,則只能在那里使用 NULL。

    您應該做的是將bytesUsernameWritten聲明為 DWORD 並使用&運算符傳遞其地址。
    否則,即使函數成功創建文件,您也不會獲得寫入的字節數。

  2. 您正在嘗試關閉INVALID_HANDLE_VALUE
    這是不必要的,但幸運的是它不會使您的程序崩潰。

最后,沒有理由嘗試調用CreateFile兩次。 只需使用一個帶有OPEN_ALWAYS參數的調用。 這將打開一個現有文件,但如果該文件不存在,它將自動創建它而不是失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM