C语言两个逐字符读取字符串函数的差异及异常行为解析
两个C语言行读取函数的差异分析
核心差异
read_line:遇到换行符'\n'时,会读完并丢弃该行剩余所有字符,彻底清空输入缓冲区中当前行的残留内容。read_lineD_Solution:遇到换行符'\n'时仅停止向数组存字符,或读取满n个字符就停止,未读取的输入内容会留在缓冲区中,下次调用函数时直接读取这些残留字符,无需用户重新输入。
函数执行逻辑拆解
1. read_line(while循环实现)
int read_line(char str[], int n) { int ch, i=0; while ((ch=getchar()) != '\n') if (i < n) str[i++] = ch; str[i] = '\0'; return i; }
- 循环会持续调用
getchar()读取字符,直到碰到换行符才停止:- 当读取的字符数未达到
n时,将字符存入数组; - 一旦字符数达到
n,后续字符不再存入数组,但依然会被getchar()读取(即从缓冲区移除),直到遇到换行符。
- 当读取的字符数未达到
- 最终效果:当前行的所有字符(包括超出
n的部分和换行符)都会被处理完毕,输入缓冲区中当前行无残留。
2. read_lineD_Solution(for循环实现)
int read_lineD_Solution(char str[], int n) { int ch, i; for (i=0;i<n; i++) { ch = getchar(); if (ch == '\n') break; str[i] = ch; } str[i] = '\0'; return i; }
- 循环最多执行
n次,每次先读取一个字符:- 如果读到换行符,立即跳出循环,停止读取;
- 如果未读到换行符,就将字符存入数组,直到读满
n个字符。
- 最终效果:如果输入字符数超过
n,未被读取的部分会留在缓冲区;如果中途遇到换行符,换行符后的输入内容也会留在缓冲区。
意外行为的根源
C语言的输入缓冲区是一个全局字符队列,getchar()每次从队列头部取出一个字符:
read_line的while循环会彻底"消费"当前行的所有字符(直到换行符),缓冲区不会残留当前行的任何内容;read_lineD_Solution的for循环仅"消费"最多n个字符,中途碰到换行符也会提前停止,未被消费的字符会留在队列中,下次调用函数时直接读取这些残留内容,因此不需要用户重新输入。
测试代码
#include <stdio.h> #include <ctype.h> int read_lineD_Solution(char str[], int n); int read_line(char str[], int n); int main(void) { char a[100] ; printf("Enter a sentece: "); read_lineD_Solution(a, 3); printf("%s\n", a); printf("Enter a sentece: "); read_lineD_Solution(a, 3); printf("%s\n", a); return 0; } int read_line(char str[], int n) { int ch, i=0; while ((ch=getchar()) != '\n') if (i < n) str[i++] = ch; str[i] = '\0'; return i; } int read_lineD_Solution(char str[], int n) { int ch, i; for (i=0;i<n; i++) { ch = getchar(); if (ch == '\n') break; str[i] = ch; } str[i] = '\0'; return i; }
内容的提问来源于stack exchange,提问作者Pepe Cuesta
相关产品推荐
相关产品推荐

