【玩转Linux】标准IO函数

  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主
  • 快上,一起学习!
  • 送给读者的一句鸡汤:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢

标准IO函数

        标准IO函数是C语言标准库提供的一组用于输入和输出的函数,通常是以缓冲区为基础实现

【玩转Linux】标准io缓冲区的操作_祐言QAQ的博客-CSDN博客

的,可以提高程序的性能和效率。标准IO函数还可以通过文件指针操作文件,今天主要来学习一些常见的标准IO函数以及通过文件指针操作文件

1.fopen() / fclose()     

(1)功能:
        fopen():打开一个文件,返回一个文件指针,用于后续对文件的读写操作。
        fclose():关闭一个已打开的文件,释放相关资源。
(2)头文件:
        fopen()和fclose()函数需要包含头文件
(3)原型:
        fopen():FILE *fopen(const char *filename, const char *mode);
        fclose():int fclose(FILE *stream);

(4)返回值:

  • fopen():如果文件打开成功,返回指向该文件的文件指针;如果打开失败,返回 NULL
  • fclose():成功关闭文件返回0,关闭失败返回非零值。

(5)示例:

FILE* fp = fopen("example.txt", "r");  // 以只读方式打开文件
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 读取文件内容
char buffer[10] = "hello";
fgets(buffer, 10, fp);
printf("文件内容:%s\n", buffer);
fclose(fp);  // 关闭文件

        想必大家看到这个例子也很懵,在fopen函数中的这个“r”是什么,其实这是打开文件的模式(mode),它一共有六种,分别是:

【玩转Linux】标准IO函数_第1张图片

2.fgetc()和getc()和getchar(),以及fputc()和putc()和putchar()    

(1)功能:
        fgetc():从文件中读取一个字符。
        getc():从文件中读取一个字符。
        getchar():从标准输入中读取一个字符。
        fputc():将一个字符写入文件。
        putc():将一个字符写入文件。
        putchar():将一个字符写入标准输出。
(2)头文件:
        上述函数需要包含头文件
(3)原型:
        fgetc():int fgetc(FILE *stream);
        getc():int getc(FILE *stream);
        getchar():int getchar(void);
        fputc():int fputc(int ch, FILE *stream);
        putc():int putc(int ch, FILE *stream);
        putchar():int putchar(int ch);

值得注意的是:

fgetc()是函数
getc()是宏//getc(stdin)等同于getchar()
stream:己经打开的文件流
getchar()只能从标准输入流(键盘)获取一个字符,getc()和fgetc()可以自定义从文件流读取一个字符

fputc()是函数
putc()是宏//putc('a',stdout)等同于putchar('a')
stream:已经打开的文件流
putchar()只能从标准输入流(键盘)获取一个字符,getc()和fgetc()可以自定义从文件流读取一个字符

(4)返回值

  • fgetc()getc()getchar()返回读取的字符的ASCII码值。
  • fputc()putc()putchar()返回写入的字符的ASCII码值。

(5)示例:  

FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 读取文件内容并输出
int c;
while ((c = fgetc(fp)) != EOF) {
    putchar(c);
}
fclose(fp);

FILE* fp2 = fopen("output.txt", "w");
if (fp2 == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 向文件中写入数据
fputc('H', fp2);
fputc('e', fp2);
fputc('l', fp2);
fputc('l', fp2);
fputc('o', fp2);
fclose(fp2);

3.fgets()/gets()/fputs()/puts()  

(1)功能:
    fgets():从文件中读取一行字符。
    gets():从标准输入中读取一行字符。
    fputs():将一行字符写入文件。
    puts():将一行字符写入标准输出。
(2)头文件:
    上述函数需要包含头文件
(3)原型:
    char *fgets(char *str, int n, FILE *stream);
    char *gets(char *str);
    int fputs(const char *str, FILE *stream);
    int puts(const char *str);
(4)返回值:
    fgets():成功读取字符返回 str 的地址;读取失败或到达文件末尾返回 NULL。
    gets():成功读取字符返回 str 的地址;读取失败或到达文件末尾返回 NULL。
    fputs():成功写入字符返回非负值;写入失败返回 EOF。
    puts():成功写入字符返回非负值;写入失败返回 EOF。

(5)示例:

	// 打开一个文件
	FILE *fp = fopen("1.txt", "r+");	//以读写打开文件,但是要求文件必须存在
	if(fp == NULL)
	{
		perror("fopen() fail");
		exit(errno);
	}
	
	// 从文件中读取一个字符
	int ch = fgetc(fp);
	printf("ch = %c\n", ch);
	ch = getc(fp);
	printf("ch = %c\n", ch);
	
	getchar();	//默认从标准输入读取 getc(stdin);
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 读取文件内容并输出
char buffer[100];
while (fgets(buffer, 100, fp) != NULL) {
    printf("%s", buffer);
}
fclose(fp);

FILE* fp2 = fopen("output.txt", "w");
if (fp2 == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 向文件中写入数据
fputs("Hello, world!\n", fp2);
fputs("This is a test.\n", fp2);
fclose(fp2);
    FILE *fp = fopen("1.txt", "r+");    // 以读写打开文件,要求文件必须存在
    if (fp == NULL) {
        perror("fopen() fail");
        exit(errno);
    }

    // 从文件中读取一个字符
    int ch = 'A';
    fputc(ch, fp);
    putc('B', fp);

    // 将文件指针移动到文件开头
    fseek(fp, 0, SEEK_SET);

    // 从文件中读取一个字符并打印到终端
    int read_ch = fgetc(fp);
    putchar(read_ch);

    fclose(fp); // 关闭文件

    return 0;
}

值得注意的有以下几点:
        (1)fgets()跟fgetc()一样,当其返回NULL时并不能确定究竟是达到文件末尾还是碰到错误,需要用feof()/ferror()来进一步判断。
       (2)fgets()每次读取至多不超过size个字节的一行,所谓“一行”即数据至多包含一个换行符'\n'。
        (3)gts()是一个已经过时的接口,因为他没有指定自定义缓冲区s的大小,这样很容易造成缓冲区溢出,导致程序段访问错误。
        (4)fgets()和fputs(),gets()和puts()一般成对使用,鉴于gets()的不安全性,一般建议使用前者。

4.feof()/ferror()   

功能:
    feof():检查文件流的文件结束标志,判断是否已经读取到文件末尾。
    ferror():检查文件流的错误标志,判断文件读取是否出错。
头文件:
    上述函数需要包含头文件
原型:
    feof():int feof(FILE *stream);
    ferror():int ferror(FILE *stream);
返回值:
    feof():如果到达文件末尾,返回非零值(true);否则返回0(false)。
    ferror():如果文件读取出错,返回非零值(true);否则返回0(false)。

示例:

	// 打开一个文件
	FILE *fp = fopen("1.txt", "a+");	//以读写打开文件,但是要求文件必须存在
	if(fp == NULL)
	{
		perror("fopen() fail");
		exit(errno);
	}
	
	while(1)
	{
		int ch = fgetc(fp);
		if(ch == EOF)
		{
			if(feof(fp))	//为真,说明文件读到末尾
			{
				printf("文件已读完\n");
				break;
			}
			if(ferror(fp))		//为真,说明文件读取出错
			{
				perror("fgetc() fail");
				exit(errno);
			}
		}
		
		// 输出到屏幕
		printf("%c\n", ch);
	}
	
	// 关闭文件
	fclose(fp);

  5.fread(/fwrite()    

功能:
    fread():从文件中读取一段数据。
    fwrite():将一段数据写入文件。
头文件:
    上述函数需要包含头文件
原型:
    size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:
    fread():返回实际成功读取的数据项数量,如果出错或到达文件末尾,返回值可能小于 nmemb。
    fwrite():返回实际成功写入的数据项数量,如果出错,返回值可能小于 nmemb。
示例:

struct student {
    char name[20];
    int age;
};

// 写入结构体数据到文件中
struct student s1 = {"Tom", 18};
FILE* fp = fopen("example.bin", "wb");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fwrite(&s1, sizeof(struct student), 1, fp);
fclose(fp);

// 从文件中读取结构体数据
struct student s2;
fp = fopen("example.bin", "rb");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fread(&s2, sizeof(struct student), 1, fp);
printf("姓名:%s,年龄:%d\n", s2.name, s2.age);
fclose(fp);

6.fseek()/ftell()/rewind 

功能:
    fseek():在文件中定位指针的位置,用于设置文件指针的位置。
    ftell():获取文件指针当前位置的偏移量。
    rewind():将文件指针重新定位到文件的起始位置。
头文件:
    上述函数需要包含头文件
原型:
    int fseek(FILE *stream, long offset, int whence);
    long ftell(FILE *stream);
    void rewind(FILE *stream);
返回值:
    fseek():成功定位文件指针返回0,失败返回非零值。
    ftell():返回当前位置的偏移量。如果出错,返回 ftell() 出错的标识值 (-1)。
    rewind():无返回值。

示例:

FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
// 获取文件大小
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
printf("文件大小:%ld\n", size);
// 将文件指针移回文件开头
rewind(fp);
// 读取文件内容并输出
char buffer[100];
while (fgets(buffer, 100, fp) != NULL) {
    printf("%s", buffer);
}
fclose(fp);

7.printf()/fprintf()/sprintf()/snprintf()/scanf()/fscanf()/sscanf()

功能:
    printf():将格式化的数据输出到标准输出。
    fprintf():将格式化的数据输出到指定文件。
    sprintf():将格式化的数据输出到字符数组。
    snprintf():格式化数据输出到字符数组,并限制输出的字符数量。
    scanf():从标准输入读取格式化数据。
    fscanf():从指定文件读取格式化数据。
    sscanf():从字符数组读取格式化数据。
头文件:
上述函数需要包含头文件
原型:
    int printf(const char *format, ...);
    int fprintf(FILE *stream, const char *format, ...);
    int sprintf(char *str, const char *format, ...);
    int snprintf(char *str, size_t size, const char *format, ...);
    int scanf(const char *format, ...);
    int fscanf(FILE *stream, const char *format, ...);
    int sscanf(const char *str, const char *format, ...);
返回值:
    printf():成功打印字符数。
    fprintf():成功写入字符数,失败返回负值。
    sprintf():成功写入字符数。
    snprintf():成功写入字符数(不包括末尾的空字符),如果截断输出返回欲写入的字符数。
    scanf():成功读取的参数个数。
    fscanf():成功读取的参数个数。
    sscanf():成功读取的参数个数。

示例:

// 格式化输出数据到标准输出设备
int num = 123;
printf("数字:%d\n", num);

// 格式化输出数据到文件
FILE* fp = fopen("output.txt", "w");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fprintf(fp, "数字:%d\n", num);
fclose(fp);

// 将格式化数据写入字符串中
char str[20];
sprintf(str, "数字:%d\n", num);
printf("%s", str);

// 将格式化数据写入指定长度的字符串中
char str2[10];
snprintf(str2, 10, "数字:%d\n", num);
printf("%s", str2);

// 从标准输入设备读取数据
int num2;
printf("请输入一个数字:");
scanf("%d", &num2);
printf("输入的数字:%d\n", num2);

// 从文件中读取数据
fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("打开文件失败\n");
    return 1;
}
fscanf(fp, "数字:%d", &num2);
printf("从文件中读取的数字:%d\n", num2);
fclose(fp);

// 从字符串中读取数据
char str3[20] = "数字:456";
sscanf(str3, "数字:%d", &num2);
printf("从字符串中读取的数字:%d\n", num2);

关于格式控制符的一些解释:

格式控制符用于指定数据的输出格式。以下是常见的格式控制符:

整数类型:

        %d:有符号十进制整数
        %u:无符号十进制整数
        %o:无符号八进制整数
        %x:无符号十六进制整数(小写字母)
        %X:无符号十六进制整数(大写字母)


浮点数类型:

        %f:浮点数(以小数形式输出)
        %e:浮点数的指数表示(科学计数法,小写字母)
        %E:浮点数的指数表示(科学计数法,大写字母)
        %g:根据实际值自动选择%e或%f格式输出


字符类型:

        %c:字符
        %s:字符串


指针类型:

        %p:指针的地址值(以十六进制输出)


布尔类型:

        %d 或 %i:整数输出(0表示假,非零表示真)


特殊控制符:

        %%:输出百分号符号 %


        这些格式控制符可以用于 printf()、fprintf()、sprintf()、snprintf() 等输出函数,根据需要选择适合的格式控制符进行数据输出。

        

        更多C语言Linux系统相关文章,关注专栏:

   手撕C语言

            玩转linux

写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 感谢关注

你可能感兴趣的:(玩转Linux,服务器,开发语言,c语言,linux)