存储句子单词指针遇异常:加'\0'提前结束,不加则多存单词
问题分析与解决方案
看起来你在实现用指针数组存储句子中每个单词的起始地址时遇到了两难困境:手动插入'\0'拆分单词会导致程序提前终止,不加的话又会多存无效内容。咱们一步步拆解问题根源,再给出可行的修复方案。
核心问题拆解
strlen()动态计算导致循环提前结束
你在循环条件里直接用了i < strlen(sentence),但strlen()的工作逻辑是从字符串起始地址开始,找到第一个'\0'就停止计算长度。如果你中途把句子里的空格改成'\0',strlen()的结果会立刻缩小,循环也就提前终止了,后面的单词根本没机会被处理。未妥善处理字符串边界与无效内容
要是不手动加'\0',如果原字符串本身没有正确以'\0'结尾(或者内存后续有非空格的垃圾数据),strlen()会读取超出有效内容的区域,导致循环多处理了一堆无效的"伪单词";另外如果句子末尾没有空格,你的逻辑其实已经记录了最后一个单词的起始,但字符串不规范的话也会触发异常。
修复后的代码示例
针对这些问题,调整几个关键逻辑就能解决:
#include <stdio.h> #include <string.h> #define MAX_WORDS 100 // 根据实际需求调整最大单词数 int main() { char sentence[] = "Hello world this is a test"; char* wordList[MAX_WORDS]; int wordIndex = 0; int prevIsSpace = 1; // 初始标记为"前一个是空格",确保第一个单词能被捕获 int strLength = strlen(sentence); // 提前存储字符串长度,避免循环中动态变化的影响 for(int i = 0; i < strLength; i++){ // 遇到非空格且前一个是空格时,记录单词起始地址 if(sentence[i] != ' ' && prevIsSpace == 1){ prevIsSpace = 0; wordList[wordIndex] = &sentence[i]; printf("wordList[%d] now points to %c\n", wordIndex, sentence[i]); wordIndex++; } // 遇到空格且当前处于单词中时,将空格改为'\0'拆分单词 if(sentence[i] == ' ' && prevIsSpace == 0){ prevIsSpace = 1; sentence[i] = '\0'; // 用'\0'替换空格,让每个单词成为独立字符串 } } // 测试输出拆分后的单词 printf("\n拆分后的结果:\n"); for(int k = 0; k < wordIndex; k++){ printf("Word %d: %s\n", k, wordList[k]); } return 0; }
关键调整说明
- 提前存储字符串长度:把
strlen(sentence)的结果存在strLength变量里,循环时用i < strLength作为条件。这样即使中途修改字符串里的字符为'\0',循环也会完整遍历原字符串的所有字符,不会提前终止。 - 精准替换空格为
'\0':只在遇到空格且当前处于单词中间时(prevIsSpace == 0)才替换,既完成了单词拆分,又不会干扰循环的遍历范围。 - 确保输入字符串规范:一定要保证传入的
sentence是标准的C字符串(以'\0'结尾),否则strlen()会读取内存垃圾数据,导致逻辑混乱。
如果你的需求是不能修改原字符串,那可以改用malloc为每个单词分配独立内存,再用strncpy复制单词内容,不过逻辑会稍微复杂一些。
内容的提问来源于stack exchange,提问作者S Jiles
相关产品推荐
相关产品推荐

