C++字符转整数

9

当你使用cin>>将字母输入到int变量中时会发生什么?我尝试了一个简单的代码来加两个整数,首先读取它们,然后相加。但是当我输入字母时,它就会失败并在屏幕上打印出大量数字。但是这种错误是由什么引起的呢?我的意思是,我期望它加载和使用该字母的ASCII码。


1
你能发一下你用的代码吗? - Pratik Deoghare
5个回答

10

我假设您有以下代码:

int n;
while (someCondition) {
    std::cin >> n;
    .....
    std::cout << someOutput;
}

当你尝试读取无法转化为整数的输入时,输入流(std::cin)将进入失败状态,除非你处理这个输入错误,否则之后的所有输入都会失败。

你可以测试输入操作的成功与否:

if (!(std::cin >> n)) //failed to read int

你可以将流恢复到良好状态并丢弃未处理的字符(导致输入故障的输入):

std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

另一种可能性是将输入接受到一个字符串变量中(这很少会失败),然后尝试将字符串转换为整数。

这是输入时非常常见的问题,这里和其他地方应该有大量关于此的讨论帖子。


谢谢,如果我理解正确的话,stdout实际上将ASCII代码发送到程序,但std :: cin识别它是什么类型并以这种方式使用它。 - Vit
1
如果您期望输入到 int 变量中,那么 "123" 是可以的,但 "xyz" 会导致输入操作失败。流仅从输入获取一系列字符,但它执行请求类型的转换,并以您可以和应该测试的方式指示无法执行转换的情况。 - visitor

3
如果你将char明确转换为int,它将使用ASCII码,否则它不会自动将其转换为int,因此你会得到奇怪的结果。

1

当你在做类似这样的事情时:

int x;
cin >> x;

你正在指示C++从键盘读取一个int。实际上,当你输入的不是int时,输入流(在这种情况下是标准输入)会因其错误状态而无法使用。

这就是为什么我个人更喜欢始终读取字符串,并在需要时将它们转换为数字。C++标准库的C部分中有一些转换函数可以帮助完成此操作。

double cnvtToNumber(const std::string &num)
{
    char * ptr;
    double toret = strtod( num.c_str(), &ptr );

    if ( *ptr != 0 ) { // If it got to the end of the string, then it is correct.
        throw std::runtime_error( "input was not a number" );
    }
    return toret;
}

在这里,您正在转换一个数字,并检测转换是否正确。 strtod(s)仅在找到字符串的结尾或空格时停止。为了避免尾随空格欺骗函数,您可能需要一个修剪函数:

std::string &trim(std::string &str)
{
    // Remove trailing spaces
    unsigned int pos = str.length() -1;

    while( str[ pos ] == ' ' ) {
        --pos;
    }

    if ( pos < ( str.length() -1 ) ) {
        str.erase( pos + 1 );
    }

    // Remove spaces at the beginning
    pos = 0;
    while( str[ pos ] == ' ' ) {
        ++pos;
    }

    if ( pos < 1 ) {
        str.erase( 0, pos );
    }

    return str;
}

现在你可以安全地从控制台(或任何其他输入流)读取:

int main()
{
    std::string entry;

    try {
        std::getline( std::cin, entry );
        int age = cnvtToNumber( trim( entry ) );

        std::cout << age << std::endl;
    } catch(const std::exception &e) {
        std::cerr << e.what() << std::endl;
    }
}

如果你总是读取 double 然后转换,当然会失去精度。如果你想进一步研究,可以使用特定的整数函数(strtol(s))。


1
你可以使用 int istream::get();

1
问题在于,当您使用C++流读取整数变量时,输入方法期望可以组成数字的字符,例如'+', '-', '0' ... '9'。任何不属于此集合的字符都会终止输入,并从这些字符创建一个数字。
要获取字符的ASCII值,您需要将数据输入到char变量中。在内部,它具有ASCII值(前提是程序未读取16位字符或EBCDIC)。如果您想查看ASCII值,则需要将char变量输出为整数(通常需要在输出之前进行转换)。
如果读取整数失败,则您的程序需要通知用户输入不正确。程序可能需要用户重新输入数字,然后才能处理输入数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接