C 语言输入字符串核心就是把键盘输入的字符存入 char 类型数组,并且保证字符串末尾带有空结束标记,主流实现方案包含 scanf fgets getchar 循环读取三种,其中 fgets 安全性最高,支持读取带空格的整行内容并且可以限制读取长度,scanf 写法简单但是遇到空格就停止读取,getchar 循环读取灵活性最强适合自定义读取规则。C 语言本身没有专门的字符串类型,字符串本质就是连续字符内存单元,最后以空字符作为终止标志,所有输入函数读取完成之后都要围绕这个终止标记做处理,同时还要理解标准输入缓冲区机制,键盘输入的数据会先缓存,按下回车之后输入函数才从缓冲区取出字符,缓冲区残留换行符是初学者最容易踩坑的点,会造成后续输入直接读到空内容。
一 各输入函数对比表
| 函数 | 能否读取空格 | 长度限制 | 是否保存回车符 | 安全等级 |
|---|---|---|---|---|
| scanf %s | 不能 | 可设置宽度 | 不保存 | 中等 |
| fgets | 可以 | 强制设置最大长度 | 会保存 | 高 |
| getchar 循环 | 可以 | 代码自行控制 | 代码自行处理 | 高 |
| gets | 可以 | 无长度限制 | 丢弃回车 | 极低 标准已移除 |
二 scanf 读取字符串
首先定义字符数组作为存储容器,例如 char str [120];
基础调用 scanf ("% s", str);
执行逻辑是跳过开头空白字符,持续读取字符,一旦碰到空格 制表符 换行就停止,读取完成之后自动追加空结束标记。
安全改进写法 scanf ("%119s", str); 数字代表最多读取 119 个字符,预留最后一个字节存放空结束标记,防止数组越界。
注意数组名本身就是首地址,所以这里不需要写取地址符号,如果额外加上取地址符会出现类型不匹配编译报错。
缺点非常明显,只要用户输入句子中间有空格,后面内容就不会被读入,仍然留在输入缓冲区。
三 fgets 读取字符串
函数调用形式 fgets (str, 最大字符数,stdin);
stdin 代表标准输入也就是键盘,第二个参数是数组总大小,函数实际最多读取总大小减 1 个字符,自动补上空结束标记。
执行特点是可以读取整行,包含中间空格,读到换行符就停止,并且会把换行符一起存入数组。
后续经常需要清理换行符,遍历数组找到换行符位置,替换成空字符,否则打印字符串的时候会额外多出一行。
这个函数是现代 C 语言教学和工程开发优先推荐方案,因为自带长度上限,从根源降低缓冲区溢出风险。
四 getchar 循环手动读取字符串
循环调用 getchar,每次读取单个字符,存入字符数组,设置下标上限防止越界,检测到回车就退出循环,最后手动写入空结束标记。
优势是可以自定义终止条件,比如遇到指定符号停止,也可以自行过滤不需要的字符,适合特殊业务需求。
劣势是代码编写量更大,需要自己维护下标变量,还要处理各种边界情况,适合理解底层输入原理。
五 gets 函数说明
调用写法 gets (str);
可以读取整行包含空格,读取到回车就终止,同时丢弃回车符,但是它没有任何长度校验,用户输入字符超过数组容量就会覆盖相邻内存,引发缓冲区溢出安全漏洞,C11 标准已经正式删除 gets,新项目禁止继续使用。
六 深层原理与常见坑点
C 语言字符串依靠空字符识别结尾,如果输入之后没有写入空结束标记,strlen strcpy 等字符串函数会持续向后读取内存,直到随机碰到空字符,出现乱码或者程序崩溃。
缓冲区残留问题,如果前面使用 scanf 读取整数,回车会留在缓冲区,后面调用 fgets 或者 scanf 读取字符串,会直接读到空行,解决办法是循环读取丢弃多余换行字符。
数组容量规划,打算保存 N 个有效字符,数组定义长度至少为 N 加 1,额外这一个字节专门用来存放空结束标记。
输入超长场景,fgets 会保留多余字符继续留在缓冲区,下一次输入函数会继续读取剩余内容,需要根据项目需求决定是否清空缓冲区。
【常见问题】
问题 1 C 语言怎样输入字符串才能读取带空格的整句话
回答 1 C 语言怎样输入字符串想要读取带空格整句话,不适合使用 scanf% s,推荐使用 fgets 或者 getchar 循环读取,scanf% s 遇到空格就终止读取,无法完整保存句子中间空格。
问题 2 C 语言怎样输入字符串用 fgets 之后为什么打印会多一行
回答 2 C 语言怎样输入字符串使用 fgets 时,函数会把回车对应的换行符存入字符数组,打印的时候就会额外换行,需要找到这个换行符替换为空结束标记。
问题 3 C 语言怎样输入字符串为什么不推荐继续使用 gets 函数
回答 3 C 语言怎样输入字符串里面 gets 没有长度限制,超长输入会造成缓冲区溢出,存在严重安全风险,C11 标准已经移除 gets,工程开发替换成 fgets。
问题 4 C 语言怎样输入字符串使用 scanf 为什么不需要取地址符
回答 4 C 语言怎样输入字符串调用 scanf 读取字符串的时候,数组名本身代表数组首地址,所以直接写数组名即可,额外添加取地址符会造成类型错误,编译无法通过。
【免责申明】
本文是 C 语言怎样输入字符串相关基础原理与函数用法讲解,不同编译器对函数行为 警告提示存在差异,示例代码仅用于学习演示,实际项目还需要增加非法输入校验 缓冲区清空 异常捕获处理,本文不覆盖全部极端输入场景,程序运行产生异常由开发者自行负责。
本文来自作者[居家通识百问]投稿,不代表万里行信息网立场,如若转载,请注明出处:https://www.wlx315.cn/kpjh/202611/7566.html
评论列表(4条)
我是万里行信息网的签约作者“居家通识百问”!
希望本篇文章《C 语言怎样输入字符串 常用函数深度解析》能对你有所帮助!
本站[万里行信息网]内容主要涵盖:生活百科,小常识,生活小窍门,知识分享
本文概览:C 语言输入字符串核心就是把键盘输入的字符存入 char 类型数组,并且保证字符串末尾带有空结束标记,主流实现方案包含 scanf fgets getchar 循环读取三种,其中 fgets 安全性最高,支持读取带空格的整行内容并且可以限制读取长度,scanf 写法简单但是遇到空格就停止读取,getchar 循环读取灵活性最强适合自定义读取规则。C 语言本身没有专门的字符串类型,字符串本质就是连续字符内存单元,最后以空字符作为终止标志,所有输入函数读取完成之后都要围绕这个终止标记做处理,同时还要理解标准输入缓冲区机制,键盘输入的数据会先缓存,按下回车之后输入函数才从缓冲区取出字符,缓冲区残留换行符是初学者最容易踩坑的点,会造成后续输入直接读到空内容。