fputs函数
我们给出使用的测试代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)\
do\
{\
if (e == NULL)\
{\
printf("open error\n");\
exit(0);\
}\
} while (0)\
int main()
{
FILE* pf = fopen("lines.txt","w");
F_PRINTF_ERR(pf);
fputs("aaaaaaaaaaaaaaa\n", pf);
fputs("bbbbbbbbbbbbbbb\n", pf);
fputs("ccccccccccccccc\n", pf);
fclose(pf);
return 0;
}
执行结果为:
我们可以看到三行数据已经写入。
当然我们也可以给字符串中加入控制字符:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)\
do\
{\
if (e == NULL)\
{\
printf("open error\n");\
exit(0);\
}\
} while (0)\
int main()
{
FILE* pf = fopen("lines.txt","w");
F_PRINTF_ERR(pf);
fputs("aaa\naaaaaaaaaaaa\n", pf);
fputs("bbbbbbbbbbbbbbb\n", pf);
fputs("ccccc\0cccccccccc\n", pf);
fclose(pf);
return 0;
}
执行结果如下:
\n表示换行,\0代表字符串结束,所以控制字符在代码中也得以体现。
fgets函数
我们通过代码进行测试:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)\
do\
{\
if (e == NULL)\
{\
printf("open error\n");\
exit(0);\
}\
} while (0)\
int main()
{
FILE* pf = fopen("lines.txt", "r+");
F_PRINTF_ERR(pf);
char buf[1024];
fgets(buf,1024,pf);
printf("buf = %s",buf);
fclose(pf);
return 0;
}
执行结果为:
这里只读取到了 aaa\n
这里呢就是我们的第一种情况:
读 n-1 个字符前遇到\n,读取\n然后在后面加上\0结束。
接下来我们修改代码,这次我们就值读取2个字节:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)\
do\
{\
if (e == NULL)\
{\
printf("open error\n");\
exit(0);\
}\
} while (0)\
int main()
{
FILE* pf = fopen("lines.txt", "r+");
F_PRINTF_ERR(pf);
char buf[1024];
fgets(buf,2,pf);
printf("buf = %s",buf);
fclose(pf);
return 0;
}
执行结果为;
只读取到了一个字符,这里我们说明第二种情况:
n-1 个字符前没有遇到\n,读 n-1 个字符前也没有遇到 EOF,读到 n-1 个字符然后后面加上\0。
所以上面代码读取两个的时候只读取到1个 因为最后一个字符用与添加\0表示字符串结束。
那么这一次我们把所有的\n都去掉:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)
do
{
if (e == NULL)
{
printf(“open error\n”);
exit(0);
}
} while (0)\
int main()
{
FILE* pf = fopen(“lines.txt”, “r+”);
F_PRINTF_ERR(pf);
fputs(“aaaaaaaaaaaaaaa”, pf);
fputs(“bbbbbbbbbbbbbbb”, pf);
fputs(“ccccccccccccccc”, pf);
return 0;
}
执行结果为:
接下来我们进行读取:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)\
do\
{\
if (e == NULL)\
{\
printf("open error\n");\
exit(0);\
}\
} while (0)\
int main()
{
FILE* pf = fopen("lines.txt", "r+");
F_PRINTF_ERR(pf);
char buf[1024];
fgets(buf,1024,pf);
printf("buf = %s",buf);
fclose(pf);
return 0;
}
执行结果为:
这是我们的第三种情况:
这次读取既没有遇到\n,直到遇到EOF那么就到 n-1 个符+\0结束。
这里在读取所有字母之后遇到了EOF,所以只读取了30个字符并且在后面添加了\0
典型问题分析
如果读取以下文件:
1234567890abcdefg
1234567890
abcdefg \n
使用
fgets(buf,10,fp);
读取数据需要读取多少次?
我们在这里直接进行说明,然后通过编译器验证:
①123456789 \0
②0abcdefg \0
③123456789 \0
④0 \0
⑤abcdefg \0
⑥需要再进行一次来判断是文件结束EOF
总共需要6次
我们通过代码来验证:
首先我们先把数据写入文件:
接下来我们进行验证:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define F_PRINTF_ERR(e)\
do\
{\
if (e == NULL)\
{\
printf("open error\n");\
exit(0);\
}\
} while (0)\
int main()
{
FILE* pf = fopen("lines.txt", "r+");
F_PRINTF_ERR(pf);
char buf[1024];
int count = 0;
while (fgets(buf, 10, pf) != NULL)
{
count++;
printf("第%d次读取%s\n",count,buf);
}
return 0;
}
执行结果为:
如果我们把最后的一行的回车去掉(只留下多一个空行):
执行结果为:
如果我们不要所有的空行:
执行结果为:
结果也是只需要读取5次,读者可以根据前面的行规则细细体会其中的不同。
小结
关于典例,希望读者能够理解并且分析清楚,典例运用的就是本篇博客前半部分的内容进行分析得到。