【问题标题】:How to make sure the words being read in from the file are how I want them to be C++如何确保从文件中读取的单词是我希望它们成为 C++ 的方式
【发布时间】:2016-09-02 04:27:57
【问题描述】:

如果我必须从文档中读取一个单词(一次一个单词),然后将该单词传递给一个函数,直到到达文件末尾,我该怎么做?

还必须记住的是,单词是任何连续的字母串和撇号(所以can'trojas' 是一个单词)。像bad-day 这样的东西应该是两个单独的词,像to-be-husband 这样的东西应该是三个单独的词。我还需要忽略句点.、分号;,以及几乎所有不属于单词的内容。我一直在使用file >> s; 阅读它,然后从字符串中删除内容,但它变得非常复杂。有没有办法只将字母字符+撇号存储到s 并在单词末尾停止(出现空格时)?

while (!file.eof()) {

   string s;
   file >> s;  //this is how I am currently reading it it
   passToFunction(s);    
}

【问题讨论】:

标签: c++ string file io fstream


【解决方案1】:

流的OnlyLetterNumAndApp facet

#include <locale>
#include <string>
#include <fstream>
#include <iostream>

// This facet treats letters/numbers and apostrophe as alpha
// Everything else is treated like a space.
//
// This makes reading words with operator>> very easy to sue
// when you want to ignore all the other characters.
class OnlyLetterNumAndApp: public std::ctype<char>
{
    public:
        typedef std::ctype<char>    base;
        typedef base::char_type     char_type;

        OnlyLetterNumAndApp(std::locale const& l)
            : base(table)
        {
            std::ctype<char> const&  defaultCType  = std::use_facet<std::ctype<char> >(l);

            for(int loop = 0;loop < 256;++loop) {
                table[loop] = (defaultCType.is(base::alnum, loop) || loop == '\'')
                     ? base::alpha
                     : base::space;
            }
        }
    private:
        base::mask  table[256];
};

用法

int main()
{
     std::ifstream  file;
     file.imbue(std::locale(std::locale(), new OnlyLetterNumAndApp(std::locale())));
     file.open("test.txt");

     std::string word;
     while(file >> word) {
         std::cout << word << "\n";
     }
}

测试文件

> cat test.txt
This is %%% a test djkhfdkjfd
try another $gh line's
bad-people.Do bad things

结果

> ./a.out
This
is
a
test
djkhfdkjfd
try
another
gh
line's
bad
people
Do
bad
things

【讨论】:

    【解决方案2】:

    是的,有一种方法:只需编写代码即可。一次读取一个字符,并收集字符串中的字符,直到获得一个非字母、非撇号字符。你现在已经读了一个字。等到你读到下一个字母或撇号的字符,然后从顶部取出它。

    另一件事:

    while (!file.eof())
    

    这是always a bug, and a wrong thing to do。只是想我会提到这一点。我想在编写其余代码之前,解决这个问题将是您的首要任务。

    【讨论】:

    • 您好,感谢您的回复。我使用您描述的方法修复了它并在上面进行了编辑。我上面做的有意义吗?我对结尾部分if (s.size() != 0) passToFunction(s); 有点不确定。我这样做是因为我不想传入一个空字符串,如果说当前读取的字符是一个数字。
    • s.size() 部分很好,但我相信您的代码有错误。如果文件中的最后一个字符是字母或撇号(文件不以换行符或任何其他字符结尾),在我看来,您的代码将进入无限循环,并最终耗尽内存。
    • 我也测试了它,它没有考虑单词之间的空格。编辑:我将其更改为 file.get(c);现在可以了
    • 谢谢,我去看看
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多