Error[8]: Undefined offset: 95, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

目录

一、文件指针

二、文件的打开和关闭

文件打开方式:

fopen打开失败的原因:

三、流

四、文件顺序读写

1. fgetc(字符输入函数) fputc(字符输出函数)

2. fgets (文本行输入函数)  fputs(文本行输出函数)

3.1 fprintf   fscanf

3.2 scanf  sprintf

4. fread  fwrite(只适用于文件流)


一、文件指针

fopen打开文件会在内存中开辟一个文件信息区,用来存放文件的相关信息(文件名,文件状态及文件当前位置等)。这些信息存放在一个结构体变量中。这个结构体类型由系统声明,取名为FILE。

每打开一个文件系统会自动创建一个FILE结构体变量,并存入信息。

通过FILE*指针我们通过文件信息区中的内容访问文件。

二、文件的打开和关闭

读取和写入之前应该先打开文件,使用结束要关闭文件

// 打开文件

FILE * fopen ( const char * filename , const char * mode );

filename 文件路径,只写文件名也可以。mode是打开方式。打开错误返回NULL。

返回值:文件信息区的起始地址

//关闭文件

int fclose ( FILE * stream);

文件打开方式:
文件打开方式含义如果指定文件不存在
"r"(只读) 为了输入数据,打开一个已存在的文本文件 出错
"w"(只写) 为了输出数据,打开一个文本文件 创建新文件
 "a"(追加) 向文本文件尾添加数据  创建新文件
 "rb"(只读) 为了输入数据,打开二进制文件 出错
 "wb"(只写) 为了输出数据,打开一个二进制文件 创建新文件
 "ab"(追加) 向二进制文件尾添加数据 出错
 "r+"(读写) 打开文本文件,读和写出错
 "w+"(读写) 创建新文件,读和写创建新文件
 "a+"(读写) 打开一个文件,在文件尾读写 创建新文件
 "rb+"(读写) 打开二进制文件,读和写出错
 "wb+"(读写) 创建新二进制文件,读和写创建新文件
 "ab+"(读写) 打开二进制文件,在文件尾读写 创建新文件

记忆小tip :带b的是二进制文件,带+是读写。都是带双引号的。

用"w"和"wb" (只写)只要打开文件会直接清空文件初始内容。

初始内容:

写内容到文件之后:

只打开文件但不写入:

 

打开文件后内容被清空。 

使用fopen的时候

文件不存在:根据文件打开方式("w","r","a"...),有的会出错,有的会自动创建新文件

fopen打开失败的原因:

1.没显示文件扩展名 

给文件起名为test.txt,但是没显示扩展名。那实际上这个文件名是test.txt.txt.

2.路径不对

写路径的时候要带两个\\ 防止将你的路径识别成转义字符。

上面这样就会打开失败。

这样就成功了。 

三、流

计算机传输数据的过程称为流。传输是有方向性的,需要输出流和输入流。

标准输入流:stdin 键盘

标准输出流:stdout 屏幕

标准错误流:stderr 

⬆️这三个流只要程序运行起来就会默认打开。

FILE * 是文件流。

四、文件顺序读写
功能函数名使用于
字符输入函数

fgetc

所有输入流
字符输出函数fputc所有输出流
文本输入函数fgets所有输入流
文本输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件
1. fgetc(字符输入函数) fputc(字符输出函数)

头文件:

int fgetc ( FILE * stream) ;

      1️⃣参数:( 流 )

      2️⃣返回值:一定要用int类型接收。成功读取,返回读取的字符,提升为整型。失败返回EOF。

int fputc ( int characyer , FILE * stream) ;  //stream 是流的意思

      1️⃣参数:( 想传输的字符 ,流 )

      2️⃣返回值:写入失败返回EOF

例1:从键盘输入一个字符,输出到屏幕

# include
int main()
{
	int ch = fgetc(stdin);//stdin 标准输入流 键盘 一定要用int类型接收
	fputc(ch, stdout);//stdout 标准输出流 屏幕

	return 0;
}

例2:把a~z写入文件

#include
int main()
{
	//打开文件
	FILE* pf = fopen("D:\ 222.txt", "wb");
	if (pf == NULL)//判断是否打开成功
	{
		printf("fopen");
		return 1;
	}

	//写文件
	char ch = 'a';
	for (ch = 'a'; ch >= 'a' && ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

	//关闭文件
	fclose(pf);
	//指针置空防止野指针
	pf = NULL;
	
	return 0;
}

2. fgets (文本行输入函数)  fputs(文本行输出函数)

头文件

char * fgets ( char * str , int num , FILE * stream );

      1️⃣参数:(存入地址,个数,流)

      2️⃣返回值:存入空间地址

int puts ( const char * str , FILE * stream );

      1️⃣参数:(内容,流)

      2️⃣返回值:成功是返回非负值,失败返回EOF

fputs:输出一行,想换行要给字符串带'\n',不然写到文件里就是一整行

1.带'\n'的版本

#include
int main()
{
	//打开文件
	FILE* pf = fopen("D:\\test.txt", "w");
	
	if (pf == NULL)
	{
		printf("fopen\n");
		return 1;
	}

	//写文件
	fputs("abcdef\n", pf);
	fputs("aaaaaa\n", pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 

 2.不带'\n'的版本

fputs:

文件内容:

#include
int main()
{
	char arr[256] = "xxxxxxxxxxxxxxx";

	//打开文件
	FILE* pf = fopen("D:\\test.txt", "r");
	
	if (pf == NULL)
	{
		printf("fopen\n");
		return 1;
	}
	
	fgets(arr, 256, pf);
	printf("%s", arr);//不用换行,因为在文件里第一行结尾是有换行符的
	fgets(arr, 256, pf);
	printf("%s", arr);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

只打印一行:

这里我们打印时没带换行符,但还是自动换行了。因为在文件里第一行没写满,要到下一行继续写内容,就必须给第一行结尾带上换行符。使用fgets时读取个数超出字符串长度,所以就读到了第一行字符串的'\n'。

 

 

fgets:只读n-1个字符,因为会预留最后一个位置放'fprintf   fscanf'

如果设置个数少于字符串长度,没读到'\n'呢?

没有换行。

下面我们迎来一对万能选手。前面的一个是字符输入输出,一个文本行输入输出。

3.1 格式化输出

头文件:

针对所有输出流的

int fprintf ( FILE * stream, const char * format, ... );
函数:

格式化输入

针对所有输入流的

int fscanf ( FILE * stream, const char * format, ... );
函数:

scanf  sprintf

和printf和scanf用法差不多,就是多了个流。

例1:把一个结构体写到文件里

#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = { "张三",20,95.5 };

	//打开文件
	FILE* pf = fopen("D:\\test.txt","w");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	//写文件
	fprintf(pf, "%s %d %lf", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

例2:从文件里读结构体,打印到屏幕上

#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = {0};

	//打开文件
	FILE* pf = fopen("D:\\test.txt","r");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	//写文件
	fscanf(pf, "%s %d %lf", s.name, &(s.age), &(s.d));//和scanf使用时相似,需要取地址。因为s.name是个字符串,变量名就是首元素地址。所以s.name可以不取地址

	//打印
	fprintf(stdout, "%s %d %lf\n", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

 附加学习以一个内容

3.2 
int sprintf ( char * str, const char * format, ... );

头文件:

把格式化数据转化成字符串:

int sscanf ( const char * s, const char * format, ...);

⬇️要先转化才能提取

把字符串转换成格式化的数据(从字符串中提取信息):

fread  fwrite(只适用于文件流)
#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = { "张三",20,90.5 };
	char arr[256] = { 0 };//结构体转化成字符串,存到arr里
	struct S tmp = { 0 };//从arr提取出数据放到结构体tmp里

    //结构体转化成字符串
	sprintf(arr, "%s %d %lf", s.name, s.age, s.d);
	printf("%s\n", arr);

    //提取出的数据放到tmp里
	sscanf(arr, "%s %d %lf", tmp.name, &(tmp.age), &(tmp.d));
	printf("%s %d %lf", tmp.name, tmp.age, tmp.d);

	return 0;
}

4. 二进制输入:

头文件:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

二进制输出:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

[+++]

      1️⃣返回值:实际写入的个数

      2️⃣参数:(指针指向要写的数据,一个元素的大小,想要写入的元素个数,文件流)

 例1:以二进制方式写入文件

#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = { 0 };

	//读文件,以二进制方式读
	FILE* pf = fopen("D:\\test.txt", "rb");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %lf\n", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

 

例2:以二进制方式读

文件里是二进制数据:

#include

int main()struct S
{
	char name[20];
	int age;
	double d;//分数
};


{
	struct S s = { 0 };

	//读文件,以二进制方式读
	FILE* pf = fopen("D:\\test.txt", "rb");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %lf\n", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
C语言——文件 *** 作_C_内存溢出

C语言——文件 *** 作

C语言——文件 *** 作,第1张

目录

一、文件指针

二、文件的打开和关闭

文件打开方式:

fopen打开失败的原因:

三、流

四、文件顺序读写

1. fgetc(字符输入函数) fputc(字符输出函数)

2. fgets (文本行输入函数)  fputs(文本行输出函数)

3.1 fprintf   fscanf

3.2 scanf  sprintf

4. fread  fwrite(只适用于文件流)


一、文件指针

fopen打开文件会在内存中开辟一个文件信息区,用来存放文件的相关信息(文件名,文件状态及文件当前位置等)。这些信息存放在一个结构体变量中。这个结构体类型由系统声明,取名为FILE。

每打开一个文件系统会自动创建一个FILE结构体变量,并存入信息。

通过FILE*指针我们通过文件信息区中的内容访问文件。

二、文件的打开和关闭

读取和写入之前应该先打开文件,使用结束要关闭文件

// 打开文件

FILE * fopen ( const char * filename , const char * mode );

filename 文件路径,只写文件名也可以。mode是打开方式。打开错误返回NULL。

返回值:文件信息区的起始地址

//关闭文件

int fclose ( FILE * stream);

文件打开方式:
文件打开方式含义如果指定文件不存在
"r"(只读) 为了输入数据,打开一个已存在的文本文件 出错
"w"(只写) 为了输出数据,打开一个文本文件 创建新文件
 "a"(追加) 向文本文件尾添加数据  创建新文件
 "rb"(只读) 为了输入数据,打开二进制文件 出错
 "wb"(只写) 为了输出数据,打开一个二进制文件 创建新文件
 "ab"(追加) 向二进制文件尾添加数据 出错
 "r+"(读写) 打开文本文件,读和写出错
 "w+"(读写) 创建新文件,读和写创建新文件
 "a+"(读写) 打开一个文件,在文件尾读写 创建新文件
 "rb+"(读写) 打开二进制文件,读和写出错
 "wb+"(读写) 创建新二进制文件,读和写创建新文件
 "ab+"(读写) 打开二进制文件,在文件尾读写 创建新文件

记忆小tip :带b的是二进制文件,带+是读写。都是带双引号的。

用"w"和"wb" (只写)只要打开文件会直接清空文件初始内容。

初始内容:

写内容到文件之后:

只打开文件但不写入:

 

打开文件后内容被清空。 

使用fopen的时候

文件不存在:根据文件打开方式("w","r","a"...),有的会出错,有的会自动创建新文件

fopen打开失败的原因:

1.没显示文件扩展名 

给文件起名为test.txt,但是没显示扩展名。那实际上这个文件名是test.txt.txt.

2.路径不对

写路径的时候要带两个\\ 防止将你的路径识别成转义字符。

上面这样就会打开失败。

这样就成功了。 

三、流

计算机传输数据的过程称为流。传输是有方向性的,需要输出流和输入流。

标准输入流:stdin 键盘

标准输出流:stdout 屏幕

标准错误流:stderr 

⬆️这三个流只要程序运行起来就会默认打开。

FILE * 是文件流。

四、文件顺序读写
功能函数名使用于
字符输入函数

fgetc

所有输入流
字符输出函数fputc所有输出流
文本输入函数fgets所有输入流
文本输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件
1. fgetc(字符输入函数) fputc(字符输出函数)

头文件:

int fgetc ( FILE * stream) ;

      1️⃣参数:( 流 )

      2️⃣返回值:一定要用int类型接收。成功读取,返回读取的字符,提升为整型。失败返回EOF。

int fputc ( int characyer , FILE * stream) ;  //stream 是流的意思

      1️⃣参数:( 想传输的字符 ,流 )

      2️⃣返回值:写入失败返回EOF

例1:从键盘输入一个字符,输出到屏幕

# include
int main()
{
	int ch = fgetc(stdin);//stdin 标准输入流 键盘 一定要用int类型接收
	fputc(ch, stdout);//stdout 标准输出流 屏幕

	return 0;
}

例2:把a~z写入文件

#include
int main()
{
	//打开文件
	FILE* pf = fopen("D:\ 222.txt", "wb");
	if (pf == NULL)//判断是否打开成功
	{
		printf("fopen");
		return 1;
	}

	//写文件
	char ch = 'a';
	for (ch = 'a'; ch >= 'a' && ch <= 'z'; ch++)
	{
		fputc(ch, pf);
	}

	//关闭文件
	fclose(pf);
	//指针置空防止野指针
	pf = NULL;
	
	return 0;
}

2. fgets (文本行输入函数)  fputs(文本行输出函数)

头文件

char * fgets ( char * str , int num , FILE * stream );

      1️⃣参数:(存入地址,个数,流)

      2️⃣返回值:存入空间地址

int puts ( const char * str , FILE * stream );

      1️⃣参数:(内容,流)

      2️⃣返回值:成功是返回非负值,失败返回EOF

fputs:输出一行,想换行要给字符串带'\n',不然写到文件里就是一整行

1.带'\n'的版本

#include
int main()
{
	//打开文件
	FILE* pf = fopen("D:\\test.txt", "w");
	
	if (pf == NULL)
	{
		printf("fopen\n");
		return 1;
	}

	//写文件
	fputs("abcdef\n", pf);
	fputs("aaaaaa\n", pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

 

 2.不带'\n'的版本

fputs:

文件内容:

#include
int main()
{
	char arr[256] = "xxxxxxxxxxxxxxx";

	//打开文件
	FILE* pf = fopen("D:\\test.txt", "r");
	
	if (pf == NULL)
	{
		printf("fopen\n");
		return 1;
	}
	
	fgets(arr, 256, pf);
	printf("%s", arr);//不用换行,因为在文件里第一行结尾是有换行符的
	fgets(arr, 256, pf);
	printf("%s", arr);

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

只打印一行:

这里我们打印时没带换行符,但还是自动换行了。因为在文件里第一行没写满,要到下一行继续写内容,就必须给第一行结尾带上换行符。使用fgets时读取个数超出字符串长度,所以就读到了第一行字符串的'\n'。

 

 

fgets:只读n-1个字符,因为会预留最后一个位置放'fprintf   fscanf'

如果设置个数少于字符串长度,没读到'\n'呢?

没有换行。

下面我们迎来一对万能选手。前面的一个是字符输入输出,一个文本行输入输出。

3.1 格式化输出

头文件:

针对所有输出流的

int fprintf ( FILE * stream, const char * format, ... );
函数:

格式化输入

针对所有输入流的

int fscanf ( FILE * stream, const char * format, ... );
函数:

scanf  sprintf

和printf和scanf用法差不多,就是多了个流。

例1:把一个结构体写到文件里

#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = { "张三",20,95.5 };

	//打开文件
	FILE* pf = fopen("D:\\test.txt","w");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	//写文件
	fprintf(pf, "%s %d %lf", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

例2:从文件里读结构体,打印到屏幕上

#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = {0};

	//打开文件
	FILE* pf = fopen("D:\\test.txt","r");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	//写文件
	fscanf(pf, "%s %d %lf", s.name, &(s.age), &(s.d));//和scanf使用时相似,需要取地址。因为s.name是个字符串,变量名就是首元素地址。所以s.name可以不取地址

	//打印
	fprintf(stdout, "%s %d %lf\n", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

 附加学习以一个内容

3.2 
int sprintf ( char * str, const char * format, ... );

头文件:

把格式化数据转化成字符串:

int sscanf ( const char * s, const char * format, ...);

⬇️要先转化才能提取

把字符串转换成格式化的数据(从字符串中提取信息):

fread  fwrite(只适用于文件流)
#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = { "张三",20,90.5 };
	char arr[256] = { 0 };//结构体转化成字符串,存到arr里
	struct S tmp = { 0 };//从arr提取出数据放到结构体tmp里

    //结构体转化成字符串
	sprintf(arr, "%s %d %lf", s.name, s.age, s.d);
	printf("%s\n", arr);

    //提取出的数据放到tmp里
	sscanf(arr, "%s %d %lf", tmp.name, &(tmp.age), &(tmp.d));
	printf("%s %d %lf", tmp.name, tmp.age, tmp.d);

	return 0;
}

4. 二进制输入:

头文件:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

二进制输出:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

      1️⃣返回值:实际写入的个数

      2️⃣参数:(指针指向要写的数据,一个元素的大小,想要写入的元素个数,文件流)

 例1:以二进制方式写入文件

#include
struct S
{
	char name[20];
	int age;
	double d;//分数
};

int main()
{
	struct S s = { 0 };

	//读文件,以二进制方式读
	FILE* pf = fopen("D:\\test.txt", "rb");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %lf\n", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

 

例2:以二进制方式读

文件里是二进制数据:

#include

int main()struct S
{
	char name[20];
	int age;
	double d;//分数
};


{
	struct S s = { 0 };

	//读文件,以二进制方式读
	FILE* pf = fopen("D:\\test.txt", "rb");
	if (pf == NULL)
	{
		printf("fopen");
		return 1;
	}

	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %lf\n", s.name, s.age, s.d);

	//关闭文件
	fclose(pf);
	pf = NULL;

	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1324182.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存