0

我有以下代码:

void test(int N)
{
    printf("%d", N);

}
int main(int ac, char **av)
{
    test("");
    return 0;
}

我有一个需要一个整数参数的函数测试,但是在我调用该函数时,我主要给出一个字符串参数,然后 c 将其转换为整数并为我打印出来。但我想要的是,如果有人传递了一个字符串,我就会给出一个错误。如何检查参数是否为字符串?

谢谢 !

4

4 回答 4

1
void test(int N) { /* ... */ }

...

test("");

该函数调用根本无效。test需要 type 的参数int,或者可以隐式转换为int(任何算术类型都可以)的参数。""是字符串文字;在这种情况下,它被转换为一个char*值,该值指向'\0'数组的第一个(也是最后一个也是唯一的)字符。

没有从char*to的隐式转换int。符合标准的编译器必须为无效调用发出诊断,并且它可能(并且恕我直言应该)彻底拒绝它。它与试图取字符串文字的平方根或将 42 添加到结构中一样无效。

旧版本的 C(在 1989 年 ANSI 标准之前)对这种事情更加宽松,这种宽松在一些现代编译器中仍然存在。很可能,如果您的编译器不拒绝调用,它将获取字符串文字的地址并将其转换为int. 这种转换的结果在很大程度上是没有意义的;这样的编译器允许它真的对你没有任何好处。

如果你的编译器没有拒绝,或者至少警告,调用,你应该启用任何必要的选项来使它这样做。例如,对于 gcc,您可以尝试以下操作:

gcc -std=c99 -pedantic -Wall -Wextra filename.c

-pedantic如果你想使用 gcc 特定的扩展,你可以放弃。该选项有几个可能的参数-std=。有关更多信息,请参阅 gcc 文档 - 或您正在使用的任何编译器的文档。

如果您询问验证用户输入(即来自运行您的程序而不是编写 C 代码的人的输入),则用户输入通常不是数字形式。它以文本、字符序列的形式出现。例如,您可以使用该fgets()函数从标准输入中读取一行文本。然后,如果您愿意,可以检查该行是否具有整数文字的形式。一种方法是使用该sscanf功能。一个简单的例子:

#include <stdio.h>
int main(void) {
    char line[200];
    int n;

    printf("Enter an integer: ");
    fflush(stdout);
    fgets(line, sizeof line, stdin);
    if (sscanf(line, "%d", &n) == 1) {
        printf("You entered %d (0x%x)\n", n, (unsigned)n);
    }
    else {
        printf("You did not enter an integer\n");
    }
}

但是,如果您的问题是关于有人编写调用您提供的函数的 C 代码,编译器将检查任何参数是否为有效类型。

于 2013-09-24T04:56:17.943 回答
0

我想要的是如果有人传递一个字符串而不是我给出一个错误

那不是你的问题。我认为大多数编译器都会为此发出警告——假设警告已启用。

问题是 C 总是按值传递,但字符串参数是一个数组,它的值是数组中第一个字符的地址——一个指针,但指针值可以被视为整数。同样,如果您正确使用它们,大多数编译器都足够聪明,可以捕捉到这种歧义。

你不能对不正确使用它的人完全保护你的代码。你编写一个 API,记录它,但你不必为那些不能正确使用基本工具的人提供案例。

核心标准 C 库不包括您在此处寻找的那种检查,因此将它们合并到您的 API 中似乎毫无意义——有大量带有参数的内置标准命令,int数组可以在同样的方法。使某人免于使用您的库做一些愚蠢的事情不会使他们免于使用基本 C 库做完全相同的事情——即,您不能阻止他们传递指针来代替整数。时期。

于 2013-09-24T01:52:31.280 回答
0

天真的方法是这样的:

int is_integer( const char *s )
{
    if( *s == '-' || *s == '+' ) s++;
    while( isdigit(*s) ) s++;
    return *s == 0;
}

这将告诉您是否所有字符都是数字,带有可选符号。然而,它并不是特别强大。它不能处理空格,并且它不检查整数是否在有效范围内。

但是,它可能足以满足您的需求。

例子:

int main( int argc, char **argv )
{
    int val;

    if( argc <= 1 || !is_integer(argv[1]) ) {
        fprintf( stderr, "Syntax: %s val\n\nWhere val is an integer\n", argv[0] );
        return 1;
    }

    val = strtol( argv[1], NULL, 10 );
    test(val);

    return 0;
}
于 2013-09-24T01:46:18.820 回答
0

-Wall用and编译,-Werror你的问题就会神奇地消失。

gcc -Wall -Werror file.c
于 2013-09-24T02:06:32.457 回答