目录
1 标准I/O – 读写流
2 标准I/O – 按字符输入
3 标准I/O – 按字符输出
4 标准I/O – 思考和练习
5 标准I/O – 按行输入
6 标准I/O – 按行输出
7 标准I/O – 思考和练习
1 标准I/O – 读写流
流支持不同的读写方式:
读写一个字符:fgetc()/fputc()一次读/写一个字符
读写一行:fgets()和fputs()一次读/写一行
读写若干个对象:fread()/fwrite() 每次读/写若干个对象,而每个对象具有相同的长度
2 标准I/O – 按字符输入
下列3个函数用来输入一个字符:
#include <stdio.h>int fgetc(FILE *stream); int getc(FILE *stream); //宏 int getchar(void);
成功时返回读取的字符;若到文件末尾或出错时返回EOF(-1),
区别:
getchar()等同于fgetc(stdin),但是只能读取标准输入即键盘内容,不能读文件
getc和fgetc区别是一个是宏一个是函数
注意事项:
- -函数返回值是int类型不是char类型,主要是为了扩展返回值的范围。
- -stdin 也是FILE *的指针,是系统定义好的,指向的是标准输入(键盘输入)
- -打开文件后读取,是从文件开头开始读。读完一个后读写指针会后移。读写注意文件位置!
- -调用getchar会阻塞,等待你的键盘输入
标准I/O – fgetc – 示例
#include <stdio.h>#define F_PATH "./1.txt"int main(int argc,char *argv[]){FILE *fp;int rec;fp = fopen(F_PATH,"r");if(fp==NULL){perror("fopen");return 0;}rec = fgetc(fp); //等同于rec = getc(fp);printf("Get char=%c\n",rec);rec = fgetc(fp);printf("Get char=%c\n",rec);rec = fgetc(fp);printf("Get char=%c\n",rec);}//1.txt 内容abcdef
//结果即是打开后的第一个字符
//结果 a
linux@linux:~/Desktop$ ./a.out
Get char=a
Get char=b
Get char=c
#include <stdio.h>int main(int argc,char *argv[]){int rec;rec = getchar();printf("Get STD=%c\n",rec);
}//getchar会阻塞,等待键盘输入后再输出
linux@linux:~/Desktop$ ./a.out
a
Get STD=a
int ch;
ch = fgetc(stdin);
printf(“%c\n”, ch);FILE *fp;
int ch, count = 0;
if ((fp = fopen(argv[1], “r”)) == NULL) { perror(“fopen”); return -1;
}
while ((ch = fgetc(fp)) != EOF) { count++;
}
printf(“total %d bytes\n”, count);
3 标准I/O – 按字符输出
下列函数用来输出一个字符:
#include <stdio.h>
int fputc(int c, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
成功时返回写入的字符;出错时返回EOF
putchar(c)等同于fputc(c, stdout) ,标准输出即显示器
标准I/O – fputc – 示例
#include <stdio.h>
#define F_PATH "./1.txt"int main(int argc,char *argv[]){FILE *fp;int rec;int wrc = 'w'; fp = fopen(F_PATH,"r+"); //a+在下一行写入if(fp==NULL){perror("fopen");return 0;}rec = fputc(wrc,fp);if(rec == -1){perror("fputc");fclose(fp);return 0;}putchar(wrc);fclose(fp);}//结果
linux@linux:~/Desktop$ cat 1.txt
abcdef
linux@linux:~/Desktop$ ./a.out
linux@linux:~/Desktop$ cat 1.txt
wbcdef //a改成了w
fputc(‘a’, stdout);
putchar(‘\n’);FILE *fp;
int ch;
if ((fp = fopen(argv[1], “w”)) == NULL) { perror(“fopen”); return -1;
}
for(ch = ‘a’; ch <=‘z’; ch++) { fputc(ch, fp);
}
4 标准I/O – 思考和练习
如何利用fgetc / fputc实现文件的复制?
提示:
通过命令行参数传递源文件和目标文件名
通过fgetc返回值判断是否读到文件末尾
#include <stdio.h>int main() {FILE *sourceFile, *destinationFile;char ch;// 打开源文件sourceFile = fopen("source.txt", "r");if (sourceFile == NULL) {printf("无法打开源文件。\n");return 1;}// 创建目标文件destinationFile = fopen("destination.txt", "w");if (destinationFile == NULL) {printf("无法创建目标文件。\n");fclose(sourceFile);return 1;}// 复制文件内容while ((ch = fgetc(sourceFile)) != EOF) {fputc(ch, destinationFile);}// 关闭文件fclose(sourceFile);fclose(destinationFile);printf("文件复制成功。\n");return 0;
}
5 标准I/O – 按行输入
下列函数用来输入一行:
#include <stdio.h>
char *gets(char *s); //默认读取得stdin,键盘内容
char *fgets(char *s, int size, FILE *stream);
- 成功时返回s,到文件末尾或出错时返回NULL
- gets不推荐使用,容易造成缓冲区溢出(已经被淘汰)
- 遇到’\n’或已输入size-1个字符时返回,总是包含’\0’ (如abcd,size=3,实际ab\0;如abcd,size=10,那么补充\n)
标准I/O – fgets – 示例
#define N 6char buf[N];fgets(buf, N, stdin);printf(“%s”, buf);
假设键盘输入分别是: abcd<回车> abcdef<回车> buf中的内容是?
abcd<回车> 终端显示:abcd\n
abcdef<回车> 终端显示:abcde\0
示例2
#include <stdio.h>#define F_PATH "./1.txt"int main(int argc,char *argv[]){FILE *fp;char *ret;char buff[100];fp = fopen(F_PATH,"r+");if(fp==NULL){perror("fopen");return 0;}ret = fgets(buff,5,fp);if(ret == NULL){perror("fgets");fclose(fp);return 0;}printf("buff=%s\n",buff);fclose(fp);
}//运行
linux@linux:~/Desktop$ cat 1.txt
wb
linux@linux:~/Desktop$ ./a.out
buff=wblinux@linux:~/Desktop$ echo abcde > 1.txt
linux@linux:~/Desktop$ cat 1.txt
abcde
linux@linux:~/Desktop$ ./a.out
buff=abcd
6 标准I/O – 按行输出
下列函数用来输出字符串:
#include <stdio.h>
int puts(const char *s);
int fputs(const char *s, FILE *stream);
- 成功时返回非负整数;出错时返回EOF
- puts将缓冲区s中的字符串输出到stdout,并追加’\n’,类似printf
- fputs将缓冲区s中的字符串输出到stream,不追加 ‘\n’
标准I/O – fputs – 示例
puts(“hello world”);FILE *fp;char buf[] = “hello world”;if ((fp = fopen(argv[1], “a”)) == NULL) { perror(“fopen”); return -1;}fputs(buf, fp);
示例2
#include <stdio.h>#define F_PATH "./1.txt"int main(int argc,char *argv[]){FILE *fp;int ret;fp = fopen(F_PATH,"r+");if(fp==NULL){perror("fopen");return 0;}puts("hello world");fputs("hello world\n",stdout);printf("hello world\n");ret = fputs("abcdef",fp);if(ret == -1){perror("fputs");}fclose(fp);
}//运行结果
linux@linux:~/Desktop$ ./a.out
hello world
hello world
hello world
linux@linux:~/Desktop$ cat 1.txt
abcdeflinux@linux:~/Desktop$
注意:输出的字符串中可以包含’\n’,也可以不包含
7 标准I/O – 思考和练习
如何统计一个文本文件包含多少行?
fgetc ? 效率低
fgets ? 如何判断读取了一行?
#include <stdio.h>int main() {FILE *file;char line[256];int lineCount = 0;// 打开文件file = fopen("file.txt", "r");if (file == NULL) {printf("无法打开文件。\n");return 1;}// 统计行数while (fgets(line, sizeof(line), file) != NULL) {if (line[0] != '\n') { // 判断是否读取了一行非空行printf("读取了一行:%s", line);}lineCount++;}// 关闭文件fclose(file);printf("文件包含 %d 行。\n", lineCount);return 0;
}
需要注意的是,fgets() 函数会保留读取到的换行符('\n')字符,因此在判断是否读取了一行时,需要排除只包含换行符的空行。示例代码中使用 if 语句来进行过滤,只输出非空行。
另外,示例代码中对行缓冲区的大小进行了固定设置为 256 字节,具体根据实际需求和文件内容的最大长度进行适当调整。