Я написал программу c++, которая может получать информацию из файла, но она должна поддерживать два способа чтения данных.
Первый способ - передать имя файла в качестве параметра командной строки: ./a.out a.txt
Второй - это чтение из трубы: cat a.txt |./a.out
cat a.txt |./a.out
Второй путь более важен и сложнее для меня. Как это можно сделать?
Вот подробности о моем вопросе:
Существует класс, который я определил следующим образом:
class API_EXPORT SamReader {
// constructor / destructor
public: SamReader (void); ~ SamReader (недействительными);
// closes the current SAM file
bool Close(void);
// returns filename of current SAM file
const std::string GetFilename(void) const;
// return if a SAM file is open for reading
bool IsOpen(void) const;
// opens a SAM file
// *** HERE IS MY QUESTION
bool Open(const std::string& filename);
bool Open(std::istream cin); //HERE~~~~
// retrives next available alignment
bool LoadNextAlignment(BamAlignment& alignment);
private: Internal :: SamReaderPrivate * d; };
У меня есть способ ввода файла и получения результата. Но мне нужно добавить func в этот класс, чтобы он мог вводить из stdin...
Спасибо за помощь, я здесь новый парень, и я очень ценю людей, которые сейчас помогают мне.
Чтобы читать из трубы, ваша программа просто должна быть прочитана из stdin. То, как работает труба в оболочке, если вы запустите a | b
a | b
, он просто передает весь вывод на stdout of a
stdin из b
.
Таким образом, в основном ваша программа должна охватывать 2 случая: (1) читать из файла, если он предоставлен, и (2) читать с stdin в противном случае.
Чтобы избежать повторения кода, самый простой способ всегда считывается из stdin. Это, очевидно, будет охватывать (2). Чтобы охватить (1), когда файл предоставляется как параметр, используйте freopen
для переопределения stdin с этим файлом.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char** argv) {
if (argc > 1) {
freopen(argv[1], "r", stdin);
}
string s;
while (cin >> s) {
cout << s << endl;
}
return 0;
}
Демонстрируя, как это работает
$ g++ test.cc
$ cat content
This
is
a
test
$ ./a.out content
This
is
a
test
$ cat content | ./a.out
This
is
a
test
std::istream
(или из FILE*
, хотя обычно это не очень хорошая идея).
Так же, как @Sander De Dycker сказал. Это ни один программный бизнес. это зависит от оболочки, которую вы используете, я думаю, вы используете классический sh.
Вы можете написать очень простую программу c++, такую как:
#include <string>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<string> v;
string s;
while (cin >> s)
v.push_back(s);
for (int i = 0; i != v.size(); ++i)
cout << v[i] << endl;
return 0;
}
то вы можете ввести ./a.out a.txt
для использования a.txt
качестве вывода или типа cat a.txt |./a.out
cat a.txt |./a.out
для использования a.txt
качестве входных данных. или вы также можете смешивать эти две команды.
./a.out > a.txt
. Для ввода ./pgm < in.txt
проще IMO. Оба могут быть смешаны. (Ну, точный синтаксис для перенаправления зависит от используемой вами оболочки ... но здесь мы будем использовать классический sh.)
std::cin
либо из файла, указанного параметром командной строки."-"
).