【问题标题】:Converting *argv[] to int using atoi使用 atoi 将 *argv[] 转换为 int
【发布时间】:2015-01-11 20:16:38
【问题描述】:

我正在尝试使用 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;
}

【问题讨论】:

标签: c++


【解决方案1】:

一般来说,要将std::string 转换为整数类型,可以使用std::stoi
当您写入指向未分配内存的指针时,您的代码会显示未定义的行为;使用std::string []std::strings 的标准容器。

【讨论】:

  • 我没有使用 C++11,因此是 C++ 标签,而不是 C++11 标签。
【解决方案2】:

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

改为:

#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",它以null 结尾,是C 风格的字符串,适合传递给atoi() 之类的函数.但是,您将无法修改该字符串,因此如果您想这样做,您需要声明一个实际数组,或者使用 new 运算符动态分配一些内存。

您也可以将nullptr 更改为NULL,如果正如对另一个答案的评论所暗示的那样,您没有使用 C++11。我添加了argv 的第五个成员设置为nullptr,因为当您开始使用实际命令行而不是手动设置它时,传递给main()argv 将拥有该成员。

【讨论】:

  • 感谢这对您有很大帮助。
  • 所以,当我实际通过命令行传递参数时,我的 argv 数组中的最后一个参数将是一个空 ptr,它是一个指向 NULL 的指针,对吗? --是的,我正在为 g++ 进行编译,而目前它没有使用 C++11。
  • 谢谢,这很有趣。所以 argv 在意义上类似于 c 字符串,因为它是一个 char 数组的数组,由指向空值的指针终止。所以 argv 总是二维的?我认为 2D 数组是这样声明的 **arrayName。如果我杀了那个也真的很抱歉……我真的很想把头绕在 argv 上。
  • 当您开始在此上下文中了解指针和数组之间的技术差异时,事情可能会变得有些棘手。从技术上讲,argv 是指向char * 的单个指针,根本不是一个数组,但对于大多数实际目的,您可以将其视为char *argc + 1 元素的一维数组,最后一个其中将始终为NULL。从某种意义上说,它的最后一个可用元素用作标记“结束”的标记值,它类似于 C 字符串,是的。
  • 因为argv 的每个元素都指向一个C 字符串,也可以将其作为一维数组(char,不过,不是char *) 这允许您执行argv[1][3] 之类的操作,使argv 看起来 好像它是一个二维数组,但实际上不是。 argv[1][3] = 'x'; 基本等同于char * str = argv[1]; str[3] = 'x';
【解决方案3】:

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

有效代码如下所示

#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 &lt;&lt; 解释为以零结尾的字符串的第一个字符。

【讨论】:

    猜你喜欢
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 2013-07-14
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多