使用istream遇到错误将double输入int变量
Input double into int variable using istream encounting error
在 windows10 和 VS2017 下:
我试图使用 istream 从键盘读取一个双数 1.1
并将其放入一个 int 类型变量中,比如 temp
。原因是 temp
是 1
但 istream 似乎卡在了某种错误状态。预计 istream 应该停止并等待键盘输入,但它继续进行另一轮从缓冲区读取,这次发生错误。
我检查了rdstate()
,在第二轮从缓冲区读取后它等于2
。我知道这是不正常的,但为什么?
要复制,运行 代码,在控制台中键入 1.1
并按回车键,将显示错误。
实际上,出于某些原因,我使用 int32 尝试存储 double。该程序应该打印来自键盘的有效输入。这里valid是指输入的不能超过int32的范围或者是double/readable字符。否则程序应该在屏幕上打印 Invalid input
。
#include <iostream>
std::istream& f(std::istream &in) {
int temp = 0;
while(true) {
while (in >> temp) {
if (temp == -1) {
break;
}
std::cout << temp << std::endl;
}
if (in.eof()|| temp == -1) break;
if (!in) {
std::cout << "Invalid input" << std::endl;
in.clear();
in.ignore(10000,32);
}
}
in.seekg(0, std::ios::beg);
return in;
}
int main(){
std::cout << "Please input some integers and end with ^Z or -1" << std::endl;
f(std::cin);
return 0;
}
试试这个:
#include <iostream>
std::istream& f(std::istream &in) {
std::string temp = "";
while(true) {
while (in >> temp) {
if (temp == "-1") {
break;
}
std::cout << temp << std::endl;
}
if (in.eof()|| temp == "-1") break;
if (!in) {
std::cout << "Invalid input" << std::endl;
in.clear();
in.ignore(10000,32);
}
}
in.seekg(0, std::ios::beg);
return in;
}
int main(){
std::cout << "Please input some integers and end with ^Z or -1" << std::endl;
f(std::cin);
return 0;
}
您正在逐个字符地解析缓冲区中的内容。您不能将字符放入整数中。您假设您正在从流中读取 1.1
,但您正在从缓冲区中读取 1
、.
、1
,而 .
是抛出错误。以上部分在您读取字符并将它们保存在字符串中时有效。
请记住,当您通过键盘阅读 1.1
时,您正在阅读 文本。该程序查看该文本并决定它代表什么值,具体取决于您正在读入的变量类型。如果您正在读取 int
,输入例程读取第一个“1”,然后看到“.”,它不能是 int
的文本表示的一部分,然后它停止读。您的变量的值为 1。如果您尝试从同一个输入流中读取另一个 int
,那么 '.'将立即停止读取,因为它不能成为 int
的一部分,并且尝试输入失败。
简短回答:不要那样做。如果您的输入 text 看起来像浮点数,请将其读取为浮点数。
在 windows10 和 VS2017 下:
我试图使用 istream 从键盘读取一个双数 1.1
并将其放入一个 int 类型变量中,比如 temp
。原因是 temp
是 1
但 istream 似乎卡在了某种错误状态。预计 istream 应该停止并等待键盘输入,但它继续进行另一轮从缓冲区读取,这次发生错误。
我检查了rdstate()
,在第二轮从缓冲区读取后它等于2
。我知道这是不正常的,但为什么?
要复制,运行 代码,在控制台中键入 1.1
并按回车键,将显示错误。
实际上,出于某些原因,我使用 int32 尝试存储 double。该程序应该打印来自键盘的有效输入。这里valid是指输入的不能超过int32的范围或者是double/readable字符。否则程序应该在屏幕上打印 Invalid input
。
#include <iostream>
std::istream& f(std::istream &in) {
int temp = 0;
while(true) {
while (in >> temp) {
if (temp == -1) {
break;
}
std::cout << temp << std::endl;
}
if (in.eof()|| temp == -1) break;
if (!in) {
std::cout << "Invalid input" << std::endl;
in.clear();
in.ignore(10000,32);
}
}
in.seekg(0, std::ios::beg);
return in;
}
int main(){
std::cout << "Please input some integers and end with ^Z or -1" << std::endl;
f(std::cin);
return 0;
}
试试这个:
#include <iostream>
std::istream& f(std::istream &in) {
std::string temp = "";
while(true) {
while (in >> temp) {
if (temp == "-1") {
break;
}
std::cout << temp << std::endl;
}
if (in.eof()|| temp == "-1") break;
if (!in) {
std::cout << "Invalid input" << std::endl;
in.clear();
in.ignore(10000,32);
}
}
in.seekg(0, std::ios::beg);
return in;
}
int main(){
std::cout << "Please input some integers and end with ^Z or -1" << std::endl;
f(std::cin);
return 0;
}
您正在逐个字符地解析缓冲区中的内容。您不能将字符放入整数中。您假设您正在从流中读取 1.1
,但您正在从缓冲区中读取 1
、.
、1
,而 .
是抛出错误。以上部分在您读取字符并将它们保存在字符串中时有效。
请记住,当您通过键盘阅读 1.1
时,您正在阅读 文本。该程序查看该文本并决定它代表什么值,具体取决于您正在读入的变量类型。如果您正在读取 int
,输入例程读取第一个“1”,然后看到“.”,它不能是 int
的文本表示的一部分,然后它停止读。您的变量的值为 1。如果您尝试从同一个输入流中读取另一个 int
,那么 '.'将立即停止读取,因为它不能成为 int
的一部分,并且尝试输入失败。
简短回答:不要那样做。如果您的输入 text 看起来像浮点数,请将其读取为浮点数。