阅读文本文件

时间:2013-09-22 20:08:10

标签: c++ arrays text-files

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

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;

每个新数组在到达";'时停止。白色空间和终结点也让我感到困惑。任何帮助将不胜感激,谢谢。

2 个答案:

答案 0 :(得分: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";
}

查看 Live on Coliru

答案 1 :(得分:2)

这里有很多混淆。我只列出一些要点,但即使你解决了这些问题,也有办法。

  1. 你究竟在读什么?你说你正在阅读一系列数字,但你的代码说明了这个

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

    我可能错了,bigint听起来像是一个号码。我希望这样的事情

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

    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
    
  5. 希望这有帮助。