使用atoi将* argv []转换为int

时间:2014-11-14 12:25:52

标签: c++

我正在尝试使用atoi函数将存储在argv数组中的char转换为int 我是C ++新手并传递参数,所以请耐心等待。

每当我尝试将atoi [1]中存储的值设置为const char并打印char时,它根本不会打印任何内容。如果我做错了,它仍然应该打印一个内存地址,对吗?

我将它设置为const char,因为atoi函数需要一个const char作为它的参数。 (如果我错了,请纠正我)

我一直在通过ideone.com这样做,所以我的argv数组在运行时并没有真正设置,因为ideone不允许这样做。

到目前为止,这是我的代码:

#include <iostream>
#include<string>
#include <stdlib.h>
using namespace std;

int main() {
    int argc;
    char *argv[4]; 

    *argv[0] = 'x';
    *argv[1] = '5';//this will be the length of our first array for testing
    *argv[2] = '3';//this will be the length of our second array for testing
    *argv[3] = '4';//this will be the length of our third array for testing
    argc = 4;

    const char  * argv1 = argv[1];

    cout << "*argv[1]: " <<  *argv[1] << endl;
    cout << "argv[1]: " <<  argv[1] << endl;
    cout << *argv1;

    //int x = atoi(argv1);

    return 0;
}

更新的代码:现在具有编译功能!

#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

int main() {
    char nullGuy = NULL;
    char * nullptr1 = &nullGuy;//Null ptr

    int argc;
    const char * argv[5]; 

    argv[0] = "x";
    argv[1] = "5";
    argv[2] = "3";
    argv[3] = "4";
    argv[4] = nullptr1;

    argc = 4;

    int x = atoi(argv[1]);

    cout << "argv[1]: " <<  argv[1] << endl;
    cout << "x: " << x << endl;

    return 0;
}

3 个答案:

答案 0 :(得分:1)

你的指针都没有指向有效的内存。当你尊重它们时,你会得到未定义的行为。即使这不是真的,你也不会将它们终止,因此它们不是字符串。

更改为:

#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

int main() {
    int argc;
    const char * argv[5]; 

    argv[0] = "x";
    argv[1] = "5";
    argv[2] = "3";
    argv[3] = "4";
    argv[4] = nullptr;
    argc = 4;

    int x = atoi(argv[1]);

    cout << "argv[1]: " <<  argv[1] << endl;
    cout << "x: " << x << endl;

    return 0;
}

作为解释,来自原始代码:

*argv[0] = 'x';

与:

相同
*(argv[0]) = 'x';

与:

相同
argv[0][0] = 'x';

表示“将地址存储在argv[0],并将值'x'存储在那里”。由于您从未初始化argv[0]或任何argv成员,因此这些地址都不是有效的,并且它们极不可能指向您允许写入的任何内存。

如果您将argv声明为char argv[4][20];,那么这样就行了,因为argv[0]不再是未初始化的指针,而是一个包含20个字符的数组可以写信给。

然而,即使你这样做了,你也想做类似的事情:

argv[1][0] = 'x';
argv[1][1] = '\0';

因为传递给atoi()的东西必须是实际的(C风格)字符串,而不是指向单个字符的指针,并且字符串必须以空字符终止。

相反,在我给出的代码中:

const char * argv[5];
argv[1] = "5";  //  <-- Note use of double, not single, quotes

确实使argv[1]成为char的指针,但指向字符串文字"5",它是以空值终止的,是一个C风格的字符串,适合传递像atoi()这样的函数。但是,您将无法修改该字符串,因此,如果您想这样做,则需要声明实际数组,或者使用new运算符动态分配一些内存。

如果您对其他答案的评论表明您没有使用C ++ 11,则还可以将nullptr更改为NULL。我添加了argv的第五个成员设置为nullptr,因为当您开始使用实际命令行而不是手动设置它时,传递给argv的{​​{1}}是有这个成员。

答案 1 :(得分:0)

通常,要将std::string转换为整数类型,您可以使用std::stoi 您的代码显示未定义的行为,因为您正在写入指向未分配内存的指针;使用std::string []std::string s的标准容器。

答案 2 :(得分:0)

主要的问题是你没有分配数组元素所指向的内存以及你要写字符的位置。

有效代码可以采用以下方式

#include <iostream>

int main() 
{
    const size_t N = 4;
    int argc;
    char *argv[N];

    argv[0] = new char( 'x' );
    argv[1] = new char( '5' );//this will be the length of our first array for testing
    argv[2] = new char( '3' );//this will be the length of our second array for testing
    argv[3] = new char( '4' );//this will be the length of our third array for testing
    argc = N;

    const char *argv1 = argv[1];

    std::cout << "*argv[1]: " << *argv[1] << std::endl;
    std::cout << "argv[1]: "  << ( void * )argv[1]  << std::endl;
    std::cout << *argv1 << std::endl;;

    for ( char *p : argv ) delete p;

    return 0;
}

输出看起来像

*argv[1]: 5
argv[1]: 0x9aeb018
5

考虑在声明

中使用强制转换为void *
    std::cout << "argv[1]: "  << ( void * )argv[1]  << std::endl;

否则argv1 [1]将由operator <<解释为字符串的第一个字符,以零结尾。