使用 ifstream 计算单词的出现次数

using ifstream to count the appearance of a word

本文关键字:ifstream 计算 单词 使用      更新时间:2023-10-16

我从C++ Primer(第5版,Stanley B.Lippman)中读到了这段代码此代码用于计算文件中字母出现的时间。

我想知道主函数的2个参数的功能以及,什么是infile.open(argv[1],infile)

另外,infile.open()的参数不能是常量吗?如果没有,如何更改要从控制台读取而不是从源代码读取的文件。这是代码:

//enter code here
void runQueries(ifstream &infile)
{
    // infile is an ifstream that is the file we want to query
    TextQuery tq(infile);  // store the file and build the query map
    // iterate with the user: prompt for a word to find and print results
    while (true) {
         cout << "enter word to look for, or q to quit: ";
         string s;
         // stop if we hit end-of-file on the input or if a 'q' is entered
         if (!(cin >> s) || s == "q") break;
         // run the query and print the results
         print(cout, tq.query(s)) << endl;
         }
}
// program takes single argument specifying the file to query
//enter code here 
int main(int argc, char **argv)
{
    // open the file from which user will query words
    ifstream infile;
    // open returns void, so we use the comma operator XREF(commaOp) 
    // to check the state of infile after the open
    if (argc < 2 || !(infile.open(argv[1]), infile)) {
        cerr << "No input file!" << endl;
        return EXIT_FAILURE;
    }
    runQueries(infile);
    return 0;
}

我想知道主函数的2个参数的功能

它们分别是参数数(int argc)和指向参数的指针数组(const char* argv[])。

请注意,const char* argv[]const char** argv 是等价的,但我认为前者更容易阅读。

argv[0]通常包含运行程序的可执行文件的名称。

在您的情况下,程序期望第二个参数 argv[1] 是要打开的文件的路径。

<小时 />

例如,如果按如下方式运行程序:

$ myprogram file.txt

然后

argc == 2
argv[0] == "myprogram"
argv[1] == "file.txt"
<小时 />

什么是infile.open(argv[1],infile)

这不是它的拼写方式。它实际上是(infile.open(argv[1]), infile).这是打开文件并检查它是否正确打开的有点复杂的方式(在注释中解释)。这可以重写为:

if (argc >= 2) {
    infile.open(argv[1]);
    if (!infile) {
        //handle error
    }
} else {
    // handle error
}

但如您所见,这需要在两个地方使用错误处理。

<小时 />

坦率地说,我个人不会这样写:

if (argc < 2)
    throw std::runtime_exception("Requires a filename");
ifstream infile(argv[1]); // at this point we can safely assume we can dereference argv[1]
if (!infile)
    throw std::runtime_exception ("Cannot open file");

如果我没记错的话,这本书在后面的阶段引入了异常处理,所以你现在不必改变这一切。

<小时 />

另外,infile.open() 的参数不能是常量吗?

如果一个函数需要一个const的参数,你也可以向它传递一个非常量参数(引用除外)。但是,您已经从控制台读取文件名(标准输入),所以我在这里看不到问题。