C++ atoi没有给出正确的输出

C++ atoi没有给出正确的输出,c++,C++,有人能告诉我为什么变量'b'的值是25,我期望值是2。这是我的密码 #include<iostream> #include<string> #include<stdlib.h> #include<sstream> using namespace std; int main(int argc,char*argv[]) { stringstream ss; string sss; unsigned short rt=52;

有人能告诉我为什么变量'b'的值是25,我期望值是2。这是我的密码

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

using namespace std;

int main(int argc,char*argv[])
{
    stringstream ss;
    string sss;
    unsigned short rt=52;
    ss<<rt;
    sss=ss.str();

    cout<<sss.at(0)<<"     "<<sss.at(1)<<endl;
    char ch1=sss.at(0);
    char ch2=sss.at(1);
    //int ui=atoi((char*)sss.at(0))*10+atoi((char*)sss.at(1)); //can somebody tell me what's wrong in this statement(causes segmentation fault)
    cout<<ch1<<"     "<<ch2<<endl;
    int a=atoi(&ch1);
    int b=atoi(&ch2); //giving output as 25
    cout<<a<<"    "<<b<<endl;
    int c=a*10+b;
    int ui=atoi(&ch1)*10+atoi(&ch2);

    cout<<ui<<"     "<<c<<endl;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(int argc,char*argv[])
{
细流ss;
字符串sss;
无符号短rt=52;

ssatoi应该将以零结尾的C字符串作为输入参数 您只传递指向字符的指针。这是未定义的行为,可能有任何结果(在某些情况下,程序可能崩溃)

但为什么你能得到25分呢

可能变量ch1和ch2都顺序存储在内存中,并且在它们后面有一些非数字字符。atoi()将指向ch1的指针视为以零结尾的c字符串,并从内存中读取数据,直到找到第一个非数字字符,然后将结果转换为整数。这就是为什么会得到25。但实际上,这是未定义的行为,您可能会得到另一个结果,或者使用另一个编译器(甚至另一个编译参数)导致程序崩溃

我还可以在注释掉的代码行中看到另外一个问题

//int ui=atoi((char*)sss.at(0))*10+atoi((char*)sss.at(1)); //can somebody tell me what's wrong in this statement(causes segmentation fault)

存在分段错误,因为您将char('2'或'5')的值转换为指针“char*”。因此这些字符的ASCII码被视为内存地址。当然,此地址不正确,访问内存会导致分段错误。

atoi应将以零结尾的C字符串作为输入参数 您只传递指向字符的指针。这是未定义的行为,可能有任何结果(在某些情况下,程序可能崩溃)

但为什么你能得到25分呢

可能变量ch1和ch2都顺序存储在内存中,并且在它们后面有一些非数字字符。atoi()将指向ch1的指针视为以零结尾的c字符串,并从内存中读取数据,直到找到第一个非数字字符,然后将结果转换为整数。这就是为什么会得到25。但实际上,这是未定义的行为,您可能会得到另一个结果,或者使用另一个编译器(甚至另一个编译参数)导致程序崩溃

我还可以在注释掉的代码行中看到另外一个问题

//int ui=atoi((char*)sss.at(0))*10+atoi((char*)sss.at(1)); //can somebody tell me what's wrong in this statement(causes segmentation fault)
存在分段错误,因为您将char('2'或'5')的值转换为指针“char*”。因此这些字符的ASCII码被视为内存地址。当然,此地址不正确,访问内存会导致分段错误。

atoi()
如中所述,expect是一个以null结尾的字符串,并尝试将整个字符串转换为数字,因此尝试将其用于单个数字是完全错误的,只需将其应用于整个字符串即可:

int ui = std::atoi( sss.c_str() );
atoi()
如中所述,使用一个以null结尾的字符串并尝试将整个字符串转换为数字,因此尝试将其用于单个数字是完全错误的,只需将其应用于整个字符串:

int ui = std::atoi( sss.c_str() );

atoi
需要指向以零结尾的字符串的指针。向其传递任何其他内容都是未定义的。您可以通过减去
'0'
将文本数字转换为数字数字。无需调用函数。对于这种特殊情况,Thomas有更好的方法,但请注意:永远不要使用
atoi()
。标准函数
strtol()
做同样的事情更好。@BenVoigt:更不用说
stoi
等了。
atoi
需要一个指向以零结尾的字符串的指针。传递给它的任何东西都是未定义的。你可以通过减去
'0'
将文本数字转换为数字数字。不需要调用函数。Thomas有更好的方法来传递这是一个特殊的例子,但要注意将来:永远不要使用
atoi()
。标准函数
strtol()
可以更好地完成所有相同的事情。@BenVoigt:更不用说
stoi
等了。'你怎么知道的?实际上这是C++ C++中未定义的行为。在任何情况下程序都会崩溃。但是问题的作者很好奇他是如何得到25的结果。C++字符串(SSS)将数据存储为char数组和“0”(它不是标准的,但是所有编译器都这样做)。
std::string
可以以任何方式存储数据,但OP不会传递指向
std::string
内容的指针,因此您无法知道ch1和ch1之后内存中驻留的内容ch2@Sandro还需要返回以null结尾的字符串。@HolyBlackCat,但他只是将at()方法返回的字符复制到内存“25\0”中的以下字符你怎么知道的?实际上这是C++ C++中未定义的行为。在任何情况下程序都会崩溃。但是问题的作者很好奇他是如何得到25的结果。C++字符串(SSS)将数据存储为char数组和“0”(它不是标准的,但是所有编译器都这样做)。
std::string
可以以任何方式存储数据,但OP不会传递指向
std::string
内容的指针,因此您无法知道ch1和ch1之后内存中驻留的内容ch2@Sandro还需要返回以null结尾的字符串。@HolyBlackCat,但他只是复制由at()方法返回的字符