这是一个在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);是导致错误的线.
指针变量toReturn没有指向任何地方,在没有初始化的情况下以任何方式使用它(即使它指向某个有效且足够大的地方)将导致未定义的行为
你有两个解决方案:
动态分配内存并返回指向该内存的指针.这当然要求调用者在完成操作时释放内存.
让函数接受另外两个参数:指向缓冲区的指针和缓冲区的长度.然后将字符串复制到该缓冲区中,并返回布尔"true"或"false"成功/失败状态.
我推荐第二个解决方案.
在一个不相关的说明中,没有必要sprintf在你的情况下使用昂贵的功能,一个简单的strcpy(strncpy如果你使用第二个解决方案)将会这样做.
在两种情况下,您还必须记住strlen,对于终止'\0'字符,C中的字符串的实际长度比例如报告的长度多1 .