如何将输入与ASCII代码进行比较?

3

我正在尝试编写一个控制台程序,该程序从输入中获取一个数字并将其放入数组中。读取持续时间取决于用户是否按下“空格”按钮。我尝试了几种方法,但是我的程序无法将输入与“空格”的ASCII代码进行比较。提前致谢!

#include <iostream>
using namespace std;

int main()
{
    int fabcd[25],number_of_items = 0;
    cout << "The read in loop lasts while you don't hit space:\n";
    while((char)cin.get() != 32)
    {
            cin >> fabcd[number_of_items];
            number_of_items++;      
    }   
    return 0;
}

它将接受一个整数输入,并将其与数字32进行比较。 - Grobi
你应该使用 char a=cin.get(); 然后 fabcd[number_of_items]=a - kwjsksai
@Immueggpain 可能。这取决于他想要做什么。如果他想读取一个整数(由一个或多个字符组成的数字),则需要在某处使用 >>。如果他想读取数字,则 int a = std::cin.get(); 是正确的解决方案。在测试文件结束之前,将 std::cin::get() 的结果分配给 char永远不正确 的做法。 - James Kanze
@JamesKanze,没错。请看下面我的回答。有其他问题。 - kwjsksai
@Immueggpain,有不止一件事情出了问题,而且甚至不清楚OP在尝试做什么。请看下面的我的回答。 - James Kanze
显示剩余5条评论
5个回答

4
你的代码存在几个问题。最根本的问题是每次循环都进行两次输入,第一次在while中,第二次使用>>在循环中。注意第二次输入将跳过任何空格,然后将输入转换为整数。如果输入不能被合法地转换为整数(例如下一个字符是'a'),则输入会进入错误状态,并且cin.get()将始终返回EOF。当然,如果你输入的是数字,你可以轻松地输入超过25,并覆盖缓冲区。
如果你只想输入一系列数字,那么:
std::vector<int> fabcd;
int tmp;
while ( std::cin >> tmp ) {
    fabcd.push_back( tmp );
}

只需要这个。 (数字必须用空格分隔。)如果您想输入数字,直到遇到空格,可以尝试以下内容:

std::vector<int> digits;
int tmp = std::cin.get();
while ( tmp != EOF && ! std::isspace( tmp ) ) {
    digits.push_back( tmp /* or tmp - '0' */ );
    tmp = std::cin.get();
}

请注意,std::cin.get()的结果被赋值给了一个int,而不是char。这个函数有意返回一个int,因为它必须能够返回EOF值。关于这个函数还有几个变体:如果使用std::cin::peek()而不是std::cin::get(),你不会实际提取字符(这将在循环中进行),还有std::get(char&),它将提取字符到给定的char中,前提是它不在EOF处。使用这个函数,循环将是:
std::vector<int> digits;
char tmp;
while ( std::get( tmp ) && ! std::isspace( tmp ) ) {
    digits.push_back( tmp );
}

(你可能希望使用 std::isdigit 来控制循环,而不是 !std::isspace。)

编辑:

最后一个要点:空格或其他字符的实际数字代码取决于实现,并且不一定为32。此外,您将希望类似地处理制表符和换行符。您应该始终使用 isspace 等函数。或者,如果您确实想要检查空格,只有空格,请与 ' ' 进行比较,而不是32。


感谢您详尽的回答。我会仔细学习它 :) - Grobi

0

空格的ASCII码是32。因此,您应该将64或13(回车)替换为32:

while((char)cin.get() != 32)

然而问题可能在于cin会停留在某些字符上,例如空格:您可以通过设置cin.unsetf(ios::skipws)来禁用此行为。参考C++, user input check for '\0' stops at spaces?


问题是,我已经尝试了32,然后想尝试使用回车键13,但是我的循环出于某种原因仍然无法停止。 - Grobi
cin >> plainText 从输入中读取直到第一个空格字符,但不包括它。也许 std::getline(cin, plainText) 可以解决这个问题。 - David Karlsson
std::ios::skipwsstd::istream::get 没有影响。只有格式化输入('>>')会跳过空格。 - James Kanze

0

试试这个:

 #include <iostream>
#include <conio.h >
using namespace std;

int main()
{
    int fabcd[25],number_of_items = 0;
    cout << "The read in loop lasts while you don't hit space:\n";
    while( _kbhit() != 32  )
    {
            char ch =getche();
            if (ch != 32 )
            {
           cin >> fabcd[number_of_items];
            number_of_items++;
            }
            else
                break;

    }   
    cout << "\nnumber of items:"<<number_of_items;
    cin.get();
    cin.get();
    return 0;
}

用什么编程语言?这不是C++,在支持<conio.h>的少数平台上,它已被弃用。它是MS-DOS的余孽(在那里它是CP/M的余孽),你不应该在新代码中使用<conio.h> - James Kanze

0

(char)13 是回车符而不是空格。

重点不是你会做什么:

((char)cin.Get()) !=' '

0
这是答案:
int fabcd[25],number_of_items = 0;
cout << "The read in loop lasts while you don't hit space:\n";
char a;
while((a=cin.get()) != ' ')
{

        fabcd[number_of_items]=a;
        number_of_items++;      
}   
return 0;

这是不正确的,会在文件结束时进入无限循环。std::cin::get() 之所以返回一个 int 是有原因的,并且在测试文件结束前将其赋值给 char 是始终不正确的。 - James Kanze
@JamesKanze,是的,它是int类型,但可以赋值给char。 - kwjsksai
在错误的代码中,由于重要信息的丢失,您不能将其分配给一个 char 之前 确保它不是 EOF(通常为-1,但保证为负数)。 - James Kanze
@JamesKanze,你怎么可能在这里期望任何EOF呢?但是你说得对,如果需要将其转换为char,则确实需要在检查EOF之前进行检查。 - kwjsksai
你可以像在任何地方一样获取文件结尾。但是,你怎么能确定不会有文件结尾呢? - James Kanze
当然,关键点在于,在8位机器上,std::istream::get可能会返回257个不同的值。这就是为什么它返回int而不是char的原因。(但是你可以使用while ( std::cin.get( a ) && a != ' ' ))。检查成功很重要,因为任何时候如果输入失败,流将继续返回失败(从std::istream::get()返回EOF),直到错误被清除。这会导致你的示例进入无限循环。 - James Kanze

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