简体   繁体   English

C ++ int或双输入

[英]C++ int or double input

I'm looking to clean up some already-functioning code I have. 我正在寻找清理一些已经运行的代码。 First of all, this is for an assignment and the assignment specifies ints must be taken as ints, doubles as doubles, etc, otherwise I might just take the input as a double and cast as an int if(number%1==0) . 首先,这是一个赋值,赋值指定整数必须作为整数,双精度数等,否则我可能只是将输入作为双精度并转换为int if(number%1==0)

I've trimmed the code down to just handling the input (with an output statement to verify it's working properly). 我已经将代码修剪为仅处理输入(使用输出语句来验证它是否正常工作)。

int wholePart=0;
double decimalPart=0;
cout << "Input a number: ";
cin >> wholePart;
if(cin.peek() != '\n')
    cin >> decimalPart;

cout << "wholePart = " << wholePart << endl << "decimalPart = " << decimalPart << endl;

Now... this works as is, and after I add the code to handle combining the integer and decimal if the decimalPart isn't 0, then I've already done more than the assignment calls for, but I'm looking to learn, and I want to clean this code up as much as possible. 现在......这样可以正常工作,并且在我添加代码以处理组合整数和十进制(如果decimalPart不为0)之后,我已经完成了比赋值调用更多的工作,但我希望学习,我想尽可能地清理这段代码。

I can wrap the whole input section with other input validation to be sure the user is actually entering numbers and not characters. 我可以使用其他输入验证来包装整个输入部分,以确保用户实际上输入数字而不是字符。 But my primary concern here is that if(cin.peek() != '\\n') isn't good enough. 但我最关心的是if(cin.peek() != '\\n')不够好。 Perhaps if(cin.peek() == '.') is a better option, but I'm curious what would be the best way of going about accomplishing what I'm trying to accomplish here. 也许if(cin.peek() == '.')是一个更好的选择,但我很好奇什么是最好的方式来完成我想在这里完成的事情。 Any ideas? 有任何想法吗?

And please don't just turn this down as "oh it's homework." 请不要把它变成“哦它的功课”。 I want to emphasize that my program already goes above and beyond what even the extra credit part of the homework asks for. 我想强调的是,我的课程已经超出了家庭作业的额外学分所要求的范围。 I'm just trying to learn more about the language and what the best way for handling this sort of input might be. 我只是想了解更多关于语言的知识以及处理这种输入的最佳方法。

I presume that something like "1.0" should be taken as a double as well; 我认为像"1.0"这样的东西也应该被视为双倍; that pretty much eliminates things like reading a double, then checking if it is actually an integer. 这几乎消除了读取double之类的内容,然后检查它是否实际上是一个整数。

The only way is to parse the data, to see whether you encounter something that can be interpreted as an int or not. 唯一的方法是解析数据,看看你是否遇到了可以被解释为int东西。 If you're going to use the conversion functions of the stream, this pretty much means scanning the input twice. 如果您要使用流的转换函数,这几乎意味着扫描输入两次。 The obvious solution would be to put the input into a string; 显而易见的解决方案是将输入放入字符串中; these are much easier to scan multiple times. 这些更容易扫描多次。 If you're not allowed to do that, you can use istream::tellg to memorize the position, scan ahead, and once you've decided, istream::seekg to go back to where you started from. 如果你不允许这样做,你可以使用istream::tellg记住位置,向前扫描,一旦你决定, istream::seekg回到你开始的地方。 But I don't know what rules your instructor has imposed. 但我不知道你的导师强加了什么规则。

If you can't seek, you can try hacking it by hand. 如果你不能寻求,你可以尝试手工黑客攻击。 First read an int , then peek at the next character. 首先读取一个int ,然后查看下一个字符。 If it's a '.' 如果它是'.' , you can then read a double, which will give you the fractional part, which you can add to the integer you've already read. ,然后你可以读一个double,它会给你小数部分,你可以将它添加到你已读过的整数中。 If it's an 'E' or and 'e' , it becomes a bit more difficult; 如果它是'E''e' ,它会变得有点困难; you probably have to advance, read an int, and use pow manually. 你可能需要前进,读取一个int,并手动使用pow But this is far from perfect: if the double has the form "1.2E6" , you'll end up with 200000 as the "fractional" part; 但这远非完美:如果双重形式为"1.2E6" ,那么你最终会得到200000作为“分数”部分; you'll need some means of detecting this, and scaling the integer you've alread read. 你需要一些方法来检测它,并缩放你读过的整数。 And if the number is ".3" , you'll get an error when reading the integer: you can either check for this beforehand (but don't forget "-.3" ), or reset the error before doing anything else. 如果数字为".3" ,则在读取整数时会出现错误:您可以事先检查(但不要忘记"-.3" ),或者在执行任何其他操作之前重置错误。 And of course, it's possible that the integral part of a double won't fit into an int (or even a long long ). 当然,双精度的整数部分可能不适合int (甚至long long )。

All in all, it seems a bit artificial to me. 总而言之,对我来说似乎有点人为。 In practice, you'd read into a string, and match regular expressions against it in order to determine how you wanted to interpret it. 在实践中,您将读入一个字符串,并将正则表达式与其匹配,以确定您希望如何解释它。

It's probably easier to read in the whole line as a string first, check for a decimal point and then feed the line to a stringstream which can then either convert it to an int or double (depending on if the decimal point is available): 它可能更容易在整行中作为字符串读取,检查小数点然后将该行提供给字符串流,然后可以将其转换为int或double(取决于小数点是否可用):

#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>

using namespace std;

int main() {
  string line;
  int anInteger;
  double aDouble;

  getline( cin, line );
  stringstream ss( line );
  if ( line.find( '.' ) == string::npos ) {
    ss >> anInteger;
  } else {
    ss >> aDouble;
  }

  return 0;
}

Given your specification, I would read a std::string , see if that could be something else than an integer and depending on the outcome parse as int or as double . 根据你的规范,我会读取一个std::string ,看看是否可能是一个整数以外的东西,取决于结果解析为intdouble For example 例如

int         integer;
double      number;
std::string value;
if (std::cin >> value) {
    if (value.find_first_of(".Ee")) {
        if (std::istringstream(value) >> number) {
            std::cout << "read double=" << number << '\n';
        }
        else {
            std::cout << "failed to read double from '" << value << "'\n";
        }
    }
    else {
        if (std::istringstream(value) >> integer) {
            std::cout << "read integer=" << integer << '\n';
        }
        else {
            std::cout << "failed to read integer from '" << value << "'\n";
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM