坏流中的异常

时间:2011-05-07 18:59:38

标签: c++ exception

如果用户要输入一个字母而不是一个整数,那么循环就会变得疯狂。 我知道如何摆脱这个错误

cin.clear() and cin.ignore()

但我无法理解为什么会这样。字符由0到255之间的整数表示。每个数字都是32位足以使整数变量处理。那么为什么流失败呢?

是否可以使用异常来测试此错误,我试图理解异常,并且我无法为此编写代码。

4 个答案:

答案 0 :(得分:1)

是的,您可以使用ios::exception告诉任何流引发异常(而不是仅设置失败位)。

cin.exceptions(istream::failbit | istream::badbit);

try
{
    int a;
    cin >> a;
}
catch(istream::failure& e)
{
    cerr << "Error : " << e.what() << endl;
}

答案 1 :(得分:1)

他们为什么这样工作:

流媒体运营商&gt;&gt;和&lt;&lt;旨在读取文本(或人类可读的流(或文件))。因此,在使用时,您期望某种类型的输入具有特定形式:

int a;
stream >> a; // I expect the stream to contain an integer in human readable form.

MyClass x;
stream >> x; // I expect the class to contain a serialize version of x;

如果将char自动转换为整数,则流不会像大多数人期望流操作符一样工作(即读取人类可读形式)。即,你知道'z'的ASCII值应该是多少?您是否知道您的平台是否将字符表示为ASCII?如果我们走这条路,有很多问题只有一半是知道的。

现在,如果您想将文件视为二进制值。您可以读取单个字节并将其视为整数。

char y;
stream.read(&y, 1); // Read a single byte into y

int  x = y;         // now convert the byte to an integer.

转向例外:

当您处理与处理分开的错误时,例外情况很好。当你有大文件并且文件输入中的错误通常意味着损坏并且你应该停止处理时,这很好。然后例外是完美的解决方案。

但是简单的例子虽然你通常处理用户输入。检测和修复用户输入通常在处理现场完成,因此异常不是解决问题的最佳方案。

std::cout << "Enter a number\n";
int number;
while(!(std::cin >> number))
{
    std::cout << "That was not a number\n";
    std::cin.clear();
    std::cin.ignore();
}


// With exceptions:

  // That's too much work.

但如果我正在处理谷歌索引:

// If the read fails get out of here with an exception.
while(data >> x >> y >> z >> j >> q >> p >> src >> dst)
{
    doWork();
}
ExapndAndGrok();


// Handling the errors:

while(data >> x >> y >> z >> j >> q >> p >> src >> dst)
{
    doWork();
}
if (testDataStreamForSomeError(data)) // EOF is not an error.
{
    throw someException("The input failed");
}
ExapndAndGrok();

答案 2 :(得分:0)

您可以将循环编写为:

int var;
while ( std::cin >> var )
{
     //do whatever you want to do with var
}

如果输入除整数之外的任何内容,循环将会中断。这意味着,如果您输入字母,标点符号,浮点数等等,循环将退出,这意味着输入流中出现了错误。

答案 3 :(得分:0)

  

但我无法理解为什么会这样。一个字符由0到255之间的整数表示。每个数字都是32位足以让整数变量处理。那么为什么流失败呢?

当您使用运算符&gt;&gt;时,规范说明了对于一个int,它需要将输入解析为整数的文本表示(根据当前所使用的语言环境,尽管在int的情况下,这可能并不重要)。这意味着,除非您还使用io操纵器接受非默认基数(例如ios::hex),否则字母数字按定义是禁止的。

如果你想接受任何字符并将其视为“短短整数”的二进制表示,你可以

 unsigned char uch;
 signed char   sch;

 std::cin >> uch;
 std::cin >> sch;

正如您所预料的那样,解析原因(仅限eof(),权限被拒,内存不足或其他一些技术故障......)永远不会失败。

希望解释