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

C语言使用fgets和strtok()读取stdin文本仅运行几行就终止的问题求解

问题原因与修复方案

核心问题梳理

  • 内存申请逻辑错误:malloc(sizeof(WORD_BUFFER_SIZE)*TEXT_SIZE)写法错误,WORD_BUFFER_SIZE是整型常量,sizeof(WORD_BUFFER_SIZE)实际得到的是整型的字节数(通常为4),而非预期的50字节,导致申请的内存远小于实际需要,写入越界触发程序崩溃。
  • text内存未初始化:strcat要求目标字符串必须以\0结尾,malloc申请的内存是未初始化的随机值,无法确定\0位置,直接调用strcat会发生非法内存访问。
  • 输入缓冲区残留换行符:前面scanf("%s", word)读取到====后,输入流中还残留了换行符,会被后续fgets当做第一行内容读取。
  • strtok分隔符设置不全:仅设置空格为分隔符,没有包含fgets读取的每行末尾自带的换行符,会导致单词粘连换行符,也可能出现拆分异常。
  • 缺少边界校验:停用词数组、输入缓冲区都没有做写入边界判断,极端输入下容易触发溢出。

修正后代码

#define WORD_BUFFER_SIZE 50
#define TEXT_SIZE 200
// 计算实际需要的文本缓冲区大小
#define TEXT_BUFFER_SIZE (WORD_BUFFER_SIZE * TEXT_SIZE)

int main(void) {
    char stopWords[TEXT_SIZE][WORD_BUFFER_SIZE];
    char word[WORD_BUFFER_SIZE];
    int numberOfWords = 0;
  
    while(scanf("%s", word) == 1){
      // 停用词数量边界校验
      if (numberOfWords >= TEXT_SIZE) {
          break;
      }
      if (strcmp(word, "====") == 0){
        break;
      }
      // 单词长度校验,避免溢出
      if (strlen(word) < WORD_BUFFER_SIZE) {
          strcpy(stopWords[numberOfWords], word);
          numberOfWords++;
      }
    }
    // 消耗掉scanf残留的换行符
    while(getchar() != '\n');

    char *buffer = malloc(TEXT_BUFFER_SIZE);
    char *text = malloc(TEXT_BUFFER_SIZE);
    // 内存分配失败判断 + text初始化
    if (!buffer || !text) {
        perror("内存分配失败");
        return 1;
    }
    text[0] = '\0'; // 初始化text为空白字符串,保证strcat正常工作
  
    while(fgets(buffer, TEXT_BUFFER_SIZE, stdin) != NULL){  
      // 避免text缓冲区溢出
      if (strlen(text) + strlen(buffer) >= TEXT_BUFFER_SIZE) {
          break;
      }
      strcat(text, buffer);
    }
  
    char *k;
    // 分隔符增加换行、制表符等常见空白符
    k = strtok(text, " \n\t\r");
    while (k != NULL) {
      printf("%s\n", k);
      k = strtok(NULL, " \n\t\r");
    }
    
    // 释放申请的内存
    free(buffer);
    free(text);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:15:00