C++ 在将文本文件读取为字符串时,如何忽略文本文件中的符号/数字

C++ How can I ignore symbols/numbers in a text file when reading it into a string?

本文关键字:文本 文件 何忽略 符号 数字 读取 C++ 字符串      更新时间:2023-10-16

我正在做一个项目,我需要制作一个单词计数器来计算文本文件中的唯一单词。在课堂上,我们刚刚了解了STL,我们应该使用地图来制作程序。我从文件中读到的单词并准确计算它们,除了它不会忽略我需要它做的符号或数字。例如,就像现在一样,它将单词"file"和"file."计为两个单独的单词。我该如何解决这个问题?我遇到的另一个问题是单词应该按字母顺序打印。这就是我到目前为止所拥有的。

#include <iostream>
#include <map>
#include <fstream>
#include <string>
using namespace std;
template <class words, class counter>
void PrintMap(map<words, counter> map)
{
    typedef std::map<words, counter>::iterator iterator;
    for (iterator p = map.begin(); p != map.end(); p++)
    cout << p->first << ": " << p->second << endl;
}
int main()
{
    static const char* fileName = "D:\MyFile.txt";
    map<string, int> wordCount;
    {
        ifstream fileStream(fileName);
        if (fileStream.is_open())
            while (fileStream.good())
            {
                string word;
                fileStream >> word;
                if (wordCount.find(word) == wordCount.end())
                    wordCount[word] = 1;
                else
                    wordCount[word]++;
            }
        else 
        {
            cerr << "Couldn't open the file." << endl;
            return EXIT_FAILURE;
        }
        PrintMap(wordCount);
    }
    system("PAUSE");
    return 0;
}

原则上,Jake Killpack的回答是正确的。您可以读取字符串,然后对其进行修剪,也可以调整C++中读取字符串的行为。根据文档:

[ operator >> ] [...] 然后从 is 中读取字符并将它们附加到 str 中,就像 str.append(1, c),直到满足以下条件之一:

  • [...]
  • std::isspace(c,is.getloc()) 对于 is 中的下一个字符 c 为真(此空格字符保留在输入流中)。

显然,标点符号不是空格,因此它们也被阅读并添加到单词中。要改变这一点,你必须调整std::isspace的行为,它将标点符号视为空格,这是可以做到的,即使它很尴尬:

struct punctws_ctype : std::ctype<char> {
    static const mask* table() {
        static std::vector<mask> v(classic_table(), classic_table() + table_size);
        v[','] |= space; // classify comma as whitespace
        v['.'] |= space; // accordingly...
        v['-'] |= space;
        return &v[0];
    }
    my_ctype(std::size_t refs = 0) : std::ctype<char>{ table(), false, refs } { } 
};

稍后,在您阅读直播之前:

// apply the modified behaviour to the stream:
fileStream.imbue(std::locale{ fileStream.getloc(), new my_ctype });

现在,当阅读时 fileStream >> word ,它会立即去除任何标点符号。

在wordCount字典中检查之前,您可以编写一个单独的函数来删除每个字符串中不需要的符号。例如,在你读了一个新单词后,你可以运行一个小的修剪函数,逐个字符地穿过单词,看看是否有任何字符==一个'.'或'-'等。