You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

终端行读写异常:输入需按两次回车且换行符被存入字符串

问题与解决方案

问题描述

编写函数用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);
}

关键修改说明

  1. readLine函数重构:
    • 先将读取的字符存入临时变量ch,确认不是换行/EOF后再写入数组,彻底避免换行符被存入。
    • 读取结束后统一添加'\0',确保字符串正确终止。
    • 仅当输入字符数超过长度上限时,才调用flushBuffer()清空剩余输入,避免不必要的回车等待。
  2. flushBuffer函数优化:添加EOF判断,防止输入结束时进入死循环。
  3. printString函数修正:将do-while改为while循环,避免输出字符串结束符'\0'。
  4. 移除main中多余的flushBuffer调用:仅在readLine内部按需清空缓冲区,消除重复等待回车的问题。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:45:54