lv4 嵌入式开发-3 标准IO的读写

目录

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  
 int  fgetc(FILE *stream); 
 int  getc(FILE *stream);   //宏   
 int  getchar(void);

成功时返回读取的字符;若到文件末尾或出错时返回EOF(-1),

区别:

getchar()等同于fgetc(stdin),但是只能读取标准输入即键盘内容,不能读文件

getc和fgetc区别是一个是宏一个是函数

注意事项:

  1. -函数返回值是int类型不是char类型,主要是为了扩展返回值的范围。
  2. -stdin 也是FILE *的指针,是系统定义好的,指向的是标准输入(键盘输入)
  3. -打开文件后读取,是从文件开头开始读。读完一个后读写指针会后移。读写注意文件位置!
  4. -调用getchar会阻塞,等待你的键盘输入

标准I/O – fgetc – 示例

#include 

#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 

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  
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 
#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 

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  
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  6

  char buf[N];
  fgets(buf, N, stdin);
  printf(“%s”, buf);

假设键盘输入分别是: abcd<回车>     abcdef<回车>   buf中的内容是?

abcd<回车> 终端显示:abcd\n

abcdef<回车> 终端显示:abcde\0

示例2

#include 

#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=wb

linux@linux:~/Desktop$ echo abcde > 1.txt 
linux@linux:~/Desktop$ cat 1.txt 
abcde
linux@linux:~/Desktop$ ./a.out 
buff=abcd

6 标准I/O – 按行输出

下列函数用来输出字符串:

#include  
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 

#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 

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 字节,具体根据实际需求和文件内容的最大长度进行适当调整。

你可能感兴趣的:(嵌入式开发,linux,I/O)