【问题标题】:How Do I read and Output the Contents of a File and the Number of Words it Contains?如何读取和输出文件的内容及其包含的字数?
【发布时间】:2019-11-22 17:05:46
【问题描述】:

我正在尝试为家庭作业编写一个程序,该程序读取记事本文件的内容并显示文件中的内容和字数。当我输入用于测试程序的文件的名称时,我的代码当前没有输出任何内容,并且我插入的输入验证 while 循环也不起作用。

#include <iostream>
#include <fstream>
using namespace std;

int main()
{
//Declare needed variables
string fileName, contents;

int wordCount = 0;
ifstream inData;

//Display program info
cout << "*** A SIMPLE FILE PROCESSING PROGRAM ***" << endl;

//Prompt user input
cout << "Enter a filename or type quit to exit: ";
cin >> fileName;

inData.open(fileName.c_str());

//Inform the user when their input is invalid and ask them to input another 
file name
while (!inData)
{
    inData.clear();
    inData.ignore(200, '\n');
    cout << "File not found. Please type a correct file name." << endl;
    cin >> fileName;
    inData.open(fileName.c_str());
}

inData >> contents;

//Read and output the contents of the selected file
while (inData)
{
    cout << fileName << " data\n";
    cout << "***********************" << endl;
    inData >> contents;
    wordCount++;
    cout << contents << endl;
    inData >> contents;
}

//Display the number of words in the file
cout << "***********************" << endl;
cout << fileName << " has " << wordCount << " words." << endl;

inData.close();

return 0;
}

代码在其当前状态下编译 [但不会产生预期的结果。

【问题讨论】:

  • 编译仅仅意味着它在语法上是正确的,而不是它在逻辑上是正确的。在调试器中单步调试代码将帮助您弄清楚为什么它没有按预期工作。
  • why while (!inData.eof()) is wrong。此外,ifstream 函数与std::string 一起工作得很好,无需使用c_str。当流超出范围时,流析构函数将自动关闭文件,因此您不必显式关闭它。你认为这个循环有什么作用? while (fileName != "quit")ericlippert.com/2014/03/05/how-to-debug-small-programs

标签: c++ file while-loop


【解决方案1】:

我将向您展示众多可能的解决方案之一。

但我不建议在循环中检查文件名的有效性。你会让用户没有机会逃脱。因此,我建议打开该文件,如果这不起作用,则显示错误消息并退出。

那么,一开始听起来很容易的事情,数一下单词,并不是那么容易。什么是词?仅字符,还是与数字混合的字符,甚至像 C++ 变量名中的下划线?需要定义。

此外,您可能还有逗号等分隔符或一个或多个其他空格。所以像"Hello,,,,World" 这样的行不能这么容易计算。如果您尝试阅读这两个单词,那么您会看到一个惊喜。

    std::string s1{};
    std::string s2{};
    std::istringstream iss("Hello,,,,World");
    iss >> s1 >> s2;

将读取 s1 中的所有内容!

解决方案是我们清楚地定义一个词是什么。我们将使用std::regex 来实现这一点。在下面的示例中,我们使用字符、数字和 _

然后我们使用 regex_iterator 来查找该行中所有出现的正则表达式(单词)。我们用std::distance从开头减去结尾,这将给我们字数。

然后我们以任何格式向用户提供输出。

这可能看起来很复杂。但它是精确的。而且相当灵活。试着逐行分析,你就会明白了。

请看:

#include <iostream>
#include <string>
#include <regex>
#include <fstream>
#include <iomanip>

int main()
{
    // Get a filename from the user
    std::cout << "Enter a filename:\n";
    std::string filename{};  std::cin >> filename;

    // Try to open and read the file
    std::ifstream fileStream(filename);
    if (fileStream) {
        // We will count all words
        size_t numberOfWordsOverall{ 0 };

        // We will also count the lines in the file
        size_t lineCounter{ 1 };

        // Define, what a word is. In this case: Characters, Digits and _
        std::regex regexForWord("[\\w\\d_]+");

        // Read all lines in file
        std::string line{};
        while (std::getline(fileStream, line)) {

            // Count the numbers of words in one line
            const size_t numberOfWordsInLine = std::distance(
                std::sregex_token_iterator(line.begin(), line.end(), regexForWord, 1),
                std::sregex_token_iterator()
            );
            // Update the overall word counter
            numberOfWordsOverall += numberOfWordsInLine;

            // Show result to user
            std::cout << "# " << std::left << std::setw(2) << lineCounter++ << "   (Words in line: "<< std::setw(2) << numberOfWordsInLine <<
                " Words overall: " << std::setw(4) << numberOfWordsOverall << ")  Line content --> " << line << '\n';
        }
    }
    else {
        std::cerr << "Could not open file '" << filename << "'\n";
    }
    return 0;
}

希望这会有所帮助。 . .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2014-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多