在MFC中读写文件(VS2019)

方法一:使用File定义一个结构体指针:FILE *pFile

写文件

在工程目录下创建一个名为“1.txt”的文件,并写入数据:“http://org1”

FILE* pFile;
int flag;
flag = fopen_s(&pFile, "1.txt", "w");   //2019之前版本的VS直接用fopen,fopen较fopen_s少了第一个参数
fwrite("http://org1", 1, strlen("http://org1"), pFile);
fclose(pFile);

fopen_s函数:

 _ACRTIMP errno_t __cdecl fopen_s(
            _Outptr_result_maybenull_ FILE**      _Stream,
            _In_z_                    char const* _FileName,
            _In_z_                    char const* _Mode
            );

第三个参数表示对文件的操作模式:
“w”表示对空文件进行写操作,若文件已经存在,则文件内容会被销毁;
“r”表示对文件进行读操作,若文件不存在,则函数调用失败;
“a”表示在文件的末尾添加数据,若文件不存在,则会先创建文件;
“r+”表示对文件进行读和写操作,前提是文件必须存在;
“w+”表示对空文件进行读和写操作;
“a+”表示对文件进行读操作和添加数据操作;
fwrite函数:

  _ACRTIMP size_t __cdecl fwrite(
        _In_reads_bytes_(_ElementSize * _ElementCount) void const* _Buffer,
        _In_                                           size_t      _ElementSize,
        _In_                                           size_t      _ElementCount,
        _Inout_                                        FILE*       _Stream
        );

第一个参数void const* _Buffer表示要写入的内容;
第二个参数和第三个参数都是无符号整型,第二个参数表示将要写入的数据的项的大小,第三个参数表示项的数目。举个例子:比如说要写入8个字节的数据,把项的大小设为1(即第二个参数为1),那么项的数目就应该为8(即第三个参数为8)。如果项的大小设为2,则项的数目就为4;
第四个参数是指向FILE结构体的指针;
fclose函数:
对文件操作完成后要关闭文件,使缓冲区的数据写入到文件中;如果需要对文件进行多次操作且不想反复调用fopen_s和
fclose,则可以在每次操作完成后调用fflush,此函数会对缓冲区进行刷新,使数据写入文件当中。
fseek函数:

 _ACRTIMP int __cdecl fseek(
        _Inout_ FILE* _Stream,
        _In_    long  _Offset,
        _In_    int   _Origin
        );

当对文件写入一次数据后,继续进行写操作,会从当前位置进行写操作,此时如果想要从文件开头位置进行写操作,就需要调用函数fseek;第一个参数表示指向文件的结构体指针;第二个参数表示从初始化位置的偏移量,若是从文件开头处写入,则偏移量为0;第三个参数表示初始化位置,即起始位置,有三个值可以选择:SEEK_SET表示从文件的开头处开始写入;SEEK_CUR表示从文件的当前位置开始;SEEK_END表示从文件的结尾处开始。

FILE* pFile;
	int flag;
	flag = fopen_s(&pFile, "1.txt", "w");       //2019之前版本的VS直接用fopen
	fwrite("http://org1", 1, strlen("http://org1"), pFile);
	fseek(pFile, 0, SEEK_SET);
	fwrite("ftp", 1, strlen("ftp"), pFile);
	fclose(pFile);

读文件

FILE* pFile;
int flag;
int len;
flag = fopen_s(&pFile, "2.txt", "r");
char ch[100];
memset(ch, 0, 100);//将数组初始化为0
fread(ch, 1, 100, pFile);
MessageBoxA(0,ch,"",MB_OK);
fclose(pFile);

采用固定长度的数组存储从文件读取到的数据,不灵活且浪费内存,可先获得文件的数据长度,建立动态数组。

FILE* pFile;
int flag;
int len;
flag = fopen_s(&pFile, "2.txt", "r");
fseek(pFile, 0, SEEK_END);//将文件指针移动到文件结尾处,方便后续读取数据长度
len = ftell(pFile);//获得数据长度
char* ch = new char[len];
fseek(pFile, 0, SEEK_SET);
rewind(pFile);//读操作之前要将文件指针重新移动到文件开头
fread(ch, 1, len, pFile);
ch[len] = 0;//数组最后一个元素赋值为零,表示数据结尾
MessageBoxA(0,ch,"",MB_OK);
fclose(pFile);

注:此处直接使用MessageBox会出现乱码的情况。
参考链接:MessageBox乱码解决办法
MessageBox(LPCTSTR)乱码问题解决方法:
ANSI 和 UNICODE 字符集的区别,char buf[100],是采用的 ANSI 字符集,而下面MessageBoxW(buf),函数又是Unicode的版本。在此解释一下,MessageBox()分两个版本:MessageBoxA() 和 MessageBoxW() 版本。如果使用 char,那么应该用MessageBoxA();如果用 WCHAR,那么用MessageBoxW();如果用模板TCHAR,那么MessageBox()。
所以对于上述问题,将会有两种解决方案。
方案一:将char buf[100]; 改为 WCHAR[100];
方案二:将MessageBoxW(buf); 改为 ::MessageBoxA(0,buf,"", MB_OK);
如果你从文件里读的内容是ANSI字符格式的话,那么你必须采用第二种方案;相反,如果你从文件力度的内容是UNICODE字符格式的话,那么你需要采用方案一。

方法二:使用ifstream和ofstream两个类

写文件

ofstream ofs("4.txt");
ofs.write("http://", strlen("http://"));
ofs.close();

读文件

ifstream ifs("4.txt");
char ch[100];
memset(ch, 0, 100);
ifs.read(ch, 100);
ifs.close();
MessageBoxA(0, ch, "", MB_OK);

在使用这两个类进行文件操作时,要添加头文件和命名空间:

#include 
using namespace std;

方法三:使用Win32中的API文件操作函数

写文件

DWORD dwWrites;
hFile = CreateFile(_T("3.txt"), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, "http//:orgFG", strlen("http//:orgFG"), &dwWrites, NULL);
CloseHandle(hFile);

读文件

HANDLE hFile;
DWORD dwReads;
char ch[100];
hFile = CreateFile(_T("3.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ReadFile(hFile,ch,100, &dwReads, NULL);
ch[dwReads] = 0;
CloseHandle(hFile);
MessageBoxA(0, ch, " ", MB_OK);

方法四:使用MFC的类CFile

写文件

CFile file(_T("6.txt"), CFile::modeCreate | CFile::modeWrite);
file.Write("http:://", strlen("http:://"));
file.Close();

读文件

CFile file(_T("6.txt"), CFile::modeRead);
char* ch;
int len;
len = file.GetLength();
ch = new char[len];
file.Read(ch, len);
ch[len] = 0;
MessageBoxA(0, ch, " ", MB_OK);
file.Close();

方法五:使用CFileDialog

写文件

CFileDialog fileDlg(FALSE);//FALSE表示文件保存对话框
fileDlg.m_ofn.lpstrTitle = _T("File Save Frame");//设置文件保存对话框的标题
fileDlg.m_ofn.lpstrFilter = _T("Text Files(*.txt)\0*.txt\0*.All Files(*.*)\0*.*\0\0");
fileDlg.m_ofn.lpstrDefExt = _T("txt");
if (IDOK == fileDlg.DoModal())
{
	CFile file(fileDlg.GetFileName(), CFile::modeCreate | CFile::modeWrite);
	file.Write("test file save", strlen("test file save"));
	file.Close();
}

读文件

CFileDialog fileDlg(TRUE); //TRUE表示文件打开对话框
fileDlg.m_ofn.lpstrTitle = _T("File Open Frame");
fileDlg.m_ofn.lpstrFilter = _T("Text Files(*.txt)\0*.txt\0*.All Files(*.*)\0*.*\0\0");
if (IDOK == fileDlg.DoModal())
{
	CFile file(fileDlg.GetFileName(), CFile::modeRead);
	char* ch;
	int len;
	len = file.GetLength();
	ch = new char[len];
	file.Read(ch, len);
	ch[len] = 0;
	MessageBoxA(0, ch, "",MB_OK);
	file.Close();
}

你可能感兴趣的:(编程语言)