C++ MFC reading Cstring from editbox for file reading(std::filesystem Exception unhandled memory problem)

C++ MFC reading Cstring from editbox for file reading (std::filesystem Exception unhandled memory problem)

我的代码应该实现的是在给定文件路径输入和输出后读取文件名(开关1:同一文件夹下的文件)(开关2:目录下的所有文件名,包括子目录),并且不将文件夹名存储到vector中(1.png 2.png 3.png但不是ChildFolder)。

如果您需要有关文件夹结构的额外信息,可以在我的 previous question.

中找到
#define IDC_RADIO1                      1000
#define IDC_RADIO2                      1001
#define IDC_EDIT1                       1002
#define IDC_BUTTON1                     1003
#define IDC_LIST1                       1004

This window app 有 2 个单选框,1 个用户输入路径名的编辑框,1 个启动整个过程的按钮,1 个列表框显示读取的文件

下面开始主要功能:

void CMFCApplication3Dlg::OnBnClickedButton1()
{
    string a;
    vector<string> caseOne,
                   caseTwo;

最后两行代码是我遇到问题的地方

a = "C:\Users\User... 代码有效,但输出似乎存在数组元素逻辑问题,列表框中的输出为 Nothing,1.png,2.png 而不是 1.png,2.png 编辑说明:这部分现在有效

代码directory_iterator list(str);好像是
引起的内存问题 a = enterPath.GetBuffer(); 我不知道该怎么做才能解决它。

ErrorMessage MFCApplication3.exe 中 0x7525B502 处的未处理异常:Microsoft C++ 异常:std::filesystem::filesystem_error 在内存位置 0x0133E438。

屏幕截图如下

我最好删除 a = "C:\Users\User... 并使用 a = enterP.. 如果可行的话

    a = "C:\Users\User\Desktop\ParentFolder";//This line is used to test code, will move on to having user input to IDC_EDIT1

    //a = enterPath.GetBuffer();//Code I want to use

    path str = a;
    directory_iterator list(str);
    CListBox* listBox = (CListBox*)GetDlgItem(IDC_LIST1);

    UpdateData(TRUE);//update the data
    int checkRadio = GetCheckedRadioButton(IDC_RADIO1, IDC_RADIO2);
    switch (checkRadio)
    {
    case IDC_RADIO1:
        list = directory_iterator(a);                          //reset directory_iterator evertime button clicked to read new file
        for (auto& it : list) {                                //go through the directory_iterator list
            string filename1 = it.path().filename().string();  //get file names then convert filename into string format
            if (filename1.find(".") < filename1.length()/*or != string::npos*/ ) {    // find file name to rule out folders cause files contain '.'

                caseOne.push_back(filename1);       //putting the filenames into the vector
                CString fileunderPath;              //bottom 3 lines of code convert string to CString
                fileunderPath = filename1.c_str();
                listBox->AddString(fileunderPath);
            }
        }
        break;

    //same problem that should be resolved if case 1 is fixed
    case IDC_RADIO2://NOTE: NEED TO ADD CLEAR LISTBOX FUNCTION and vector
        list = directory_iterator(a);
        for (auto& dirEntry : recursive_directory_iterator(a)) {
            string filename2 = dirEntry.path().filename().string();
            if (filename2.find(".") != string::npos) { // find file name to rule out folders cause files contain '.'
                caseTwo.push_back(filename2);
            }
        }
        break;
    }
    UpdateData(FALSE);//finish updating the data

}

编辑:

这就是我想要实现的(UI截图)

Working version where I predetermine the folder path for user

This is what I want user to enter

Error message I got

What the folder content looks like

A child folder of the parent folder

The complete code of button 1

我还发现了一个之前没有注意到的新bug,输出的是png.1 png.2 而不是1.png 2.png,这不应该发生,因为我在使用 cout<<; 时让它正常工作。不久前 Working version where I predetermine the folder path for user

经过一些研究,我修改了我的代码,终于让它工作了

//Answer
string a;
CString stri;//Read text from edit control box and convert it to std::string
GetDlgItem(IDC_EDIT1)->GetWindowText(stri);
a = CT2A(stri);

//This code is something I also tried but the string a it passed back is ""
/*CString b;
b = enterPath;//a control variable I added from IDC_EDIT1
a = CT2A(b);*/

关于 filename1.find(".") < filename1.length() 它起作用是因为 find() 传回查找字符的第一个位置

so < filename1.length() 意味着 find() 的 return 不能比它自己的字符串长,当 什么都找不到时 returns -1 if 语句仍然运行,但没有向 AddString 传递任何内容。(这就是为什么它感觉像是创可贴修复)

所以写 if 语句的更好方法是

if(filename1.find(".") != -1)
//or
if(filename1.find(".") != string::npos)//npos is -1

并且由于我找到了一种更好的方法来区分 #include 文件系统中的文件名和文件夹,所以我最终还是删除了上面的代码

因为出于某种原因我认为文件夹名称不能有“。”在他们

//code I switched to 
if(is_regular_file(it))