ホームページ >バックエンド開発 >C++ >C の `std::getline` でさまざまな行末を適切に処理する方法は?

C の `std::getline` でさまざまな行末を適切に処理する方法は?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-08 07:59:10807ブラウズ

How to Gracefully Handle Different Line Endings in C  's `std::getline`?

std::istream::getline でのさまざまな行末の適切な処理

テキスト ファイルを読み取るときに、'n などのさまざまな行末が発生する'、'r'、および 'rn' は問題を引き起こす可能性があります。 std::getline は入力ストリームから行を取得するのに便利な関数ですが、文字列の末尾に 'r' 文字が残る可能性があります。

Neil 氏が指摘したように、C ランタイムには通常、プラットフォームに基づいて行末規則を処理します。ただし、異なるシステム間の相互運用性には、より堅牢なアプローチが必要です。

3 つの行末タイプすべてをシームレスに処理するカスタマイズされた関数を次に示します。

std::istream& safeGetline(std::istream& is, std::string& t)
{
    t.clear();

    std::istream::sentry se(is, true);
    std::streambuf* sb = is.rdbuf();

    for(;;) {
        int c = sb->sbumpc();
        switch (c) {
        case '\n':
            return is;
        case '\r':
            if(sb->sgetc() == '\n')
                sb->sbumpc();
            return is;
        case std::streambuf::traits_type::eof():
            if(t.empty())
                is.setstate(std::ios::eofbit);
            return is;
        default:
            t += (char)c;
        }
    }
}

この関数では、streambuf オブジェクトを利用して、文字を 1 文字ずつ効率的に読み取ります。各文字が検査され、そのタイプに基づいて、行末を処理するための適切なアクションが実行されます。

サンプル テスト プログラムは、safeGetline の使用法を示しています。

int main()
{
    std::string path = ... // Insert path to test file here

    std::ifstream ifs(path.c_str());
    if(!ifs) {
        std::cout << "Failed to open the file." << std::endl;
        return EXIT_FAILURE;
    }

    int n = 0;
    std::string t;
    while(!safeGetline(ifs, t).eof())
        ++n;
    std::cout << "The file contains " << n << " lines." << std::endl;
    return EXIT_SUCCESS;
}

このアプローチを採用することで、さまざまな起源のテキスト ファイルを自信を持って読み取ることができ、さまざまな行末を適切に処理できます。

以上がC の `std::getline` でさまざまな行末を適切に処理する方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。