在忽略空格,数字和符号的同时从字符串C ++中读取单词。

时间:2013-11-13 01:13:44

标签: c++ string

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

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;
}

3 个答案:

答案 0 :(得分:0)

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

  2. 为什么要定义用于获取字符串地址但使用字符串的查找字符?

  3. i&lt; line.size()你的条件是错误的,很有可能超过你的字符串并在这种情况下得到段错误。

答案 1 :(得分:0)

你的大量代码有很多问题。对于一个你不想在迭代它时改变线。作为一项规则,你不应该改变你的迭代。您需要一个起始索引和一个结束索引(您可以从搜索中找到)。

这是一个技巧,您可以使用&gt;&gt;读取单个单词操作

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

while (fp>> word)
    words.push_back(word);

答案 2 :(得分:0)

这个循环看起来很奇怪:

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));
}

你的&#34; line&#34;正在循环中进行修改但你的&#34; i&#34;发生这种情况时,不会重置为新字符串的开头。 &#34; I&#34;无论如何,它在你的循环中是无关紧要的,它不会出现在它的任何地方。

为什么这个循环?

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

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

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