2

問題のあるコード:

#include <array>
#include <iostream>
#include <cstring>

int main(int argc, char *argv[])
{
    using namespace std;

    cout << "Read from file:" << endl;

    while (!cin.eof())
    {
        array<char, 16> l_array;
        cin.read(l_array.data(), l_array.size());
        cout.write(l_array.data(), cin.gcount());
    }

    cout << endl;
    cout << "Read from keyboard:" << endl;

    cin.rdbuf(cout.rdbuf());

    while (!cin.eof())
    {
        array<char, 64> l_array;
        memset(l_array.data(), 0, l_array.size());
        cin.read(l_array.data(), l_array.size());

        cout << "===== DATA =====" << endl;
        cout << l_array.data() << endl;
        cout << "================" << endl;
    }
}

これは私が私のプログラムを実行する方法です:

./application < file.txt

パイプからデータを問題なく読み取ることができますが、もう一度読み取りたい場合は、パイプに関連付けられています。どうやって元に戻すのかわかりません。変更できる「rdbuf」関数を見つけましたが、使い方がわかりません。

キーボードをファイルに切り替えてキーボードに戻るのをじっと見つめたときの例しか見つかりませんでした。

ここのように:http ://www.cplusplus.com/reference/iostream/ios/rdbuf/

しかし、私はstreambufを覚えていないので、彼らのようにそれを行うことはできません。ファイルからほとんどのデータを読み取ることができるプログラムを作成し、何かが不足している場合にのみ尋ねるか、実行時にユーザーに許可などについて尋ねたいと思います。Linuxのコンソール内のすべて。

@EDIT助けてくれてありがとう、私は解決策を投稿します

class RedirectCinToConsole
{
    protected:
        std::ifstream m_console;
        std::streambuf *m_oldCin;
        bool m_success;

    public:
        RedirectCinToConsole() :
            m_oldCin(0),
            m_success(false)
        {
            m_console.open("/dev/tty");

            if (m_console.is_open())
            {
                m_success = true;
                m_oldCin = std::cin.rdbuf(m_console.rdbuf());
            }
        }
        virtual ~RedirectCinToConsole()
        {
            if (m_oldCin)
            {
                std::cin.rdbuf(m_oldCin);
            }
            m_console.close();
        }

        operator bool () const { return m_success; }
};

int main()
{
    RedirectCinToConsole l_redirect;
    if (l_redirect)
    {
        std::string l_helloWorld;
        std::cin >> l_helloWorld;
        std::cin.ignore();

        std::cout << l_helloWorld;
    }
    return 0;
}
4

3 に答える 3

6

提案された解決策に関係なく、最も簡単な解決策(そしておそらく最良の解決策)は、逆のことをすることだと思います。入力をリダイレクトせずに、ファイル名をプログラムに渡してstd::ifstreamstd::cinインタラクティブな入力のために自由に保ちながら、それを読んでください。

Ben Voigtは標準のUnixソリューションを提案しましたが、それについて考えると、上記の方が自然なようです。それは確かに簡単で、よりポータブルです。

于 2012-08-28T18:13:43.050 に答える
3

おそらくfstream、独自のストリームを作成するために使用し、ファイル名を要求するか、コマンドラインパラメーターとしてファイル名を取得する必要があります。これによりcin、他の入力操作に使用できるようになります。

于 2012-08-28T17:31:58.333 に答える
0

開いてみてください/dev/tty。これは、プロセスに関連付けられているコンソール(存在する場合)になります。プロセスがデーモンから開始された場合、失敗する可能性があります。

于 2012-08-28T17:32:12.513 に答える