我有这段代码:
#include <ctype.h>
char *tokenHolder[2500];
for(i = 0; tokenHolder[i] != NULL; ++i){
if(isdigit(tokenHolder[i])){ printf("worked"); }
其中tokenHolder保存来自用户输入的char标记的输入,这些标记已通过getline和strtok标记化。尝试在tokenHolder上使用isdigit时出现seg错误 - 我不知道为什么。
答案 0 :(得分:3)
由于tokenHolder
是char *
的数组,因此当您为tokenHolder[i]
编制索引时,您将char *
传递给isdigit()
,isdigit()
不接受指针。
您可能错过了第二个循环,或者您需要:
if (isdigit(tokenHolder[i][0]))
printf("working\n");
不要忘记换行符。
你在循环中的测试也很奇怪;您通常将“空指针”拼写为0
或NULL
而不是'\0'
;这只会误导人们。
另外,您需要注意所获得的编译器警告!不要发布编译有警告的代码,或者(至少)指定警告的内容,以便人们可以看到编译器告诉你的内容。您应该将编译器设置为繁琐而针对零警告。
如果您尝试测试令牌数组中的值都是数字,那么您需要一个test_integer()
函数尝试将字符串转换为数字并让您知道转换是否不使用全部字符串中的数据(或者您可能允许前导和尾随空白)。您的问题规范并不清楚您尝试使用strtok()
等找到的字符串令牌。
至于你获得核心转储的原因:
isdigit()宏的代码通常大致是
#define isdigit(x) (_Ctype[(x)+1]&_DIGIT)
当您提供指针时,它被视为(通常)257值的数组的非常大(正或可能为负)偏移,并且因为您正在访问超出范围的内存,所以会出现分段错误。当EOF
为isdigit()
时,+1允许EOF
传递给-1
,这是通常的值,但不是强制性的。像isdigit()
这样的宏/函数将字符作为unsigned char
- 通常在0..255范围内,因此 - 或EOF作为有效输入。
答案 1 :(得分:2)
您正在声明一个指向char 的指针数组,而不仅仅是 char 的简单数组。您还需要初始化数组或稍后为其分配一些值。如果您读取了尚未初始化或分配给的数组成员的值,则表示您正在调用未定义的行为。
char tokenHolder[2500] = {0};
for(int i = 0; tokenHolder[i] != '\0'; ++i){
if(isdigit(tokenHolder[i])){ printf("worked"); }
另外,您可能会忽略编译器警告,告诉您代码可能不正确。 isdigit
需要int
,而char *
与int
不兼容,因此您的编译器应该为此生成警告。
答案 2 :(得分:0)
您需要/想要将输入转换为unsigned char
,然后再将其传递给isdigit
。
if(isdigit((unsigned char)tokenHolder[i])){ printf("worked"); }
在大多数典型的编码方案中,USASCII范围之外的字符(例如,带有变音符号,重音符号,坟墓等的任何字母)将在char
已签名的典型情况下显示为负数。< / p>
至于如何导致段错误:isdigit
(以及islower
,isupper
等)通常使用位域表来实现,当您调用时函数传递的值用作表的索引。负数最终会尝试在表格之外(好)进行索引。
虽然我最初没有注意到它,但您也遇到了问题,因为tokenHolder
(可能)不是您预期/计划使用的类型。从其余代码的外观来看,您确实希望将其定义为:
char tokenHolder[2500];