2011-01-22 4 views
8

私は、この形式の行の完全なファイルを持っている:C++ストリームを使ってエレガントに整数を読み込むには?

1 - 2: 3 

私はC++のストリームを使用した唯一の負荷番号にしたいです。それを行う最もエレガントな方法は何ですか?私はcin.get()について考えていたし、数字であれば各文字をチェクインする。

答えて

5

だから、あなたもこれを読むことができますそれが読み込まれるときにファイルから読み取られるものは何か。あなたがファイルを読み込むときに、あなただけの数字を残しながら、それはスペースにすべての非数字を変換します

struct numeric_only: std::ctype<char> 
{ 
    numeric_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[':'], std::ctype_base::digit); 
     return &rc[0]; 
    } 
}; 

std::fstream myFile("foo.txt"); 
myfile.imbue(std::locale(std::locale(), new numeric_only())); 

:それはあなたがすべての数値以外の値を除外します、です。その後、単純に通常の変換を使用して、読み込まれているものをintに変換することができます。以下のコメントへ

std::vector<int> intFromFile; 
std::istream_iterator<int> myFileIter(myFile); 
std::istream_iterator<int> eos; 
std::copy(myFileIter, eos, std::back_inserter(intFromFile)); 

応答:ここ

が、私はそれが

int main(int args, char** argv){ 
    std::fstream blah; 
    blah.open("foo.txt", std::fstream::in); 
    if(!blah.is_open()){ 
     std::cout << "no file"; 
     return 0; 
    } 
    blah.imbue(std::locale(std::locale(), new numeric_only())); 

    std::vector<int> intFromFile; 
    std::istream_iterator<int> myFileIter(blah); 
    std::istream_iterator<int> eos; 
    std::copy(myFileIter, eos, std::back_inserter(intFromFile)); 

    return 0; 
} 

を動作させるためにやったことではありません、これはベクターにだけint型を入れ、より多くの何も、何ももっと少なく。私は自分自身を「9」までの充填ではなく、「9」た

  1. :それは前に働いていなかった理由は2倍でした。塗りつぶしを ':'に変更しました
  2. intが保持できる数よりも大きな数字が問題になります。私はロングを使用することをお勧めします。
+0

私はそれを試した。それは動作していないようです。 – Nawaz

+0

@Nawaz ok、私のコンパイラを起動し、私が間違っていた箇所を見てください。 – wheaties

+0

@ wheaties:ところで、あなたがそれを動作させるなら、アイデアは本当に良いです。私はそれが働いているのが大好きです。 :-) – Nawaz

1
int a,b,c; 

    cin >> a; 
    cin.ignore(100,'-'); 
    cin >> b; 
    cin.ignore(100,':'); 
    cin >> c; 

    cout << "a = "<< a <<endl; 
    cout << "b = "<< b <<endl; 
    cout << "c = "<< c <<endl; 

入力:

1 - 2:3

出力:

= 1
B = 2
C = 3

は、ここに自分自身を参照してください:http://www.ideone.com/DT9KJ

注:これはまた、余分なスペースを扱うことができます。

 1  -  2  :  3

同様のトピック:

あなたがCHに localeを使用することができます

Using ifstream as fscanf

+3

は、あなたのコード内のマジックナンバーを警戒非常に*すること。彼らはあなたをかむために戻ってきます。 –

+0

@Konrad:あなたは 'ignore()'の '100'について話していますか?余分なスペースがあると思うどんな大きな数字にでもそれを増やすことができます! – Nawaz

+3

することはできますが、そうしてはいけません。それは本当に何も変わらない。もしあれば 'numeric_limits :: max()'を使うべきです。 –

0

単に、

ifstream file("file.txt"); 
int n1, n2, n3; 
char tmp; 
while (file.good()) { 
    file >> n1 >> tmp >> n2 >> tmp >> n3; 
} 
+0

たとえば、n1またはn2に数値コンポーネントがない場合、n3を抽出できません。 –

2

これを読むとき、私は、少なくとも一遍健全性チェックを行うことをお勧めします:

int a, b, c; 
char dash, colon; 

if (not (cin >> a >> dash >> b >> colon >> c) or dash != '-' or colon != ':') 
    Failure. Do something. 
0

申し訳コンラートが、私はお勧め:決しての痛みに、決して決して決して(はっきりしていますか?:-)ファイルから書式設定されたデータを読み込みます。ただしないでください。

フォーマットされたデータを入力する正しい方法は1つだけです。文字のチャンクを読み込みます(通常は行ですが、固定長ブロックも読み込むことができます)。

入力テキストを解析します。あなたは大雑把なチェックを行うつもりはない、フォーマットエラーを捕まえることを保証するパーサーを使用し、そのエラーを分かりやすい方法で報告し、適切な処置(終了、行をスキップして何でも)を実行する。

入力(I/O操作)と解析を分離します。

市販のプログラマーとしての数十年の経験から、この形式の入力を読むことは、ミッキーマウスの主体プルーフ・オブ・プリンシパル・プログラム用です。ファイルの作成を独占的に制御しても、常に解析してエラーをチェックして報告します。結局のところ、変更はありますが、それは今日ではなく、明日ではないかもしれません。

私は何十年もC++を書いてきましたが、決して整数を読んだことはありません。

7

私はこの1つは、最速の-yet elegant-の方法だろうと思う:

int a, b, c; 
scanf("%d-%d:%d", &a, &b, &c); 
関連する問題