首页 > 其他分享 >【C语言标准库函数】标准输入输出函数详解2:字符串输入输出

【C语言标准库函数】标准输入输出函数详解2:字符串输入输出

时间:2024-09-28 09:19:37浏览次数:10  
标签:换行符 函数 fputs 输入输出 C语言 fgets 字符串 库函数 读取

目录

一、字符串输入函数

1.1. gets函数(已废弃)

1.1.1. 函数简介

1.1.2. 注意和废弃原因

1.2. fgets函数

1.2.1. 函数简介

1.2.2. 使用场景

1.2.3. 注意事项

1.2.4. 示例

二、字符串输出函数

2.1. puts函数

2.1.1. 函数简介

2.1.2. 使用场景

2.1.3. 注意事项

2.1.4. 示例

2.2. fputs函数

2.2.1. 函数简介

2.2.2. 使用场景

2.2.3. 注意事项

2.2.4. 示例

三、总结


在C语言中,字符串输入输出是编程中常见的操作,标准库提供了多个函数来支持这一功能。以下是对C语言中字符串输入输出函数的详细解析:

一、字符串输入函数

1.1. gets函数(已废弃)

1.1.1. 函数简介

  • 功能gets 函数用于从标准输入(stdin,通常是键盘)读取一行文本,直到遇到换行符(\n)为止,但它不会将换行符存储在目标字符串中。读取的字符串(包括自动添加的终止空字符 '\0')被存储在调用时指定的字符数组中。
  • 原型
char *gets(char *s);
  • 参数s:指向字符数组的指针,用于存储输入的字符串。
  • 返回值
    • 成功时,返回指向 s 的指针。注意,这个返回值在大多数情况下并不是特别有用,因为调用者已经知道了 s 的值。
    • 如果发生错误(尽管在标准输入上读取时很少发生错误),则 gets 的行为是未定义的。

1.1.2. 注意和废弃原因

  • 缓冲区溢出gets 函数的主要问题是它无法限制读入的字符串长度。如果输入的字符串超过了目标数组的大小,就会发生缓冲区溢出,这可能导致程序崩溃、数据损坏或安全漏洞(如缓冲区溢出攻击)。
  • C11标准废弃:由于上述安全问题,gets 函数在C11标准中被正式废弃,并在后续的C标准中继续被废弃。这意味着新的C程序应该避免使用 gets 函数,并使用更安全的替代函数,如 fgets
  • 注意:由于gets函数无法限制输入的长度,容易导致缓冲区溢出,因此在C11标准中被废弃。在实际编程中,推荐使用fgets函数代替。

1.2. fgets函数

作为 gets 的替代,fgets 函数提供了更多的安全性和灵活性。

1.2.1. 函数简介

  • 功能:从指定的输入流(如标准输入stdin)读取一行文本,直到遇到换行符、文件结束符EOF或已读取了指定数量的字符(不包括终止的空字符'\0'),然后将读取的字符串(包括换行符,如果读取到的话)存储到指定的字符数组中。
  • 原型char *fgets(char *str, int n, FILE *stream);
  • 参数str是指向字符数组的指针,用于存储读取的字符串;n是读取的最大字符数(包括终止的空字符'\0');stream是指向FILE对象的指针,表示输入流。
  • 返回值:成功时返回指向str的指针,失败时返回NULL。

1.2.2. 使用场景

fgets函数是C语言中用于从文件流(如文件、标准输入等)读取一行字符串的重要函数。它的使用场景非常广泛,包括但不限于:

  • 从标准输入读取字符串:在需要用户通过键盘输入字符串时,可以使用fgets从标准输入(stdin)读取一行文本。
  • 从文件读取数据:在处理文件时,经常需要逐行读取文件内容,fgets能够很好地满足这一需求。
  • 安全读取字符串:与gets函数相比,fgets能够限制读取的字符数,从而有效防止缓冲区溢出,提高程序的安全性。

1.2.3. 注意事项

在使用fgets函数时,需要注意以下几点:

  • 缓冲区大小:确保为fgets提供的缓冲区足够大,以容纳预期的输入,包括换行符和结尾的空字符\0。如果输入行太长,fgets会读取到换行符或达到缓冲区大小限制为止,但不会超出缓冲区边界。
  • 换行符处理fgets会将换行符(如果有的话)读取到字符串中。如果需要去除换行符,可以在读取后手动处理字符串。
  • 返回值检查fgets的返回值需要被检查以确定是否成功读取了数据。如果返回NULL,可能是到达文件末尾或发生错误,此时可以使用feofferror函数进一步判断具体原因。
  • 文件流状态:在多次调用fgets读取文件时,需要注意文件流的状态,确保在读取前文件流是有效的,并且在读取后根据需要关闭文件流。
  • 二进制文件处理fgets不适合用于读取二进制文件,因为它会将二进制数据当作文本处理,可能导致乱码或错误。

1.2.4. 示例

以下是一个使用fgets从标准输入读取一行字符串的示例:

#include <stdio.h>  
  
int main() {  
    char str[100]; // 定义一个字符数组作为缓冲区  
    printf("请输入一行字符串: ");  
    if (fgets(str, sizeof(str), stdin) != NULL) {  
        // 去除换行符(如果存在)  
        char *newline = strchr(str, '\n');  
        if (newline != NULL) {  
            *newline = '\0'; // 将换行符替换为空字符,以去除它  
        }  
        printf("你输入的字符串是: %s\n", str);  
    } else {  
        printf("读取失败\n");  
    }  
    return 0;  
}

 

在这个示例中,我们首先定义了一个字符数组str作为缓冲区,然后使用fgets从标准输入读取一行字符串。通过检查fgets的返回值,我们可以确定是否成功读取了数据。如果读取成功,我们使用strchr函数查找字符串中的换行符,并将其替换为空字符,以去除换行符。最后,我们打印出用户输入的字符串。如果读取失败,我们打印出错误信息。

二、字符串输出函数

2.1. puts函数

2.1.1. 函数简介

  • 功能:将指定的字符串输出到标准输出(通常是屏幕),并在字符串末尾自动添加一个换行符。
  • 原型int puts(const char *str);
  • 参数str是指向要输出的字符串的指针。
  • 返回值:成功时返回非负值,失败时返回EOF。

2.1.2. 使用场景

puts函数在C语言中主要用于将字符串输出到标准输出设备(通常是屏幕),并在字符串末尾自动添加一个换行符。这使得它在需要简单输出文本信息的场景下非常有用,比如:

  • 打印欢迎信息:在程序开始时,使用puts打印一条欢迎信息或程序简介。
  • 输出结果:在程序的某个阶段,使用puts输出计算结果或程序状态信息。
  • 调试信息:在开发过程中,使用puts输出调试信息,帮助开发者跟踪程序的执行流程和状态。

2.1.3. 注意事项

在使用puts函数时,需要注意以下几点:

  • 自动换行puts函数会在输出的字符串末尾自动添加一个换行符,因此不需要在字符串中手动添加。
  • 字符串结束符:传递给puts函数的字符串必须以空字符\0作为结束标志。如果字符串未以空字符结尾,puts函数会继续向后读取内存内容,直到遇到空字符为止,这可能导致未定义行为。
  • 返回值puts函数返回一个非负整数,表示成功输出的字符数(不包括自动添加的换行符)。如果发生错误,则返回EOF(通常是-1)。在实际编程中,应该检查puts的返回值以确保输出成功。
  • 性能考虑:相较于其他输出函数如printffwriteputs函数的执行速度可能较慢,因为它在每次调用时都会执行换行操作,并可能涉及系统IO的频繁调用。在需要高效输出大量数据时,应考虑使用其他函数。
  • 类型限制puts函数只能用于输出字符串,不能用于输出其他类型的数据(如整数、浮点数等)。如果需要输出其他类型的数据,应使用printf等函数。

2.1.4. 示例

以下是一个使用puts函数的示例代码:

#include <stdio.h>  
  
int main() {  
    char str[] = "Hello, World!";  
    puts(str); // 将字符串输出到屏幕,并在末尾自动添加换行符  
      
    // 直接向puts传递字符串字面量  
    puts("This is another line.");  
      
    return 0;  
}

输出结果:

在这个示例中,我们首先定义了一个字符数组str并初始化为"Hello, World!"。然后,我们使用puts函数将str指向的字符串输出到屏幕上,并在末尾自动添加了一个换行符。接着,我们直接向puts函数传递了一个字符串字面量"This is another line.",并将其输出到屏幕上。最终,我们得到了两行文本输出,每行文本末尾都有一个换行符。

2.2. fputs函数

2.2.1. 函数简介

  • 功能:将指定的字符串输出到指定的输出流中,但不自动添加换行符。
  • 原型int fputs(const char *str, FILE *stream);
  • 参数str是指向要输出的字符串的指针;stream是指向FILE对象的指针,表示输出流。
  • 返回值:成功时返回非负值,失败时返回EOF。

2.2.2. 使用场景

fputs函数是C语言标准库中的一个重要函数,其使用场景主要涉及到向文件流或标准输出流中写入字符串。具体来说,fputs函数的使用场景包括但不限于:

  • 文件写入:当需要将字符串数据写入到文件中时,可以使用fputs函数。它允许开发者指定要写入的文件流和字符串内容,非常适合于逐行写入文件或追加内容到文件末尾的场景。
  • 标准输出:虽然fputs主要用于文件写入,但也可以将标准输出流(stdout)作为目标流,从而向屏幕输出字符串。这在需要简单输出文本信息且不需要自动换行时非常有用。

2.2.3. 注意事项

在使用fputs函数时,需要注意以下几点:

  • 字符串结束符:传递给fputs的字符串必须以空字符\0作为结束标志。fputs会输出字符串直到遇到第一个\0字符,但不会输出该字符本身。
  • 换行符fputs不会自动在字符串末尾添加换行符。如果需要换行,需要在字符串中显式包含换行符(\n)。
  • 返回值检查fputs函数返回一个非负整数(通常是成功写入的字符数,但不包括终止的空字符\0)来表示成功,或在发生错误时返回EOF(通常是-1)。在实际编程中,应该检查fputs的返回值以确保写入操作成功。
  • 文件流状态:在多次调用fputs写入文件时,需要注意文件流的状态,确保在写入前文件流是有效的,并且在写入后根据需要关闭文件流。
  • 缓冲区:虽然fputs本身不直接涉及缓冲区管理,但在进行大量文件写入操作时,需要注意操作系统的缓冲区大小和写入性能,以避免不必要的性能瓶颈。

2.2.4. 示例

以下是一个使用fputs函数向文件写入字符串的示例代码:

#include <stdio.h>  
  
int main() {  
    FILE *fp;  
    char *str = "Hello, World!\n";  
  
    // 打开文件用于写入  
    fp = fopen("example.txt", "w");  
    if (fp == NULL) {  
        perror("打开文件失败");  
        return 1;  
    }  
  
    // 使用fputs写入字符串  
    fputs(str, fp);  
  
    // 关闭文件  
    fclose(fp);  
  
    return 0;  
}

在这个示例中,我们首先定义了一个指向FILE类型的指针fp和一个字符串str。然后,我们使用fopen函数以写入模式("w")打开了一个名为"example.txt"的文件,并将文件指针赋值给fp。如果文件打开失败,我们使用perror函数打印错误信息并返回1。接下来,我们使用fputs函数将字符串str写入到文件中。最后,我们使用fclose函数关闭文件以释放资源。

如果运行上述代码,并在文件系统中检查"example.txt"文件的内容,会发现文件中包含了"Hello, World!\n"这个字符串。注意,由于我们在字符串中显式包含了换行符\n,所以文件中的内容会换行显示(这取决于使用的文本编辑器或查看工具)。

三、总结

在C语言处理字符串输入输出时,fgetsfputs函数因提供更高的安全性和灵活性而备受推崇。fgets能安全地从指定流中读取字符串,防止缓冲区溢出;fputs则负责向流中写入字符串,但不自动添加换行符,给予开发者更多控制。相比之下,gets因安全漏洞已被弃用。而puts虽便捷,但自动换行特性限制了其在需要精细控制输出格式场景下的应用。因此,在编写现代C代码时,应优先考虑fgetsfputs

标签:换行符,函数,fputs,输入输出,C语言,fgets,字符串,库函数,读取
From: https://blog.csdn.net/weixin_37800531/article/details/142580039

相关文章

  • 输入输出返回值
    大部分情况下,输入输出函数返回值没有被特别关注,但在某些情况下,这些返回值格外有研究意义。返回值的不同形态C语言printf和scanf返回值分别为输出字节个数以及成功输入的变量个数。大部分情况下,printf返回个数并不关心,可以在调用函数前面加(void)强制忽略返回值。ObjC相......
  • C语言 16 系统库
    前面了解了如何使用#include引入其他文件,接着来了解一下系统提供的一些常用库。字符串计算字符串长度:#include<stdio.h>#include<string.h>intmain(){char*c="HelloWorld!";//使用strlen计算长度,注意返回值类型是size_t(别名而已,本质上就是unsignedlong)......
  • C语言 16 系统库
    前面了解了如何使用#include引入其他文件,接着来了解一下系统提供的一些常用库。字符串计算字符串长度:#include<stdio.h>#include<string.h>intmain(){char*c="HelloWorld!";//使用strlen计算长度,注意返回值类型是size_t(别名而已,本质上就是unsigned......
  • C语言指针系列3——含野指针+assert
    今天我们来继续感受指针的魅力~野指针首先我们来了解一下什么叫野指针~1.定义    野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定......
  • C语言VS实用调试技巧
    文章目录一、什么是bug?二、什么是调试?三、Debug和Release四、VS调试快捷键4.1环境准备4.2调试快捷键五、监视和内存观察5.1监视5.2内存六、调试举例七、编程常见错误归类7.1编译型错误7.2链接型错误7.3运行时错误一、什么是bug?......
  • 【C语言】分支和循环
    个人主页:zxctscl如有转载请先通知文章目录前言1.if语句1.1if1.2else1.3分支中包含多条语句1.4嵌套if1.5悬空else问题2.关系操作符3.逻辑操作符:&&||!3.1逻辑取反运算符(!)3.2与运算符(&&)3.3或运算符(||)3.4举例3.5短路4.switch语句4.1if语句和switch语......
  • 【C语言训练题库】第一次出现的字符
     ......
  • 实验1 C语言输入输出和简单程序编写
    任务11#include<stdio.h>2intmain()3{4printf("00\n");5printf("<H><H>\n");6printf("IIII");78return0;9} 1#include<stdio.h>2intmain()3{4......
  • C语言数据类型及存储
    C语言数据类型分类C语言数据类型分为内置类型和自定义类型内置类型内置类型是C语言自带的数据类型,整形,浮点型,字符型,指针,空类型等都属于内置类型,他们的意义比较单一,往往用来表示一个含义,比如整形,可以用来记录年龄,次数等数据,浮点类型可以用来存放身高,成绩等实数类型。void(空......
  • 【Leecode 随笔】C语言版看了不后悔系列持续更新中。。。(四)
    文章目录题目一:实现一个函数,计算两个整数的最大公约数(GCD)题目分析:解题思路:示例代码:代码解析:题目二:实现一个函数,判断一个整数是否为素数题目分析:解题思路:示例代码:代码解析:题目三:实现一个函数,对给定的字符串进行排序(按字母顺序)题目分析:解题思路:示例代码:代码解析:......