从字符串 C++ 中读取单词,同时忽略空格、数字和符号。
Posted
技术标签:
【中文标题】从字符串 C++ 中读取单词,同时忽略空格、数字和符号。【英文标题】:Reading Words From Strings C++ While Ignoring Whitespace, Numbers, and Symbols. 【发布时间】:2013-11-13 01:13:44 【问题描述】:我正在尝试编写一个程序来读取文本文件,计算每个唯一单词,然后对唯一单词列表进行排序并列出每个单词的出现次数。但是,我似乎无法从字符串中读取单个单词,而不会弄乱并阅读字母、数字和符号。我读过其他主题,但我的逻辑在某些方面存在严重缺陷,这是我看不到的。
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;
【问题讨论】:
您输入的文本是什么。你的输出文本是什么。你期待它是什么? 如果输入是“aaaa1234.01 字母季节 2013”,那么输出将是“aaaa + 字母 + 季节”。所以,基本上,只有字母、所有空格、符号和数字被去掉了。 我是这么想的。 【参考方案1】:您的代码块有很多问题。对于一个你不想在迭代时改变行的人。通常,您不应更改迭代的内容。您需要一个开始索引和一个结束索引(通过搜索找到)。
这里有一个技巧,你可以用 >> 运算符读取单个单词
ifstream fp( "syllabus.txt" );
string word;
vector<string> words;
while (fp>> word)
words.push_back(word);
【讨论】:
【参考方案2】:您只在 main 中阅读了一行,但在有问题的部分您说要阅读整个文件
为什么你定义 findwords 来获取字符串的地址却给出字符串?
i
【讨论】:
1.如果我能让一行功能正常,我会在那之后逐行读取文件。这只是分配的一些奇怪的参数。 C++ 实际上一直允许我通过检查字符串的索引来阅读,这可能再也不会在其他任何事情中有用了。【参考方案3】:这个循环看起来很奇怪:
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()
,要么是第一个非字母字符的位置。
【讨论】:
你是对的。我正在尝试使用 i 作为 substr() 的起点,并使用 j 作为 then 长度,但显然我不是。以上是关于从字符串 C++ 中读取单词,同时忽略空格、数字和符号。的主要内容,如果未能解决你的问题,请参考以下文章
编辑 VBA UDF 以求和括号中的数字,同时忽略括号中的单词