当我使用gcc时,一个函数可以工作,但是当我使用Microsoft Visual Studio的编译器时,它什么都不做

问题描述 投票:1回答:1

当我使用代码: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;
}
c handle createfile
1个回答
4
投票

您的主要问题是使用Unicode和ASCII之间的混淆。

所有采用字符串参数的Windows API函数都有两个版本:一个适用于LPCSTR,另一个适用于LPCWSTR

您可以将char *强制转换为LPCSTR并使用ASCII版本CreateFileA,但是您无法将其强制转换为LPCWSTR并使用CreateFileW - CreateFile的Unicode版本,因为它需要UCS-16编码中的字符串,其中每个字符占用2个字节。

调用哪个版本的函数取决于编译器标志。对于Windows上的CodeBlocks,默认使用ASCII版本,因此您的功能有效。对于VS,默认值为Unicode,因此文件路径字符串变得混乱并且不会创建文件。

此外,您还有两个其他错误:

  1. 您正在使用WriteFile错误。 第四个参数是一个指针,其中WriteFile存储写入的字节数。 您正在传递一个NULL指针,因为您将bytesUsernameWritten等变量设置为0.但是根据MS documentation,如果最后一个参数lpOverlapped不是NULL,则只能使用NULL。 你应该做的是,将bytesUsernameWritten声明为DWORD并使用&运算符传递其地址。 否则,即使函数成功创建文件,也不会获得写入的字节数。
  2. 你正试图关闭INVALID_HANDLE_VALUE 这是不必要的,但幸运的是它不会让你的程序崩溃。

最后,没有理由尝试两次打电话给CreateFile。只需使用OPEN_ALWAYS参数调用一次。这将打开一个现有文件,但如果该文件不存在,它将自动创建它而不是失败。

© www.soinside.com 2019 - 2024. All rights reserved.