计算字符串最后一个单词长度时出现Seg Fault段错误求排查方案
字符串最后一个单词长度计算代码的段错误问题与优化方案
段错误核心原因
你的代码出现段错误主要源于未初始化变量导致的内存越界访问,同时存在逻辑漏洞无法处理标点结尾、换行符等场景,具体问题与优化如下:
1. 未初始化变量引发越界
lastWordLength函数中的i和x未初始化,初始值为内存随机垃圾值。第一次循环时strlen(word)-i会生成超出字符串范围的索引,直接触发段错误。
修复:
给变量设置合理起始值:
int i = 1; int x = 0;
2. 循环条件未覆盖边界场景
原代码仅判断空格,当输入以标点(如!、.)结尾或无空格时,循环会持续找不到空格,不断越界访问内存,引发段错误。
优化:
先跳过末尾的非单词字符(标点、空格等),再统计单词长度,避免无意义的越界循环。
3. 未处理fgets读入的换行符
fgets会将输入的换行符\n写入字符串,这会被当成最后一个字符干扰计算,且输出时会出现多余换行。
修复:
在调用lastWordLength前执行chomp(firstSen);,清理换行符。
4. clearBuffer函数逻辑错误
如果fgets已读取完整行(包含换行),clearBuffer会阻塞等待用户输入;若输入超长,它能清理剩余字符,但缺少对EOF的判断。
修复:
修改函数,仅清理未读完的缓冲区内容:
void clearBuffer() { int c; while ((c = getchar()) != '\n' && c != EOF); }
5. 优化lastWordLength的效率与鲁棒性
原代码每次循环调用strlen(需遍历整个字符串),效率低下;同时无法识别标点结尾的单词。优化后逻辑:
- 先获取字符串总长度,避免重复计算
- 跳过末尾的非单词字符(标点、空格)
- 反向统计连续的字母字符长度
优化后的lastWordLength:
int lastWordLength(char word[]) { int len = strlen(word); int count = 0; // 跳过末尾非单词字符 while (len > 0 && !((word[len-1] >= 'a' && word[len-1] <= 'z') || (word[len-1] >= 'A' && word[len-1] <= 'Z'))) { len--; } // 统计单词长度 while (len > 0 && ((word[len-1] >= 'a' && word[len-1] <= 'z') || (word[len-1] >= 'A' && word[len-1] <= 'Z'))) { count++; len--; } return count; }
完整修复代码
#include<stdio.h> #include<string.h> void clearBuffer(); void chomp(char word[]); int lastWordLength(char word[]); int main(){ int x; char firstSen[500]; printf("Enter a sentence: "); fgets(firstSen, sizeof(firstSen), stdin); chomp(firstSen); clearBuffer(); x = lastWordLength(firstSen); printf("Length of last word in \"%s\" is %d.\n", firstSen, x); return 0; } void clearBuffer() { int c; while ((c = getchar()) != '\n' && c != EOF); } void chomp(char word[]) { size_t len = strlen(word); if(len > 0 && word[len-1] == '\n') { word[len-1] = '\0'; } } int lastWordLength(char word[]) { int len = strlen(word); int count = 0; while (len > 0 && !((word[len-1] >= 'a' && word[len-1] <= 'z') || (word[len-1] >= 'A' && word[len-1] <= 'Z'))) { len--; } while (len > 0 && ((word[len-1] >= 'a' && word[len-1] <= 'z') || (word[len-1] >= 'A' && word[len-1] <= 'Z'))) { count++; len--; } return count; }
内容的提问来源于stack exchange,提问作者PapaPumpkin
相关产品推荐
相关产品推荐

