6

次のような入力ファイルがたくさんあります。

(8,7,15)
(0,0,1) (0,3,2) (0,6,3)
(1,0,4) (1,1,5)

これらの入力を一度に1つの数値で解析する関数を作成する必要があるため、入力を数値で区切ることができる必要があります。たとえば、8、7、15、0、0などです。

これまで考えてきた唯一の方法は、次の文字のASCIIコードを返すistream.get()を使用することです。これは、charにキャストすることで文字形式に戻すことができます。次に、文字が数字であるかどうかを確認します(したがって、角かっこは無視されます)が、このように、2桁(または3桁)の数字は一度に1桁しか読み取られません。

これを達成するための最良の方法は何でしょうか?

ちなみに、私はistreamを使わなければなりません。変更を許可されていないのは仕様の一部です

ありがとう

4

5 に答える 5

7

これは 1 つの解決策です。

struct integer_only: std::ctype<char> 
{
    integer_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        std::fill(&rc['0'], &rc['9'+1], std::ctype_base::digit);
        return &rc[0];
    }
};

int main() {
        std::cin.imbue(std::locale(std::locale(), new integer_only()));
        std::istream_iterator<int> begin(std::cin);
        std::istream_iterator<int> end;
        std::vector<int> vints(begin, end);
        std::copy(vints.begin(), vints.end(), std::ostream_iterator<int>(std::cout, "\n"));
        return 0;
}

入力:

(8,7,15)
(0,0,1) (0,3,2) (0,6,3)
(1,0,4) (1,1,5)

出力:

8 7 15 0 0 1 0 3 2 0 6 3 1 0 4 1 1 5 

オンラインデモ: http://ideone.com/Lwx9y

std::cin上記では、ファイルを正常に開いた後、次のようにファイル ストリームに置き換える必要があります。

 std::ifstream file("file.txt");
 file.imbue(std::locale(std::locale(), new integer_only()));
 std::istream_iterator<int> begin(file);
 std::istream_iterator<int> end;
 std::vector<int> vints(begin, end); //container of integers!

ここで、vintsはすべての整数を含むベクトルです。vintsあなたは何か役に立つことをするために一緒に働きたいと思っています。int*また、次のように期待される場所で使用できます。

void f(int *integers, size_t count) {}

f(&vints[0], vints.size()); //call a function which expects `int*`.

ファイルから単語のみを読み取る場合にも、同様のトリックを適用できます。次に例を示します。

于 2011-08-19T06:15:48.950 に答える
3

ここにいくつかのコードがあります。正確なニーズに合わせて調整できます

for (;;)
{
  int ch = in.get();
  if (ch == EOF)
    break;
  if (isdigit(ch))
  {
    int val = ch - '0';
    for (;;)
    {
      ch = in.get();
      if (!isdigit(ch))
        break;
      val *= 10;
      val += ch - '0';
    }
    // do something with val
  }
}

これはテストされていないコードです。

于 2011-08-19T06:14:45.543 に答える
2

別の解決策:

#include <string>
#include <ostream>
#include <fstream>
#include <iostream>

struct triple
{
    long a;
    long b;
    long c;
};

std::ostream& operator << (std::ostream& os, const triple& value)
{
    return os << value.a << "/" << value.b << "/" << value.c;
}

int main()
{
    std::ifstream stream("Test.txt");
    if (!stream)
    {
        std::cout << "could not open the file" << std::endl;
    }

    std::string dummy;
    triple value;
    while (std::getline(stream, dummy, '(') >> value.a &&
           std::getline(stream, dummy, ',') >> value.b &&
           std::getline(stream, dummy, ',') >> value.c)
    {
        std::cout << value << std::endl;
    }
}
于 2011-08-19T07:00:52.300 に答える
2

数字を読んでみてください。それが失敗した場合は、エラー状態をクリアし、読み取りを試みますchar(そして無視します)。char の読み取りが失敗するまで、これらの 2 つの手順を繰り返します。この場合、EOF または真の失敗になります。

')' を認識してから '(' まで読み取ることで最適化される場合があります。

しかし、私はそれが価値があるとは思わない。

乾杯 & hth.,

于 2011-08-19T06:15:24.970 に答える
1
int getFirstPos(const string& str)

{
int pos=0,PosHit=0;
bool bfind=false;
if((PosHit=str.find(','))!=string::npos){
    if(!bfind)  pos=PosHit;
    pos=pos>PosHit?PosHit:pos;
    bfind=true;
}
if((PosHit=str.find('('))!=string::npos){
    if(!bfind)  pos=PosHit;
    pos=pos>PosHit?PosHit:pos;
    bfind=true;
}
if((PosHit=str.find(')'))!=string::npos){
    if(!bfind)  pos=PosHit;
    pos=pos>PosHit?PosHit:pos;
    bfind=true;
}
return bfind?pos:string::npos;

}

void main()

{
    ifstream ifile("C:\\iStream.txt");
    string strLine;
    vector<double> vecValue;    //store the datas
    while(getline(ifile,strLine)){
        if(strLine.size()==0)
            continue;
        int iPos=0;
        while((iPos=getFirstPos(strLine))!=string::npos)
            strLine[iPos]=' ';
        istringstream iStream(strLine);
        double dValue=0;
        while(iStream>>dValue)
            vecValue.push_back(dValue);
    }
    //output the result!
    vector<double>::iterator it;
    for (it=vecValue.begin(); it!=vecValue.end()  ; ++it){
        cout<<setprecision(3)<<*it<<endl;
    }
}
于 2011-08-19T07:16:05.263 に答える