C语言无指针实现字符串单词提取至一维数组及代码修改建议
原代码存在的具体问题
- 字符串操作缺必备结束符:C语言中所有按字符串处理的数组(不管是
puts输出还是传给回文判断函数),必须在有效字符末尾加\0,否则会读取内存随机乱码。你当前往word里填完字符就直接输出,完全没有加结束符,这是输出异常的核心原因。 - 单词起始位置变量未更新:你定义了记录单词起始下标的
p,但每次触发单词提取逻辑后,没有把p更新为当前空格位置的下一位,导致每次提取的内容都从字符串开头开始计算,没法正确切分后续单词。 - 变量作用域重复定义:你在外层定义了计数变量
a,又在内层循环重新声明int a=0,把外层变量完全覆盖,计数逻辑混乱。 - 循环逻辑覆盖不全:你循环到
i < strlen(str)就停止,而strlen返回的长度本身不包含末尾\0的位置,导致字符串最后面的单词永远触发不到提取逻辑。 - 废弃函数替换:
gets()没有边界检查,存在缓冲区溢出风险,直接用更安全的fgets()读入即可,不需要复杂语法。
修改后的可运行代码(无指针操作、完全匹配你原有的代码逻辑)
#include <stdio.h> #include <string.h> // 适配你需求的回文判断实现,全程用数组下标,无复杂语法 void palindrome(int len, char word[]) { int left = 0, right = len - 1; int is_palindrome = 1; while(left < right) { if(word[left] != word[right]) { is_palindrome = 0; break; } left++; right--; } if(is_palindrome) { printf("「%s」是回文单词\n", word); } else { printf("「%s」不是回文单词\n", word); } } int main() { char str[100]; int a = 0, l, p = 0; printf("Enter the text \n"); // 替换废弃的gets,直接读入整行文本 fgets(str, sizeof(str), stdin); // 去掉fgets读入时附带的末尾换行符,不影响核心逻辑 str[strcspn(str, "\n")] = '\0'; l = strlen(str); // 循环到i <= l,保证位于字符串末尾的最后一个单词能被触发提取 for(int i = 0; i <= l; i++) { // 遇到空格或者字符串结束符,触发单词提取流程 if(str[i] == ' ' || str[i] == '\0') { char word[100]; a = 0; // 从上次记录的单词起始位置p,提取到当前空格/结束符的位置i for(int j = p; j < i; j++) { word[a] = str[j]; a++; } // 必须给word加字符串结束符,否则是无效C字符串 word[a] = '\0'; // 跳过连续空格导致的空单词,避免运行异常 if(a > 0) { printf("提取到的单词:"); puts(word); palindrome(a, word); } // 更新下一个单词的起始位置,直接跳到当前空格的下一位 p = i + 1; } } return 0; }
关键修改点说明
- 每次填完
word的字符后,立即在数组末尾写入\0,让数组成为合规的C语言字符串 - 触发提取后,立刻把
p更新为i+1,跳过当前空格的位置,从空格后开始记录下一个单词 - 把循环终止条件从
i < l改成i <= l,保证当i走到字符串末尾的\0位置时,能正确触发最后一个单词的提取 - 去掉内层重复定义的
a,每次提取时统一重置计数变量,避免作用域混乱 - 加了空单词判断,避免输入连续多个空格时提取到空字符串导致的异常
- 全程没有用指针运算、动态内存分配等复杂语法,所有逻辑都是你原本计划的数组操作
内容的提问来源于stack exchange,提问作者Anushka
相关产品推荐
相关产品推荐

