[英]Reading from text file or stdin
我有一個程序,它基本上讀取一個文本文件並計算每行每個單詞的出現次數。 使用 ifstream 從文本文件讀取時一切正常,但是,如果未在命令行中輸入文件名,則需要從 stdin 讀取。
我當前使用以下命令打開和讀取文件:
map<string, map<int,int>,compare> tokens;
ifstream text;
string line;
int count = 1;
if (argc > 1){
try{
text.open(argv[1]);
}
catch (runtime_error& x){
cerr << x.what() << '\n';
}
// Read file one line at a time, replacing non-desired char's with spaces
while (getline(text, line)){
replace_if(line.begin(), line.end(), my_predicate, ' ');
istringstream iss(line);
// Parse line on white space, storing values into tokens map
while (iss >> line){
++tokens[line][count];
}
++count;
}
}
else{
while (cin) {
getline(cin, line);
replace_if(line.begin(), line.end(), my_predicate, ' ');
istringstream iss(line);
// Parse line on white space, storing values into tokens map
while (iss >> line){
++tokens[line][count];
}
++count;
}
有沒有辦法將 cin 分配給 ifstream 並在 argc > 1 失敗時簡單地添加一個 else 語句,然后使用相同的代碼而不是像這樣重復? 我一直無法找到一種方法來做到這一點。
使閱讀部分成為它自己的功能。 將ifstream
或cin
傳遞給它。
void readData(std::istream& in)
{
// Do the necessary work to read the data.
}
int main(int argc, char** argv)
{
if ( argc > 1 )
{
// The input file has been passed in the command line.
// Read the data from it.
std::ifstream ifile(argv[1]);
if ( ifile )
{
readData(ifile);
}
else
{
// Deal with error condition
}
}
else
{
// No input file has been passed in the command line.
// Read the data from stdin (std::cin).
readData(std::cin);
}
// Do the needful to process the data.
}
您不能將 cin 分配給 ifstream。
但是你可以重新打開 cin 到某個文件。
無論如何,更好的方法是模塊化您的代碼並僅使用std::istream&
。
我只是提出了一個簡單的方法讓程序讀取文件,如果給定其他使用標准輸入,並正確關閉它。
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
int main(int argc, char* argv[]) {
auto fp_deletor = [](std::istream* is_ptr) {
if (is_ptr && is_ptr != &std::cin) {
static_cast<std::ifstream*>(is_ptr)->close();
delete is_ptr;
std::cerr << "destroy fp.\n";
}
};
std::unique_ptr<std::istream, decltype(fp_deletor)> is_ptr{nullptr, fp_deletor};
if (argc > 2) {
std::cerr << "usage: " << argv[0] << "[input-file]";
return -1;
} else if (argc == 1) {
std::cerr << "using stdin as input.\n";
is_ptr.reset(&std::cin);
} else {
is_ptr.reset(new std::ifstream(argv[1]));
}
std::string line;
while (std::getline(*is_ptr, line)) {
// your logic....
}
// just return, unique_ptr manage the istream
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.