终端行读写异常:输入需按两次回车且换行符被存入字符串
问题与解决方案
问题描述
编写函数用getchar()从终端读取输入并存储到字符串,要求:
- 读取内容以空字符
'\0'结尾 - 换行符不得存入字符串
当前问题:输入字符数小于指定长度时,需按两次回车才能继续,且换行符被存入字符串。
原代码问题分析
- readLine开头的无效循环:函数开头遍历数组替换
'\n'为'\0',但此时数组未被赋值,存储的是随机值,该操作完全无意义。 - 换行符被存入数组:do-while循环先将读取的字符写入数组,再判断是否为换行符。当读到换行符时,已经将其写入数组,后续仅在数组末尾加
'\0',导致换行符残留。 - 重复清空缓冲区:main函数中在
readLine后和print后各调用一次flushBuffer(),若readLine已处理完换行符,第二次flushBuffer()会等待用户再次输入回车,导致需要按两次回车。
修正后的代码
#include <stdio.h> #include <ctype.h> #include <string.h> #define LENGTH 4 // 测试用短长度 void flushBuffer(void) { int ch; // 处理EOF情况,避免死循环 while ((ch = getchar()) != '\n' && ch != EOF); } void readLine(char str[], int length) { int i = 0; int ch; // 读取字符,直到换行、EOF或达到长度上限 while (i < length - 1) { ch = getchar(); // 遇到换行或EOF,停止读取 if (ch == '\n' || ch == EOF) { break; } str[i++] = ch; } // 添加字符串结束符 str[i] = '\0'; // 如果输入超过长度上限,清空缓冲区剩余字符 if (ch != '\n' && ch != EOF) { flushBuffer(); } } void printArray(char a[], int length) { printf("["); for (int i = 0; i < length; i++) { if (a[i] == '\n') { printf("\\n"); } else if (a[i] == '\0') { printf("\\0"); } else { printf("%c", a[i]); } if (i != length - 1) { printf(","); } } printf("]\n"); } void printChar(char c) { putchar(c); fflush(NULL); } void printString(char s[]) { int currentChar = 0; printf("\""); // 修正循环条件,避免输出'\0' while (s[currentChar] != '\0') { printChar(s[currentChar]); currentChar++; } printf("\"\n"); } int main(void) { char inputString[LENGTH]; do { printf("String? "); readLine(inputString, LENGTH); printArray(inputString, LENGTH); printString(inputString); } while (1); }
关键修改说明
- readLine函数重构:
- 先将读取的字符存入临时变量
ch,确认不是换行/EOF后再写入数组,彻底避免换行符被存入。 - 读取结束后统一添加
'\0',确保字符串正确终止。 - 仅当输入字符数超过长度上限时,才调用
flushBuffer()清空剩余输入,避免不必要的回车等待。
- 先将读取的字符存入临时变量
- flushBuffer函数优化:添加EOF判断,防止输入结束时进入死循环。
- printString函数修正:将do-while改为while循环,避免输出字符串结束符
'\0'。 - 移除main中多余的flushBuffer调用:仅在readLine内部按需清空缓冲区,消除重复等待回车的问题。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

