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

C语言单词计数程序utest5.2.1测试输出格式不符问题求助

C语言单词计数程序测试失败排查

问题概述

实现了一款C语言单词计数程序,功能为读取用户输入文本、转为小写后统计各单词出现次数。执行用户测试utest5.2.1时失败:

  • 测试输入:Hello world Hello\n\n\n
  • 预期输出:单行格式word counts: hello: 2 world: 1\n
  • 实际输出:分为多行,首行包含enter a line of text: word counts:,第2行输出hello: 2,第3行输出world: 1,未匹配预期格式。系统测试已通过,但该用户测试失败导致无法获取flag。

程序代码(main.c)

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

#define MAX_WORDS 100
#define MAX_WORD_LEN 50

// Helper function to convert a string to lowercase
void to_lowercase(char *str) {
    for (int i = 0; str[i]; i++) {
        str[i] = tolower(str[i]);
    }
}

// Check if word already exists in the list
int find_word(char words[][MAX_WORD_LEN], int word_count, char *word) {
    for (int i = 0; i < word_count; i++) {
        if (strcmp(words[i], word) == 0) {
            return i; // return the index of the word if found
        }
    }
    return -1; // return -1 if not found
}

int main() {
    char input[1000];
    char words[MAX_WORDS][MAX_WORD_LEN];
    int counts[MAX_WORDS] = {0};
    int word_count = 0;

    // Prompt the user for input
    printf("Enter a line of text: ");
    fgets(input, sizeof(input), stdin);

    // Remove the newline character at the end of the input if it exists
    size_t len = strlen(input);
    if (len > 0 && input[len - 1] == '\n') {
        input[len - 1] = '\0';
    }

    // Tokenize the input by spaces
    char *token = strtok(input, " ");
    while (token != NULL) {
        to_lowercase(token); // convert token to lowercase

        int index = find_word(words, word_count, token);

        if (index == -1) {
            // New word, add it to the list
            strcpy(words[word_count], token);
            counts[word_count]++;
            word_count++;
        } else {
            // Existing word, increment its count
            counts[index]++;
        }

        token = strtok(NULL, " ");
    }

    // Output the word counts
    printf("word counts:");
    for (int i = 0; i < word_count; i++) {
        printf(" %s: %d", words[i], counts[i]);
        if (i < word_count - 1) {
            printf(" "); // Space between words
        }
    }
    printf("\n");

    return 0;
}

测试失败详情

---------------[  用户测试  ]---------------
User utest5.2.1: ✔ PASS  - Basic word counting test with special input ran in 0.01s
User utest5.2.1: FAIL  - Basic word counting test with special input 
        测试描述        : 测试含特殊输入'Hello world Hello\n\n'及大小写不敏感的单词计数
        命令          : /challenge/modelGood.bin 
        程序输入    : 'Hello world Hello\n\n\n'
        预期输出  : ['word counts: hello: 2 world: 1\n']
        测试耗时      : 0.01s
        未在输出中找到   : word counts: hello: 2 world: 1
        最接近匹配行是第2行 : hello: 2
--------<[ utest5.2.1   (标记的/tmp/test_output/utest5.2.1_actual_normalized.output输出) ]>--------
1  enter a line of text: word counts:
2  hello: 2
         ↑↑↑↑↑
3  world: 1
↑ EOF ↑

User utest5.2.1: ✔ PASS  - Basic word counting test with special input ran in 0.01s

---------------[ 系统测试 ]---------------
System stest5.2.1: ✔ PASS  - 上述输入的计数测试耗时0.01s
System stest5.2.2: ✔ PASS  - 预期计数的测试输入耗时0.01s

总结: 4项测试通过, 1项测试失败
失败次数过多无法获取flag

问题原因及修复方案

核心问题

  1. 交互提示干扰输出格式:程序开头的printf("Enter a line of text: ");会将提示信息与统计输出拼接在同一行,破坏了测试预期的纯统计输出格式。
  2. 分割符未覆盖换行符:strtok仅用空格作为分割符,输入中的\n会被误识别为有效单词,导致输出时插入换行,将统计结果拆分为多行。

修复后的代码

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

#define MAX_WORDS 100
#define MAX_WORD_LEN 50

// Helper function to convert a string to lowercase
void to_lowercase(char *str) {
    for (int i = 0; str[i]; i++) {
        str[i] = tolower(str[i]);
    }
}

// Check if word already exists in the list
int find_word(char words[][MAX_WORD_LEN], int word_count, char *word) {
    for (int i = 0; i < word_count; i++) {
        if (strcmp(words[i], word) == 0) {
            return i; // return the index of the word if found
        }
    }
    return -1; // return -1 if not found
}

int main() {
    char input[1000];
    char words[MAX_WORDS][MAX_WORD_LEN];
    int counts[MAX_WORDS] = {0};
    int word_count = 0;

    // 移除交互提示,适配自动测试输入
    fgets(input, sizeof(input), stdin);

    // Remove the newline character at the end of the input if it exists
    size_t len = strlen(input);
    if (len > 0 && input[len - 1] == '\n') {
        input[len - 1] = '\0';
    }

    // Tokenize the input by spaces, newlines and tabs
    char *token = strtok(input, " \n\t");
    while (token != NULL) {
        to_lowercase(token); // convert token to lowercase

        int index = find_word(words, word_count, token);

        if (index == -1) {
            // New word, add it to the list
            strcpy(words[word_count], token);
            counts[word_count]++;
            word_count++;
        } else {
            // Existing word, increment its count
            counts[index]++;
        }

        token = strtok(NULL, " \n\t");
    }

    // Output the word counts
    printf("word counts:");
    for (int i = 0; i < word_count; i++) {
        printf(" %s: %d", words[i], counts[i]);
        if (i < word_count - 1) {
            printf(" "); // Space between words
        }
    }
    printf("\n");

    return 0;
}

修复说明

  • 移除了输入提示语句,避免干扰测试输出的纯净格式。
  • 修改strtok的分割符为" \n\t",覆盖所有空白字符(空格、换行、制表符),确保输入中的换行符被当作分隔符而非有效单词,避免输出时产生不必要的换行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:44:53