当前位置: 首页 > news >正文

2025-02-26 学习记录--C/C++-C 库函数gets()、fgets()、strcspn()、puts()

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻

一、C 库函数 - gets() 🍭

C 标准库 - <stdio.h>
在这里插入图片描述

下面是 gets() 函数的声明:👇🏻
char *gets(char *str)

  • gets() 函数 从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中。当读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
    • 如果成功,该函数返回 str
    • 如果发生错误或者到达文件末尾时还未读取任何字符,则返回 NULL
  • str – 这是指向一个字符数组的指针,该数组存储了 C 字符串。

在这里插入图片描述

#include <stdio.h>  // 引入标准输入输出库,用于使用 printf 和 gets 等函数int main() // 主函数,程序入口
{char str[50]; // 定义一个字符数组 str,用于存储用户输入的字符串,最大长度为 49 个字符(最后一个字符是字符串结束符 '\0')printf("请输入一个字符串:"); // 提示用户输入一个字符串gets(str); // 使用 gets 函数从标准输入读取用户输入的字符串,并存储到字符数组 str 中printf("您输入的字符串是:%s", str); // 输出用户输入的字符串,%s 是格式化字符串的占位符return 0; // 返回 0,表示程序正常结束
}

在这里插入图片描述

二、C 中使用 gets() 提示 warning: this program uses gets(), which is unsafe.

在这里插入图片描述

gets() 不安全是因为你给了他一个缓冲区,但是你却没有告诉它这个缓冲区到底有多大,也不知道输入的内容到底有多大,输入的内容可能超出缓冲区的结尾,引起你的程序崩溃。

解决方法可以使用 fgets() 替代:👇🏻

// 使用 gets()
char buffer[4096]; // 定义一个字符数组 buffer,用于存储用户输入的字符串,大小为 4096 个字符
gets(buffer);      // 使用 gets 函数从标准输入读取用户输入的字符串,并存储到 buffer 中// 使用 fgets() 替换 gets()
char buffer[4096]; // 定义一个字符数组 buffer,用于存储用户输入的字符串,大小为 4096 个字符
fgets(buffer, (sizeof buffer / sizeof buffer[0]), stdin); // 使用 fgets 函数从标准输入读取用户输入的字符串,并存储到 buffer 中
// fgets 的第二个参数是缓冲区的大小,这里通过 (sizeof buffer / sizeof buffer[0]) 计算数组的实际大小。
// (sizeof buffer / sizeof buffer[0]) 是一种通用的计算数组大小的方式,适用于任何类型的数组。
// stdin 表示从标准输入(通常是键盘)读取数据。
  • fgets 会限制输入的字符数量,确保不会超过缓冲区的大小,从而避免缓冲区溢出。
  • fgets 会读取一行内容(直到遇到换行符或文件末尾),并将换行符(如果有)也存储到字符串中
  • 【注意】🌹 如果不需要换行符,可以手动去除: 👇🏻
    • buffer[strcspn(buffer, “\n”)] = ‘\0’; // 去除换行符

以下是使用 fgets 的完整示例代码,包括去除换行符: 👇🏻

#include <stdio.h>  // 引入标准输入输出库,用于使用 printf 和 fgets 等函数
#include <string.h> // 引入字符串处理库,用于使用 strcspn 函数【strcspn 函数用于查找字符串中第一个匹配指定字符集中任意字符的位置】int main() // 主函数,程序入口
{char buffer[4096]; // 定义一个字符数组 buffer,用于存储用户输入的字符串,大小为 4096 个字符printf("请输入一个字符串:"); // 提示用户输入一个字符串fgets(buffer, (sizeof buffer / sizeof buffer[0]), stdin); // 使用 fgets 函数从标准输入读取用户输入的字符串,并存储到 buffer 中// 参数说明:// - buffer:目标字符数组,用于存储输入的字符串。// - (sizeof buffer / sizeof buffer[0]):计算 buffer 的大小,确保不会超出缓冲区范围。// - stdin:表示从标准输入(通常是键盘)读取数据。// 去除 fgets 可能读取的换行符buffer[strcspn(buffer, "\n")] = '\0'; // 使用 strcspn 查找换行符的位置,并将其替换为字符串结束符 '\0'// 参数说明:// - buffer:要查找的字符串。// - "\n":要查找的字符集(这里只有换行符)。// - strcspn 返回第一个匹配字符的索引,如果没有匹配字符,则返回字符串的长度。printf("您输入的字符串是:%s\n", buffer); // 输出用户输入的字符串// %s 是格式化字符串的占位符,表示输出一个字符串。return 0; // 返回 0,表示程序正常结束
}

在这里插入图片描述

总结: 🐯

  • gets 的问题:不安全,容易导致缓冲区溢出,不推荐使用。

  • fgets 的优点:安全,可以限制输入长度,避免缓冲区溢出。

  • 改进建议:在实际开发中,始终使用 fgets 替代 gets,并根据需要处理换行符。

三、C 库函数 - fgets() 🍭

C 标准库 - <stdio.h>

在这里插入图片描述

下面是 fgets() 函数的声明:👇🏻
char *fgets(char *str, int n, FILE *stream)

  • fgets() 函数 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
    • 如果成功,该函数返回相同的 str 参数。
    • 如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。
    • 如果发生错误,返回一个空指针。
  • str – 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
  • n – 这是要读取的最大字符数(包括最后的空字符)。通常是使用str 传递的数组长度
  • stream – 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。

在这里插入图片描述

#include <stdio.h>  // 引入标准输入输出库,用于使用文件操作函数(如 fopen、fgets、puts 等)int main() // 主函数,程序入口
{FILE *fp;       // 定义一个文件指针 fp,用于操作文件char str[60];   // 定义一个字符数组 str,用于存储从文件中读取的内容,最大长度为 59 个字符(最后一个字符是字符串结束符 '\0')/* 打开用于读取的文件 */fp = fopen("file.txt", "r"); // 以只读模式打开名为 "file.txt" 的文件,并将文件指针赋值给 fpif (fp == NULL) { // 检查文件是否成功打开perror("打开文件时发生错误"); // 如果文件打开失败,使用 perror 输出错误信息return -1; // 返回 -1,表示程序异常结束}/* 从文件中读取内容 */if (fgets(str, 60, fp) != NULL) { // 使用 fgets 从文件中读取一行内容(最多 59 个字符),并存储到 str 中/* 向标准输出 stdout 写入内容 */puts(str); // 使用 puts 将读取的内容输出到标准输出(通常是屏幕)}fclose(fp); // 关闭文件,释放文件指针return 0; // 返回 0,表示程序正常结束
}

在这里插入图片描述

四、C 库函数 - strcspn() 🍭

C 标准库 - <string.h>
在这里插入图片描述

下面是 strcspn() 函数的声明:👇🏻
size_t strcspn(const char *str1, const char *str2)

  • strcspn() 函数 检索字符串 str1 开头连续有几个字符都不含字符串 str2 中的字符。
    • 该函数返回 str1 开头连续都不含字符串 str2 中字符的字符数。
  • str1 – 要被检索的 C 字符串。
  • str2 – 该字符串包含了要在 str1 中进行匹配的字符列表。

在这里插入图片描述

#include <stdio.h>  // 引入标准输入输出库,用于使用 printf 等函数
#include <string.h> // 引入字符串处理库,用于使用 strcspn 等函数int main() // 主函数,程序入口
{int len; // 定义一个整型变量 len,用于存储 strcspn 函数的返回值const char str1[] = "ABCDEF4960910"; // 定义一个常量字符数组 str1,初始化为 "ABCDEF4960910"const char str2[] = "013"; // 定义一个常量字符数组 str2,初始化为 "013"// 使用 strcspn 函数计算 str1 开头连续都不含字符串 str2 中字符的字符数:ABCDEF496 共9个len = strcspn(str1, str2); // 输出结果:第一个匹配的字符 前 有 len 个,所以 第一个匹配的字符 位置 是 len + 1printf("第一个匹配的字符是在 %d\n", len + 1);return 0; // 返回 0,表示程序正常结束
}

在这里插入图片描述

五、C 库函数 - puts() 🍭

C 标准库 - <stdio.h>
在这里插入图片描述

下面是 puts() 函数的声明:👇🏻
int puts(const char *str)

  • puts() 函数 把一个字符串写入到标准输出 stdout,直到空字符,但不包括空字符换行符会被追加到输出中。
    • 如果成功,该函数返回一个非负值为字符串长度(包括末尾的 \0);
    • 如果发生错误则返回 EOF
  • str – 这是要被写入的 C 字符串。

在这里插入图片描述

#include <stdio.h>  // 引入标准输入输出库,用于使用 puts 等函数
#include <string.h> // 引入字符串处理库,用于使用 strncpy 等函数int main() // 主函数,程序入口
{char str1[15]; // 定义一个字符数组 str1,用于存储字符串,大小为 15 个字符char str2[15]; // 定义一个字符数组 str2,用于存储字符串,大小为 15 个字符// 使用 strncpy 替代 strcpy,指定最大复制长度strncpy(str1, "FIGHTING1", sizeof(str1) - 1); // 将字符串 "FIGHTING1" 复制到 str1 中,最多复制 sizeof(str1) - 1 个字符strncpy(str2, "FIGHTING2", sizeof(str2) - 1); // 将字符串 "FIGHTING2" 复制到 str2 中,最多复制 sizeof(str2) - 1 个字符// 手动添加字符串结束符str1[sizeof(str1) - 1] = '\0'; // 确保 str1 的最后一个字符是字符串结束符 '\0'str2[sizeof(str2) - 1] = '\0'; // 确保 str2 的最后一个字符是字符串结束符 '\0'puts(str1); // 使用 puts 函数输出 str1 的内容(自动添加换行符)puts(str2); // 使用 puts 函数输出 str2 的内容(自动添加换行符)return 0; // 返回 0,表示程序正常结束
}

在这里插入图片描述
在这里插入图片描述


http://www.mrgr.cn/news/92467.html

相关文章:

  • Linux系统里怎么截图
  • Framework层JNI侧Binder
  • 顾客关系管理CRM思维导图模版
  • Vxe UI 根据vxe-tabs 绑定不同的值,渲染生成不同的 tabls(页签)内容
  • XXE漏洞:原理、危害与修复方法详解
  • 影响板材的热导率有哪些因素?
  • Java中的函数式编程:Lambda与Stream API实战
  • Java中的异常处理:最佳实践与常见误区
  • docker安装MongoDB
  • 操作定制万年历投屏模拟点单叫号器
  • 计算机组成与接口10
  • 用AI写游戏3——deepseek实现kotlin android studio greedy snake game 贪吃蛇游戏
  • (亲测有效)android studio gradle下载慢的解决方法
  • <网络> 网络基础3
  • 冒泡排序算法
  • 前端实现rsa加密功能
  • 【学写LibreCAD】1 LibreCAD主程序
  • 力扣-动态规划-494 目标和
  • ARM Coretex-M核心单片机(STM32)分析hardfault的原因
  • Docker快速使用指南