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
问题原因及修复方案
核心问题
- 交互提示干扰输出格式:程序开头的
printf("Enter a line of text: ");会将提示信息与统计输出拼接在同一行,破坏了测试预期的纯统计输出格式。 - 分割符未覆盖换行符:
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
相关产品推荐
相关产品推荐

