如何从GetOpenFileNameA返回一个字符串

Don*_*uck 0 c windows winapi

这是一个在Windows中打开文件对话框并返回带有文件名的字符串的函数:

#include <windows.h>
#include <commdlg.h>
#include <string.h>
char* openFileDlg(char FileTypes[]);
char* openFileDlg(char FileTypes[]){
    OPENFILENAME ofn;
    char szFile[260];
    HWND hwnd;
    HANDLE hf;
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwnd;
    ofn.lpstrFile = szFile;
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(szFile);
    strcpy(ofn.lpstrFilter,FileTypes);
    ofn.nFilterIndex = 1;
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    if(GetOpenFileNameA(&ofn)){
        char *toReturn;
        sprintf(toReturn,"%s",ofn.lpstrFile);
        return toReturn;
    }
    else{
        return NULL;
    }
}
Run Code Online (Sandbox Code Playgroud)

当我调用此函数并打开文件时,进程结束并返回值3(这意味着存在错误).我怎么能这样做,这个函数返回一个包含所选文件路径的字符串?

编辑:我已将我的代码更改为此,但仍然无效:

#include <windows.h>
#include <commdlg.h>
#include <string.h>
void openFileDlg(char *toReturn[],char FileTypes[]);
void openFileDlg(char *toReturn[],char FileTypes[]){
    OPENFILENAME ofn;
    /*
    Code for the settings of the GetOpenFileNameA, irrelevant in this question.
    If you really need to know what's here, look at the code above.
    */
    if(GetOpenFileNameA(&ofn)){
        strcpy(*toReturn,ofn.lpstrFile);
    }
    else{
        sprintf(*toReturn,"");
    }
}
Run Code Online (Sandbox Code Playgroud)

我还应该说,如果我按下打开文件对话框中的取消按钮而不是选择文件,它可以正常工作.经过一些测试,我注意到它strcpy(*toReturn,ofn.lpstrFile);是导致错误的线.

Som*_*ude 5

指针变量toReturn没有指向任何地方,在没有初始化的情况下以任何方式使用它(即使它指向某个有效且足够大的地方)将导致未定义的行为

你有两个解决方案:

  1. 动态分配内存并返回指向该内存的指针.这当然要求调用者在完成操作时释放内存.

  2. 让函数接受另外两个参数:指向缓冲区的指针和缓冲区的长度.然后将字符串复制到该缓冲区中,并返回布尔"true"或"false"成功/失败状态.

我推荐第二个解决方案.

在一个不相关的说明中,没有必要sprintf在你的情况下使用昂贵的功能,一个简单的strcpy(strncpy如果你使用第二个解决方案)将会这样做.

在两种情况下,您还必须记住strlen,对于终止'\0'字符,C中的字符串的实际长度比例如报告的长度多1 .