C isdigit()分段错误

C isdigit()分段错误,c,arguments,segmentation-fault,C,Arguments,Segmentation Fault,当我试图通过命令行将数字传递到我的应用程序中时,下面的代码出现了奇怪的分段错误 int offset = 3; int main(int argc, char *argv[]) { // Check for arguments to see whether there is a custom offset if (argc == 2) { // If argc == 2 then we have a offset? if (isdigit((un

当我试图通过命令行将数字传递到我的应用程序中时,下面的代码出现了奇怪的分段错误

int offset = 3;

int main(int argc, char *argv[]) {
    // Check for arguments to see whether there is a custom offset
    if (argc == 2) {
        // If argc == 2 then we have a offset?
        if (isdigit((unsigned char)*argv[1])) {
            offset = atoi(*argv[1]);
            printf("Offset changed to: %d\n", offset);
        } else {
            printf("Offset not changed due to %s not being a number.\n", *argv[1]);
        }
    } else if(argc >= 2) {
        // If argc >= 2 then we have too many arguments
        printf("Too many arguments.");
        return 0;
    }
}

argv[1]已经是一个char*类型的字符串,因此写入*argv[1]对第一个字节的解引用会在将该字节传递给atoi和printf时导致segfault

将其固定到:

偏移量=atoiargv[1];

由于%s不是数字,printfOffset未更改。\n,argv[1];
问题在于对atoi的调用。它需要一个字符串。换成

   offset = atoi(argv[1]);
代码的真正问题是,您试图调用未声明的函数,您必须使用C89/90编译器。你叫我isdigit。你叫printf。你叫阿托伊。你对后两者的称呼不正确。编译器不能通知您这些函数被错误调用的唯一原因是您忘记了声明它们

在源文件的开头包含和,以便编译器知道atoi和其他函数的正确参数类型。一旦您这样做了,您应该能够找出atoi的问题,因为编译器将发出一条诊断消息来解释问题。然后您可以相应地更改呼叫。一些编译器也可以检测printf调用的问题

请注意,即使您按照其他答案中的建议更改atoi和printf调用,例如更改为atoiargv[1]等,您的代码仍将保持无效,因为在C89/90中,未首先声明就调用printf会导致未定义的行为,而在C99中,未首先声明就调用任何函数是完全非法的

#include <ctype.h>
int isdigit(int c);
isdigit要求检查单个字符,argv[]是指向字符字符串数组的指针。
长话短说,它不会检查像1234这样的字符串,但会检查“1”。

我首先在*argv[1]中使用括号。它定义了一个唯一的操作序列,但我不相信自己知道是哪一个。为什么无符号字符转换为char类型的值,该值被提升为int并传递给isdigitint?我在网上阅读了一篇教程,我需要转换为无符号字符。。。不管我使用什么变量,我都会得到分段错误…@msw:因为如果值为负,将其传递给isdigit会导致未定义的行为。转换为无符号字符以减少模UCHAR_MAX+1是消除负字符值的一个非常好的方法。@Aran:您提供的参数是什么?@Aran Saurabh是正确的,如果您将2foo作为参数传递,isdigit返回true,但atoi会尝试将2foo转换为整数,但失败。你必须检查整个参数,而不仅仅是第一个字节。Aran只检查第一个字符是否是数字。类似0Saurabh的参数仍然无效。它将转换字符串的初始部分,生成0。目前还不清楚提问者是否想要这样做,但这不会再导致分段错误。如果使用-Wall编译,编译器会告诉您,您试图调用未声明的函数。或者本地等效的,但是对分段错误的引用建议使用Unix,因此使用GCC或其他兼容选项。我有所有必要的include,我只是排除了它们以减少复制的代码量…@Aran:如果你有所有必要的include,那么你是如何编译atoi*argv[1]的?当需要指针值时,任何C编译器都会在试图传递char值时引发各种各样的地狱。