C/C++读写文件和stringstream类

目录

  • C处理文件
    • 打开文件
      • 两种函数的区别
    • 读文件
      • 两种函数区别
      • 其它读操作的函数
        • fgetc:从文件中读取一个字符
        • fgets:从文件中读取一个字符串
        • fscanf:按格式从文件中读取指定内容,与scanf函数类似
    • 写文件
      • 其它的常用写操作函数
        • fputc:向文件中写入一个字符
        • fputs:向文件中写入一个字符串
        • fprintf:向文件中写入指定格式字符串,与pritnf函数类似
    • 关闭文件
  • C++处理文件
    • 通用类
  • sstream
    • 功能和用途
      • 可以把字符串根据空格分开
      • 多个字符串拼接
      • 用来string<-->int转换
      • stringstream的清空
        • clear() 方法
        • str("") 方法
      • 其他一些用法

本文主要详解C/C++对文件的所有常见方法汇总以及stringstream类用法

C处理文件

头文件

#include<cstdio> //或者#include<stdio.h>均可

注意:
C语言库中的函数,很多都存在安全隐患,就会存在一个相应的安全函数,一般对应的安全函数名称都是在原函数后添加_s后缀

相比较而言,安全函数会比标准函数使用更繁琐,所以很多情况下我们会习惯于使用标准函数,
但在VS环境下直接使用不安全的函数,会直接报错,编译无法通过,此时就必须要定义对应的宏才能正常使用
而安全函数则无需定义任何宏,可直接使用。

打开文件

//标准函数:
FILE* fopen(
const char * _FileName,//要打开的文件名,不指定路径,则在当前文件夹找
const char * _Mode //打开的模式 读r 写w 或追加a
);
//返回值:打开失败返回NULL,打开成功则返回指向文件的标识符

//安全函数
 errno_t fopen_s(
FILE**      _Stream, //保存打开文件后的标识符
const char * _FileName, //要打开的文件名,不指定路径,则在当前文件夹找
const char * _Mode //打开的模式 读r 写w 或追加a
            );
 //返回值:打开成功返回0,打开失败则返回对应错误代码	

在这里插入图片描述

两种函数的区别

#define _CRT_SECURE_NO_WARNINGS //vs环境下,必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //以读的方式打开文件
	if (file == NULL) { //file为NULL,则打开文件失败,退出程序
		return -1;
	}
}
#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","r"); //以读的方式打开文件
	if (err != 0) { //err不为0,则打开文件失败,退出程序
		return -1;
	}
}

读文件

//标准函数:
size_t  fread(
void*  _Buffer, //读取到的内容存放空间
size_t _ElementSize, //每次读多少个字节
size_t _ElementCount, //读多少次
FILE*  _Stream //文件标识符
);
//返回值:实际读取的次数,注意,实际的取得字节数应该是该返回值和_ElementSize参数相乘,所以一般_ElementSize参数填1

//安全函数:
size_t fread_s(
void*  _Buffer,//读取到的内容存放空间
size_t _BufferSize, //第一个参数指示的缓存区大小
size_t _ElementSize,//每次读多少个字节
size_t _ElementCount,//读多少次
FILE*  _Stream //文件标识符
);
//返回值:实际读取的次数,注意,实际的取得字节数应该是该返回值和_ElementSize参数相乘,所以一般_ElementSize参数填1

注意:
在C和C++中,字符串的结束标志是空字符。当使用fread函数从文件中读取数据时,fread不会自动在缓冲区的末尾添加空字符。因此,需要手动添加一个空字符作为字符串的结束标志。

两种函数区别

在这里插入图片描述

#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","r"); //以读的方式打开文件
	if (err != 0) { //err不为0,则打开文件失败,退出程序
		return -1;
	}
	char buf[0xFF];  //定义存放读取内容的缓存区
	size_t size=fread_s(buf,sizeof(buf),1,100,file);//每次读一个字节,读100次
}

其它读操作的函数

fgetc:从文件中读取一个字符
int fgetc(
FILE* _Stream //文件标识符
);
//返回值:返回读取到的一个字符
#define _CRT_SECURE_NO_WARNINGS //vs环境下必须定义该宏,否则报错
#include<cstdio>
using namespace std;
int main() {
	FILE* file = fopen("1.txt","r"); //已只读方式打开
	if (file == NULL) {  //打开失败直接返回
		return -1;
	}
	char c=fgetc(file); //读取一个字符
}
fgets:从文件中读取一个字符串
char* __cdecl fgets(
char* _Buffer, //存放读到的字符缓冲区
 int   _MaxCount, //该缓存区的大小
FILE* _Stream //文件标识符
);
//返回值:成功为_Buffer指针,失败为NULL

在这里插入图片描述

fscanf:按格式从文件中读取指定内容,与scanf函数类似
int fscanf(
 FILE*       const _Stream,//文件标识符
 char const* const _Format, //指定读取格式,与printf格式相同
        ... //存放读取内容的缓存区
)

注意:
在C语言中,fscanf函数需要变量的地址作为参数,以便它能将读取到的值存储在这些变量中。

在这里插入图片描述

写文件

size_t fwrite(
void const* _Buffer, //要写入的内容
size_t _ElementSize, //元素大小
size_t  _ElementCount, //元素个数
FILE*   _Stream //文件标识
 );

该函数无安全函数。
在这里插入图片描述

其它的常用写操作函数

fputc:向文件中写入一个字符
int  fputc(
int   _Character,//要写入的字符
FILE* _Stream //文件标识符
);
#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","w");
	if (err != 0) {
		return -1;
	}
	int ret=fputc('c',file);//向file标识的文件写入一个c字符
}
fputs:向文件中写入一个字符串
int fputs(
char const* _Buffer,//要写入的内容
FILE* _Stream //文件标识符
);

在这里插入图片描述

fprintf:向文件中写入指定格式字符串,与pritnf函数类似
int fprintf(
 FILE* _Stream, //文件标识符
char const* const _Format, //写入格式 与printf使用方式相同
        ...
)

在这里插入图片描述

关闭文件

int fclose(
FILE* _Stream //文件标识符
);
#include<cstdio>
using namespace std;
int main() {
	FILE* file;
	errno_t err=fopen_s(&file,"1.txt","w");
	if (err != 0) {
		return -1;
	}
	fclose(file);//关闭文件
}

C++处理文件

通用类

头文件:

#include<fstream> //处理文件的头文件
using namespace std; //引用该命名空间,不引用将必须使用std::fstring 的方式使用该类

注意:
使用sizeof(buf)来确定写入文件的字节数可能导致乱码。sizeof操作符返回的是整个数组的大小,包括了字符串的结尾空字符。
要解决这个问题,可以通过使用strlen函数(而不是sizeof)来完成,strlen返回的是字符串的实际长度,不包括结尾的空字符。

在这里插入图片描述

模式选择:
在这里插入图片描述

sstream

<sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。它特别有用于处理复杂的字符串操作,比如当你需要从字符串中提取或向字符串中插入多种不同类型的数据时。它还为字符串和其他基本数据类型之间的转换提供了便捷的方法,这在进行数据处理和格式化时尤其有用。本文主要介绍一些实用用法。

istringstream类用于执行C++风格的串流的输入操作。
ostringstream类用于执行C风格的串流的输出操作。
stringstream类同时可以支持C/C++风格的串流的输入输出操作。

功能和用途

1.字符串拼接和分割:可以轻松地读取或写入变量,就像使用cin或cout那样,从而允许你进行复杂的字符串拼接和分割操作。
2.类型转换:stringstream可以方便地在字符串和其他数据类型(如int、float等)之间转换。
3.格式化字符串:可以用来格式化字符串数据,进行复杂的操作,比如插入特定格式的数据。

可以把字符串根据空格分开

在这里插入图片描述

多个字符串拼接

在这里插入图片描述

用来string<–>int转换

在这里插入图片描述
在这里插入图片描述

stringstream的清空

clear() 方法

用途:clear() 方法用于重置stringstream对象的状态标志(如错误标志),而不是清空其中的内容。这对于重新使用相同的stringstream对象进行新的输入/输出操作非常有用。
功能:它会将stringstream的状态设置回goodbit状态(即无错误状态)。如果之前的操作(例如读取或写入)在stringstream上设置了错误标志(如eofbit, failbit, badbit),clear()会清除这些标志,使对象可以再次正常使用。

str(“”) 方法

用途:str(“”) 方法用于设置stringstream对象的内部字符串。当使用空字符串""作为参数时,它实际上清空了stringstream中的内容。
功能:它不影响stringstream的状态标志,仅更改其存储的字符串内容。如果你想重新使用stringstream对象并需要清除之前存储的数据,这个方法会很有用。
在这里插入图片描述
当执行sstream >> first;后,由于已经读取到流的末尾,stringstream的内部状态将设置eofbit(表示已到达流的末尾)。这意味着流已经处于一种“用完”的状态。
如果接下来再尝试往这个stringstream对象写入新的数据(如sstream << true;),并尝试读取(如sstream >> second;),由于流的状态仍然是eofbit,这个写入操作将无法正确执行,导致接下来的读取操作也无法正常进行。
因此,在进行多次读写之前,需要使用clear()方法来重置流的状态。clear()方法会清除流的状态标志(包括eofbit),使流可以再次用于读写操作。

正确的做法是,在每次读写操作完成后使用clear()方法重置流的状态,特别是在读取到流的末尾后。这样可以确保流处于一个干净的状态,准备好进行下一次读写操作。

其他一些用法

在这里插入图片描述
在这里插入图片描述