4

我一直在谷歌搜索并阅读我的书,并尝试编写代码来阅读文本文件并逐个处理其中的单词,这样我就可以按字母顺序排列它们并计算有多少单词在哪里使用,并且使用了很多词。我似乎无法让我的 GetNextWord() 函数正常工作,这让我发疯。

我需要一个接一个地阅读单词,如果每个字母是大写的,则将其转换为小写。我知道如何做到这一点,并且已经成功地做到了。它只是逐个字符地获取单词并将其放入阻止我的字符串中。

这是我最近的一次尝试:任何帮助都会非常棒,或者提供有关如何逐字读取输入文件的教程的链接。(单词是字母字符 az 和 '(不要)以空格、逗号、句点、;、: 等结尾。

void GetNextWord()
{
    string word = "";
    char c;

    while(inFile.get(c))
    {
        while( c > 64 && c < 123 || c == 39)
        {
            if((isupper(c)))
            {
                c = (tolower(c));
            }
            word = word + c;
        }
        outFile << word;
    }
}
4

5 回答 5

8

您可以使用运算符逐字读取文件>>。例如,请参阅此链接:http ://www.daniweb.com/forums/thread30942.html 。

我在这里摘录了他们的例子:

ifstream in ( "somefile" );
vector<string> words;
string word

if ( !in )
  return;

while ( in>> word )
  words.push_back ( word );
于 2010-09-15T04:27:17.920 回答
3

你的逻辑是错误的。内部循环只要c不改变就会运行,并且其中没有任何东西会改变c

为什么你有两个循环呢?我想你可能会对这个函数是应该读取下一个单词还是所有单词感到困惑。尝试将这些问题分开,将它们放入不同的函数中(其中一个正在调用另一个)。我发现以自上而下的顺序处理此类问题最容易:

while(inFile.good()) {
  std::string word = GetNextWord(inFile);
  if(!word.empty())
    std::cout << word << std::endl;
}

GetNextWord()现在通过定义读取所有内容到下一个单词边界来填补空白。

于 2010-09-15T08:24:50.657 回答
0

std::getline(std::istream&, std::string&)就我个人而言,我喜欢用(在<string>标题中,但您当然还需要#include一个流标题)来读取输入。

此函数在换行符处中断,根据您的问题定义,换行符是空格。但这不是您问题的全部答案。读入文本行后,您将需要使用字符串操作或标准算法将字符串分解为单词。或者你可以手动循环字符串。

胆量是这样的:

std::string buffer;
while (std::getline(std::cin, buffer) {
// break each line into words, according to problem spec
}
于 2010-09-15T07:52:41.353 回答
0

我用

// str is a string that holds the line of data from ifs- the text file.
// str holds the words to be split, res the vector to store them in.
while( getline( ifs, str ) ) 
    split(str, res);


void split(const string& str, vector<string>& vec)
{
    typedef unsigned int uint;

    const string::size_type size(str.size());
    uint start(0);
    uint range(0);

 /* Explanation: 
  * Range - Length of the word to be extracted without spaces.
  * start - Start of next word. During initialization, starts at space 0.
  * 
  * Runs until it encounters a ' ', then splits the string with a substr() function,
  * as well as making sure that all characters are lower-case (without wasting time
  * to check if they already are, as I feel a char-by-char check for upper-case takes
  * just as much time as lowering them all anyway.                                       
 */
    for( uint i(0); i < size; ++i )
    {
        if( isspace(str[i]) )
        {
            vec.push_back( toLower(str.substr(start, range + 1)) );
            start = i + 1;
            range = 0;
        } else
            ++range;
    }
    vec.push_back( toLower(str.substr(start, range)) );
}

我不确定这对您是否特别有帮助,但我会尝试。toLower 函数是一个快速函数,它只使用 ::toLower() 函数。这会读取每个字符直到一个空格,然后将其填充到一个向量中。我不完全确定你对 char by char 的意思。

你想一次提取一个单词字符吗?或者您想在进行过程中检查每个字符?或者你的意思是你想提取一个词,完成,然后回来?如果是这样,我会 1) 无论如何推荐一个向量,以及 2) 让我知道,以便我可以重构代码。

于 2010-09-15T07:57:35.437 回答
0

如果 c == 'a',什么会终止你的内部循环?“a”的 ASCII 值为 97。

于 2010-09-15T08:01:59.213 回答