如何处理可变参数函数?修正C语言重复字母单词输出代码问题
问题与修正方案
需求:实现一个**不使用
原代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdarg.h> #include <ctype.h> int count_char(char* str, char c) { int count = 0; c = 'o'; for (int i = 0; i < strlen(str); i++) { if (str[i] == c) { count++; } } return count; } void print_words(unsigned k, char* str, ...) { char* word; char* p; int i; const char* delim = " ,.;:!?\t\n\r\f\v"; for (i = 0, p = str; i < k; p++) { word = strtok(p, delim); while (word != NULL) { for (int i = 0; i < strlen(word); i++) { int char_count = count_char(word, word[i]); if (char_count >= 3) { printf("Words with repeated letter: %s\n", word); break; } } word = strtok(NULL, " "); } } } int main() { char str1[] = "This is a sampooole sentenceoooo."; char str2[] = "Another sentence, with more woooords."; print_words(2, str1, str2); return 0; }
原错误输出
Words with repeated letter: sampooole Words with repeated letter: sentenceoooo. Words with repeated letter: sampooole Words with repeated letter: ampooole Words with repeated letter: mpooole Words with repeated letter: pooole Words with repeated letter: ooole Words with repeated letter: sentenceoooo Words with repeated letter: entenceoooo Words with repeated letter: ntenceoooo Words with repeated letter: tenceoooo Words with repeated letter: enceoooo Words with repeated letter: nceoooo Words with repeated letter: ceoooo Words with repeated letter: eoooo Words with repeated letter: oooo Words with repeated letter: ooo Words with repeated letter: woooords. Words with repeated letter: woooords Words with repeated letter: oooords Words with repeated letter: ooords
问题分析
- 可变参数处理完全错误:
print_words里的循环for (i = 0, p = str; i < k; p++)是在遍历字符串的每个字符,而非传入的多个字符串,导致同一个字符串被反复分割,产生大量重复输出,同时还违规使用了<stdarg>,不符合需求。 - count_char功能受限:硬编码
c = 'o',只能统计字母o的出现次数,无法检查其他字母的重复情况。 - strtok使用错误:后续调用
strtok(NULL, " ")时改用单一空格作为分隔符,和初始的多分隔符不一致,导致带标点的单词被错误拆分。 - 单词重复检查冗余:对同一个单词的每个字符都调用count_char,虽有break,但核心循环逻辑错误导致问题扩大。
修正方案
- 去掉
<stdarg>,改用字符串数组作为参数传递多个字符串。 - 修复
count_char函数,使用传入的参数c进行统计。 - 新增
has_repeated_char函数,判断单词是否存在任意字母重复≥3次,避免冗余检查。 - 正确使用strtok:保持分隔符一致,且每个字符串处理前重新初始化strtok,同时复制原字符串避免被修改。
- 遍历每个字符串,逐个分割单词,符合条件的只输出一次。
修正后的代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <ctype.h> // 统计指定字符在字符串中的出现次数 int count_char(const char* str, char c) { int count = 0; c = tolower(c); // 忽略大小写,不需要可删除 while (*str != '\0') { if (tolower(*str) == c) { count++; } str++; } return count; } // 判断单词是否存在任意字母重复三次及以上 int has_repeated_char(const char* word) { const char* p = word; while (*p != '\0') { // 跳过非字母字符,不需要可删除 if (!isalpha(*p)) { p++; continue; } if (count_char(word, *p) >= 3) { return 1; } p++; } return 0; } // 接收字符串数组和数组长度,处理多个字符串 void print_words(char* strs[], int str_count) { const char* delim = " ,.;:!?\t\n\r\f\v"; for (int i = 0; i < str_count; i++) { // 复制原字符串避免被strtok修改 char str_copy[strlen(strs[i]) + 1]; strcpy(str_copy, strs[i]); char* word = strtok(str_copy, delim); while (word != NULL) { if (has_repeated_char(word)) { printf("含重复字母的单词:%s\n", word); } word = strtok(NULL, delim); } } } int main() { char str1[] = "This is a sampooole sentenceoooo."; char str2[] = "Another sentence, with more woooords."; // 将字符串放入数组中传递 char* strs[] = {str1, str2}; print_words(strs, 2); return 0; }
修正后输出
含重复字母的单词:sampooole 含重复字母的单词:sentenceoooo 含重复字母的单词:woooords
内容的提问来源于stack exchange,提问作者mary
相关产品推荐
相关产品推荐

