0

对于我的项目,我必须覆盖 operator>> 方法以从文本文件中读取数字数组。这是我第一次这样做,我很迷茫。到目前为止,我的代码看起来像这样。

std::istream& operator>>(std::istream& in, bigint array){

          bool semi = false ;

          while(!semi){
            if(get() = ';')
              semi = true ;
            in <<get();
          }
        return in ;
     }

文件看起来像这样。

10000000000000000000000000000000000345;
299793000000
00000000000000000000067;
4208574289572473098273498723475;
28375039287459832728745982734509872340985729384750928734590827098752938723;
99999999;  99999999;

每个新数组在遇到";'. 空白和尾线也让我感到困惑。任何帮助将不胜感激,谢谢。

4

2 回答 2

2

你会想要使用

bigint& array

通过引用获取值(或者您不可能将读取的数字插入其中)。

此外,您将要使用

char ch;
in >> ch;

而不是in << get()(不编译)。更好的是,添加错误处理:

if (!(in >> ch))
{
    // we're in trouble (in.rdstate(), in.eof(), in.fail() or in.bad() to know more)
}

如果你想使用in.get(),你应该准备好跳过你自己的空格(包括换行符)。我更喜欢std::istream_iterator这里,因为它会自动这样做(如果std::ios::skipws标志有效,默认情况下是这样)。

所以这是一个简单的方法(主要假设输入数据是有效的并且空白可忽略):

#include <vector>
#include <istream>
#include <iterator>

struct bigint
{
    std::vector<char> v; // or whatever representation you use (binary? bcd?)
};

std::istream& operator>>(std::istream& in, bigint& array)
{
    for (std::istream_iterator<char> f(in), l; f != l; ++f) {
        if (*f>='0' && *f<='9')
            array.v.push_back(*f - '0');
        else if (*f==';')
            break;
        else
            throw "invalid input";
    }

    return in;
}

#include <iostream>
#include <sstream>

int main()
{
    std::istringstream iss(
            "10000000000000000000000000000000000345;\n"
            "299793000000\n"
            "00000000000000000000067;\n"
            "4208574289572473098273498723475;\n"
            "28375039287459832728745982734509872340985729384750928734590827098752938723;\n"
            "99999999;  99999999;\n");

    bigint value;
    while (value.v.clear(), iss >> value)
        std::cout << "read " << value.v.size() << " digits\n";
}

在 Coliru 上看到它

于 2013-09-22T20:42:53.577 回答
2

这里有很多混乱。我只会列出一些要点,但即使你解决了这些问题,你也有一段路要走。

  1. 你到底在读什么?您说您正在读取一组数字,但您的代码说明了这一点

    std::istream& operator>>(std::istream& in, bigint array){
    

    我可能错了,但bigint对我来说听起来像是一个数字。我会期待这样的事情

    std::istream& operator>>(std::istream& in, std::vector<bigint>& array){
    
  2. 这将我带到第二点, operator>> 预计会修改它的第二个参数,这意味着它不能按值传递,您必须使用引用。换句话说,这是错误的

    std::istream& operator>>(std::istream& in, X x){
    

    但这没关系

    std::istream& operator>>(std::istream& in, X& x){
    
  3. 您正在尝试读取一个 bigint 数组,因此您需要一个循环(您有它),并且每次循环您都会读取一个 bigint。所以你需要一种方法来读取一个 bigint,你有吗?您的问题或代码中没有任何内容表明您有能力阅读 bigint,但这样做显然至关重要。因此,如果您还没有任何代码来阅读 bigint,那么在您拥有该代码之前,您可以忘记整个练习,因此首先进行该操作。当您可以读取一个 bigint 时,您才应该回到读取一组 bigint 的问题。

  4. 另一个棘手的部分是停止条件,当您阅读分号(可能前面有空格)时停止。因此,您需要一种方法来读取下一个非空格字符,并且至关重要的是如果它不是分号,您需要一种方法来取消它。所以你需要这样的东西

    if (!(in >> ch) || ch == ';')
    {
         // quit, either no more input, or the next char is a semicolon
         break;
    }
    
    in.putback(ch); // unread the last char read
    // read the next bigint
    

希望这可以帮助。

于 2013-09-22T20:44:22.273 回答