MFC C++:如何将某个文件实际保存到系统中,而不仅仅是打开另存为对话框

Posted

技术标签:

【中文标题】MFC C++:如何将某个文件实际保存到系统中,而不仅仅是打开另存为对话框【英文标题】:MFC C++: How to actually save a certain file to the system, not just open a save as dialog box 【发布时间】:2021-02-16 03:37:07 【问题描述】:

我到处搜索,但找不到有关如何将文件实际保存到系统的示例。可以在许多站点中阅读有关打开“保存文件”对话框的主题,但是始终将用户创建的文件成功保存到用户选择的路径中(//在此处添加您的代码)。请多多包涵,因为我是 C++ (MFC) 新手。

我知道我需要实际编写将数据保存到文件路径的代码,但我只是不知道如何。

代码 sn-p(通过 CFileDialog):

void CTryDlg::OnBnClickedSaveAs()

    CFileDialog dlg(FALSE);
    dlg.m_ofn.nMaxFile = MAX_PATH;
    dlg.m_ofn.lpstrFilter = _T("Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0");
    dlg.m_ofn.lpstrTitle = _T("Save File As");
    CString filename;
    if (dlg.DoModal() == IDOK)
    
        filename = dlg.GetPathName(); // return full path and filename
        //write your sample code here to save the file to the user selected path
                                                                                               

通过 GetSaveFileName() 编码 sn-p:

OPENFILENAME SfnInit()

    OPENFILENAME t_sfn;

    char szFileName[MAX_PATH] = "";
    ZeroMemory(&t_sfn, sizeof(t_sfn));
    t_sfn.lStructSize = sizeof(t_sfn);
    t_sfn.hwndOwner = NULL;
    t_sfn.lpstrFilter = _T("Text file\0*.txt\0");
    t_sfn.lpstrFile = szFileName;
    t_sfn.lpstrTitle = _T("Save As\0");
    t_sfn.nMaxFile = MAX_PATH;
    t_sfn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    t_sfn.lpstrDefExt = _T("Text file\0*.txt\0");

    if (GetSaveFileName(&t_sfn2) != true)
    
        AfxMessageBox(_T("Saving file canceled!"));
    
    else
    
        //write your sample code here to save the file to the user selected path
    

任何能够提供一个非常简单的示例代码来实际将用户所需的文件(例如:文本文件)保存到用户选择的路径的人将不胜感激。 我还读到该程序应该以管理员身份运行。

谢谢。

【问题讨论】:

仅当您尝试打开受保护目录中的文件时,才需要以管理员身份运行。你不应该那样做。 查找 MFC 的 CFile 类。它有很好的记录。 @jkb 我会检查一下。谢谢:) std::fstreamfopenCFileCreateFile。可能还有一些我忘记了。 “新手”不是不了解如此基础知识的借口。我的评论很严肃。如果你不能用 C++ 写一个简单的文本文件,你需要一个合适的类,而不是 *** 问题。肯定有一个在线教程可以涵盖它。 【参考方案1】:

由于您使用的是 MFC,我建议您坚持使用 MFC 类来处理此类文件 I/O。

遗憾的是,我使用的是 VS 2008,但这里是 CFile 的类层次结构:

如果它是一个文本文件,使用/派生自 CStdioFile 是有意义的。它具有基本的 ReadString WriteString 方法。

但是,如果您想要序列化从 CDocument(文档/视图架构)派生的内容,您将需要利用流,可能与模式/版本控制一起进行序列化。那是一个完全不同的话题/答案。

编辑:duh - 这是一个简单的 CStdioFile 输出

        CFileDialog fd(FALSE, "txt", "MyFile.txt", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Text files (*.txt)|*.txt|All files (*.*)|*.*", this);
        if (fd.DoModal() == IDOK)
            
            CStdioFile fOut(fd.GetPathName(), CFile::modeCreate | CFile::modeWrite);
            for (int i = 0; i < asData.GetSize(); i++)
                
                fOut.WriteString(asData[i] + '\n');
                
            fOut.Close();
            

【讨论】:

我不同意您的建议(我更喜欢标准函数),但我确实认识到建议中的主观性。这段代码可能会起作用(当然取决于选择的目录) @MSalters 是的,由于无效/权限文件夹等原因,ctor 肯定会抛出异常。还有其他方法可以使用更传统的机制打开文件(例如,失败的 fOut.Open 调用而不是在ctor中抛出异常)。 @franji1,请问什么是 asData[]?谢谢:) @Jay_Abitona asData 是您要写入文件的数据。这只是可以做的一个例子。我们不知道您需要将哪些数据写入文件。【参考方案2】:

这是一个非常基本的示例:

...
if (dlg.DoModal() == IDOK)

    filename = dlg.GetPathName(); // return full path and filename

    FILE *file = fopen(filename, "w");    // open file for writing

    if (file == NULL)
      AfxMessageBox("File couild not be created.";
    else
    
      // file could be created, write something
      fprintf(file, "Some text\n");

      // and close the file
      fclose(file);
    

...

这会将“一些文本”写入用户使用 CFileDialog 文件选择器提供名称的文件中。

在现实世界中,您需要根据程序的数据编写任何文本。

这确实是最基本的知识。

【讨论】:

谢谢。它有效,但我需要关闭特定代码行的警告并使用警告编译指示 #pragma warning(suppress : 4996)。 @Jay_Abitona 许多非常旧的函数已被弃用,尽管它们仍然有用。 fprintf 是 C 的保留,确实很老。使用 C++ 的 Stream I/O functions 可能会更好,即使它们更复杂。

以上是关于MFC C++:如何将某个文件实际保存到系统中,而不仅仅是打开另存为对话框的主要内容,如果未能解决你的问题,请参考以下文章

MFC如何从MFCEditBrowseControl获取路径并将其复制到编辑控件?

如何让用户保存到目录?

保存工作区 MFC C++ MDI

在 MFC 中序列化 CTypedPtrList 不会将数据保存在列表中

请求用户输入以命名使用 ofstream C++ MFC 创建的文件

Qt C++:将项目保存在文件中[重复]