web-dev-qa-db-ja.com

C ++ ifstream抽出演算子>>を使用して、ファイルからフォーマット済みデータを読み取る

私の学習として、私は以下のコードを使用してテキストファイルからデータを読み取るためにc ++ ifstreamとその演算子>>を使用しようとしています。テキストファイルoutdummy.txtの内容は次のとおりです。

just dummy
Hello ofstream
555

私の質問は、ファイルに存在するcharデータをchar配列または文字列に読み取る方法です。以下のコードでifstream :: operator >>を使用してこれを行う方法。

#include <iostream>
#include <fstream>

int main()
{
    int a;
    string s;
    char buf[100];
    ifstream in("outdummy.txt",ios_base::in);


    in.operator>>(a); //How to read integer? How to read the string data.??

    cout << a;

    in.close();
    getchar();
    return 0;
}
12
goldenmean

書式設定された入力を使用する場合は、事前にどのデータを予期し、それを対応するデータ型の変数に読み込む必要があります。たとえば、例のように、番号が常に5番目のトークンであることがわかっている場合は、次のようにすることができます。

std::string s1, s2, s3, s4;
int n;

std::ifstream in("outdummy.txt");

if (in >> s1 >> s2 >> s3 >> s4 >> n)
{
  std::cout << "We read the number " << n << std::endl;
}

一方、番号が常に3行目にあることを知っている場合は、次のようになります。

std::string line;

std::getline(in, line);  // have line 1
std::getline(in, line);  // have line 2
std::getline(in, line);  // have line 3

std::istringstream iss(line);

if (iss >> n)
{
  std::cout << "We read the number " << n << std::endl;
}

ご覧のとおり、トークンを文字列として読み取るには、トークンをstd::stringにストリーミングするだけです。フォーマットされた入力演算子はトークンごとに機能し、トークンは空白(スペース、タブ、改行)で区切られていることを覚えておくことが重要です。通常行う基本的な選択は、ファイルを完全にトークンで処理するか(最初のバージョン)、または行ごとに処理するか(2番目のバージョン)です。行ごとの処理では、最初にgetlineを使用して1行を文字列に読み取り、次に文字列ストリームを使用して文字列をトークン化します。


検証についての言葉:フォーマットされた抽出が実際に成功するかどうかはわかりません。これは入力データに依存するためです。したがって、常に入力操作が成功したかどうかを確認し、失敗した場合は解析を中止する必要があります。失敗した場合、変数には正しいデータが含まれませんが、後でそれを知っています。常に次のように言ってください:

if (in >> v) { /* ... */ }            // v is some suitable variable
else { /* could not read into v */ }

if (std::getline(in, line)) { /* process line */ }
else { /* error, no line! */ }

後者の構成は通常、whileループで使用され、ファイル全体を1行ずつ読み取ります。

while (std::getline(in, line)) { /* process line */ }
15
Kerrek SB
  1. ifstreamにはデフォルトで_ios_base::in_があります。指定する必要はありません。
  2. _operator>>_は、演算子として直接呼び出すことができます:_in >> a_。
  3. 文字列の読み取りは同じです:_in >> s_、ただし、空白で区切られているため、「ダミー」なしでそれ自体が「ただ」読み取られることに注意してください。
  4. 完全な行を読みたい場合は、std::getline(in, s)を使用します。
2
Marcelo Cantos

C文字列を使用することを選択したので、ifstreamオブジェクトの getline メソッドを使用できます(std::stringsで機能するstd::getline()ではありません)。これにより、C文字列とバッファの最大サイズを指定できます。

あなたが持っていたものに基づいて、そして2行目の追加のバッファを追加します:

char buf[100];
char buf2[100];

in.getline(buf,sizeof(buf));
in.getline(buf2,sizeof(buf2));
in >> a;

ただし、他の投稿者が提案したように、std::stringとそのメソッドを使用してみてください。

1
jonsca

ファイルの内容を読み取り、解析に Finite State Machine を使用できます。

例:

void Parse(const char* buffer, size_t length);
size_t GetBufferSize();

size_t bufferSize = GetBufferSize();
char* buffer = new char[bufferSize];

std::ifstream in("input.txt");
while(in.getline(buffer, bufferSize)) {
    Parse(buffer, in.gcount());
}

または、 Flex のようなツールを使用してパーサーを作成することもできます。

0
npclaudiu