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

ここにはかなり多くの混乱があります。ポイントだけ挙げておきますが、これらを直せば何とかなります。

  1. 正確には何を読んでいますか?あなたは数字の配列を読んでいると言いますが、あなたのコードはこれを言っています

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

    私は間違っているかもしれませんが、bigint私には単一の数字のように聞こえます。私はこのようなものを期待します

    std::istream& operator>>(std::istream& in, std::vector<bigint>& array){
    
  2. operator>> は 2 番目の引数を変更することが期待されます。つまり、値で渡すことはできません。参照を使用する必要があります。つまりこれは間違っている

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

    でもこれでOK

    std::istream& operator>>(std::istream& in, X& x){
    
  3. bigint の配列を読み込もうとしているので、ループが必要で (それがあります)、ループを一周するたびに 1 つの bigint を読みます。1 つの bigint を読み取る方法が必要ですが、それはありますか? あなたの質問やコードには、bigint を読み取る能力があることを示すものは何もありませんが、そうすることが明らかに重要です。したがって、bigint を読み取るためのコードがまだない場合は、そのコードを取得するまでこの演習全体を忘れることができるので、最初にそれを実行してください。1 つの bigint を読み取ることができる場合にのみ、bigint の配列を読み取る問題に戻る必要があります。

  4. もう 1 つのトリッキーな部分は停止条件です。セミコロン (空白が前にある可能性があります) を読み取ると停止します。したがって、次の非スペース文字を読み取る方法が必要であり、決定的に、それがセミコロンではないことが判明した場合にそれを読み取る方法が必要です。だからあなたはこのようなものが必要です

    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 に答える
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 に答える