为什么 atoi 给我一个分段错误?

发布于 2024-09-30 11:53:53 字数 496 浏览 12 评论 0原文

我有以下代码:

#include <stdio.h>

int main ( int argc, char *argv[] )
{
    int M, N;

    M = 1;
    N = 1;
    curr = 1;

    if ( argv[1][0] == '-' )
    {
        curr = 2;

        char *a = argv[1][1];
        char *b = argv[1][3];

        M = atoi(a);
        N = atoi(b);
    }

    printf("%d\n%d", M, N);
}

因此,我传递了这样的程序:

a.out -1,2

而不是获得预期的输出

1
2

我遇到分段错误。什么给?

I have the following piece of code:

#include <stdio.h>

int main ( int argc, char *argv[] )
{
    int M, N;

    M = 1;
    N = 1;
    curr = 1;

    if ( argv[1][0] == '-' )
    {
        curr = 2;

        char *a = argv[1][1];
        char *b = argv[1][3];

        M = atoi(a);
        N = atoi(b);
    }

    printf("%d\n%d", M, N);
}

So, I pass this program something like this:

a.out -1,2

and instead of getting expected output

1
2

I get a segmentation fault. What gives?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

九八野马 2024-10-07 11:53:53

这可以编译吗?!

char argv*[] 是一个 char 指针数组。

char *a = argv[1][1]

  • 获取第二个 char 指针,所以现在你有了一个 char *
  • 获取该指针中的第二个元素,该元素将是一个字符。

所以现在您将一个 char 分配给一个 char 指针(这应该是一个编译错误)。

我只能假设您的意思是 char *a = &argv[1][1]。顺便说一句,const 正确性也很好,所以 const char *a = &argv[1][1]

顺便说一句,你的代码仍然非常不安全 - 你甚至没有检查字符串的大小。想象一下,如果您的字符串只有两个字符,&argv[1][3] 会做什么。

That compiles?!

char argv*[] is an array of char pointers.

char *a = argv[1][1] will

  • Get the second char pointer, so now you have a char *.
  • Get the second element in that pointer, which will be a char.

So now you are assigning a char to a char pointer (which should be a compile error).

I can only assume you meant to say char *a = &argv[1][1]. Btw, const-correctness would be nice too, so const char *a = &argv[1][1].

Btw, your code is still very unsafe - you don't even check the size of the string. Imagine what &argv[1][3] does if your string only has two characters.

梅窗月明清似水 2024-10-07 11:53:53

#include 它应该变得显而易见。

详细说明:您将一个整数传递给需要指针的函数,并且编译器无法警告您,因为您忘记使用原型声明该函数。这就是事故发生的原因。

此外,您只是误用了atoiatoi 解析字符串,而不是单个字符。如果您希望字符的值为数字,只需减去'0'

M = argv[1][1]-'0';
N = argv[1][3]-'0';

实际上,您还应该检查该字符实际上是否是数字。

编辑:我不记得原始帖子中存在char *a = argv[1][1];(也许早期的编辑不会显示为编辑? ),但任何理智的编译器都应该在该行给出编译时错误。在 C 中,整数不会隐式转换为指针。如果编译器确实允许这种情况发生,那么包含 atoi 的原型将不再有帮助,因为之前发生了类型错误。

#include <stdlib.h> and it should become apparent.

To elaborate: you're passing an integer to a function which expects a pointer, and the compiler could not warn you because you forgot to declare the function with a prototype. This is the cause of the crash.

Moreover, you're simply misusing atoi. The atoi parses strings, not individual characters. If you want the value of a character as a digit, simply subtract '0':

M = argv[1][1]-'0';
N = argv[1][3]-'0';

In practice you should also check that the character is actually a digit.

Edit: I don't recall char *a = argv[1][1]; being in the original post (maybe early edits don't show up as edits?), but any sane compiler should give a compile-time error on that line. Integers do not implicitly convert to pointers in C. If the compiler does let this get by, then including a prototype for atoi will no longer help, since the type error occurred earlier.

栩栩如生 2024-10-07 11:53:53

atoi 接受一个字符串,而不是一个字符。

另外,atoi 总体来说也不好,因为它基本上没有错误报告。大多数情况下您应该调查 strtol。

atoi takes a string, not a character.

Also, atoi is not good in general as it has basically no error reporting. You should investigate strtol for most cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文