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

C语言向文件打印字符串异常:首行无内容输入问题求助

问题分析与解决:C语言写入TXT文件时输入次数不符、首行空内容

问题根源

scanf("%d", &columns) 读取整数后,用户输入的换行符(\n)会残留在标准输入缓冲区中。第一次调用fgets时,会直接读取这个残留的换行符,导致temp_text中只有\n;后续你用temp_text[strlen(temp_text)-1] = '\0'把换行符替换成空字符,最终temp_text变成空字符串,这就是首行无内容的原因。同时,这次“无效”的读取占用了一次循环次数,所以实际只需要输入4次内容。

另外还有潜在问题:如果fgets读取到空行(用户直接按回车),strlen(temp_text)为1(仅含\n),strlen(temp_text)-1为0没问题,但如果fgets因出错或到达文件末尾返回NULL,调用strlen会触发未定义行为,需要增加判断。

解决方案

方法1:清除scanf残留的换行符

在scanf之后,用循环清空缓冲区直到遇到换行,避免残留字符影响后续fgets:

scanf("%d", &columns);
// 清空缓冲区直到读取到换行符
while(getchar() != '\n');

方法2:用fgets读取整行再转整数(更健壮)

完全避免scanf的缓冲区残留问题,直接用fgets读取输入整行,再通过sscanf转换成整数:

char input_buf[20];
fgets(input_buf, sizeof(input_buf), stdin);
sscanf(input_buf, "%d", &columns);

修正后的完整代码

采用方法1的循环清缓冲区方案,同时增加文件打开、fgets读取的错误判断:

#include <stdio.h>
#include <string.h>

int main() {
    FILE * fptr;

    // 打开文件,增加失败判断
    fptr = fopen("test.txt", "a");
    if(fptr == NULL){
        perror("Failed to open file");
        return 1;
    }

    // 输入行数
    int columns;
    scanf("%d", &columns);
    // 清空输入缓冲区
    while(getchar() != '\n');

    // 循环写入内容
    for (int i = 0; i < columns; i++) {
        char temp_text[10001];
        // 判断fgets读取是否成功
        if(fgets (temp_text, 10000, stdin) == NULL){
            break;
        }

        // 移除fgets读取到的换行符,增加边界判断
        size_t len = strlen(temp_text);
        if(len > 0 && temp_text[len-1] == '\n'){
            temp_text[len-1] = '\0';
        }

        fprintf (fptr, "data %d: %s\n", i, temp_text);
    }

    fclose (fptr);
    return 0;
}

测试验证

输入:

5
qw
er
ty
ui
op

生成的test.txt内容:

data 0: qw
data 1: er
data 2: ty
data 3: ui
data 4: op

此时程序会要求输入5次内容,首行也能正常写入指定字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:25:17