C语言两次调用getChar函数出现Segmentation Fault问题求助
段错误原因及修复方案
问题根源
段错误的核心原因是strtok函数的特性导致的:
- 修改原字符串:
strtok会将分割位置的字符替换为'\0',第一次调用getChar后,输入字符串已被修改为"11111\0&\011111"的形式。 - 全局状态留存:
strtok内部维护着上次分割的全局状态,第二次调用getChar时,执行strtok(a, " ")会重新从字符串开头分割,拿到第一个token("11111"),接着调用strtok(NULL, " ")时,已无有效后续token,p被赋值为NULL,此时访问p[0]属于空指针引用,直接触发段错误。
修复方案
方案1:复制临时字符串处理,避免修改原字符串
修改getChar函数,每次处理前复制原字符串到临时缓冲区,避免修改原字符串,同时防止strtok的全局状态干扰:
#include <stdio.h> #include <string.h> #include <stdlib.h> char getChar(char *a){ // 复制原字符串到临时内存 char *temp = strdup(a); if (temp == NULL) { fprintf(stderr, "内存分配失败\n"); exit(EXIT_FAILURE); } char *p = strtok(temp," "); if (p != NULL) { p = strtok(NULL," "); } // 先判断p是否为空,避免空指针访问 char result = (p != NULL) ? p[0] : '\0'; free(temp); // 释放临时内存 return result; }
同时修正main函数中getline的返回值类型(应为ssize_t),并增加输入失败的判断:
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <string.h> char getChar(char *a); int main(){ char *str = NULL; size_t n = 0; ssize_t read_len = getline(&str,&n,stdin); if (read_len == -1) { fprintf(stderr, "读取输入失败\n"); return EXIT_FAILURE; } printf("%c\n", getChar(str)); char operation = getChar(str); printf("存储的操作符:%c\n", operation); free(str); return 0; }
方案2:一次性提取操作符,避免重复调用
如果只需要获取一次中间操作符,直接调用一次getChar并保存结果即可,无需重复调用:
int main(){ char *str = NULL; size_t n = 0; ssize_t read_len = getline(&str,&n,stdin); if (read_len == -1) { fprintf(stderr, "读取输入失败\n"); return EXIT_FAILURE; } char operation = getChar(str); printf("%c\n", operation); // 后续直接使用operation变量 printf("存储的操作符:%c\n", operation); free(str); return 0; }
方案3:使用线程安全的strtok_r
strtok_r是strtok的线程安全版本,需要手动维护分割状态,不会留存全局状态,但仍会修改原字符串,需配合临时字符串使用:
#include <stdio.h> #include <string.h> #include <stdlib.h> char getChar(char *a){ char *temp = strdup(a); if (temp == NULL) { fprintf(stderr, "内存分配失败\n"); exit(EXIT_FAILURE); } char *saveptr; char *p = strtok_r(temp," ", &saveptr); if (p != NULL) { p = strtok_r(NULL," ", &saveptr); } char result = (p != NULL) ? p[0] : '\0'; free(temp); return result; }
内容的提问来源于stack exchange,提问作者игорь кочнов
相关产品推荐
相关产品推荐

