1

我正在尝试编写一个程序来读取文本文件,计算每个唯一单词,然后对唯一单词列表进行排序并列出每个单词的出现次数。但是,我似乎无法从字符串中读取单个单词,而不会弄乱并阅读字母、数字和符号。我读过其他主题,但我的逻辑在某些方面存在严重缺陷,这是我看不到的。

int main()
{
 fstream fp;
 string line;

fp.open("syllabus.txt", ios::in);

getline(fp, line);

    string word = findWords(line);
    cout << word << endl;
}

string findWords(string &line)
{
int j = 0;
string word;

for(int i = 0; i < line.size(); i++)
{
    while(isalpha((unsigned char)line[j]) != 0 && isdigit((unsigned char)line[j]) != 1)
        j++;
    word += line.substr(0, j) + " + ";
    line  = line.substr(j, (line.size() - j));
}
return word;
}
4

3 回答 3

1
  1. 您只在主要内容中阅读了一行,但在有问题的部分您说要阅读整个文件

  2. 为什么你定义 findwords 来获取 string 的地址但给出 string ?

  3. i < line.size() 您的 for 条件案例是错误的,很有可能超出您的字符串并在此条件下出现 seg 错误。

于 2013-11-13T01:26:21.643 回答
1

您的代码块有很多问题。对于一个你不想在迭代时改变行的人。通常,您不应更改迭代的内容。您需要一个开始索引和一个结束索引(从搜索中找到)。

这是给你的一个技巧,你可以用 >> 运算符读取一个单词

ifstream fp( "syllabus.txt" );
string word; 
vector<string> words;  

while (fp>> word)
    words.push_back(word);
于 2013-11-13T01:29:58.227 回答
1

这个循环看起来很奇怪:

for(int i = 0; i < line.size(); i++)
{
    while(isalpha((unsigned char)line[j]) != 0 && isdigit((unsigned char)line[j]) != 1)
        j++;
    word += line.substr(0, j) + " + ";
    line  = line.substr(j, (line.size() - j));
}

您的“行”正在循环内被修改,但当发生这种情况时,您的“i”不会重置为新字符串的开头。无论如何,“i”在你的循环中是无关紧要的,它不会出现在它的任何地方。

那么为什么会出现这个循环呢?

至于解决方案,有多种方法可以做到。

  • 如果要循环,最简单的方法是将行加载到字符串中,然后string::find_first_not_of在拥有所有字母字符的字符串的地方使用。这可能不是最有效的,甚至不是最优雅的。这将返回一个位置,该位置将是std::string::npos字符串的结尾或第一个非字母字符的位置。

  • 下一个最简单的是常规的 std::find 算法,它采用迭代器并允许您放入自己的谓词,并且您可以将其放在不按字母顺序排列的基础上。使用 C++11 很容易编写基于 isalpha 的 lambda(如果您的字符串可能包含常规字符集之外的字符,则可以使用旧 C 版本或使用语言环境的增强 C++ 版本)。这将返回一个迭代器,要么是end()字符串的,要么是第一个非字母字符的位置。

于 2013-11-13T01:30:49.710 回答