C++ C++;如何编写一个代码,在从文本文件中删除任何特殊字符的同时统计最前面的单词

C++ C++;如何编写一个代码,在从文本文件中删除任何特殊字符的同时统计最前面的单词,c++,C++,如何从打开并读取文本文件的命令行获取文本文件,然后计算该文件中的顶部单词,但同时删除任何特殊字符。我在这里完成了这段代码,并使用了地图,但它并没有计算每个单词。例如,“hello.”是一个词,也是“$#%hello?”/”。我有一个来自歌曲的文件,shake it off,应该读shake 78次,但我在这个代码中只数了26次 #include <iostream> #include <fstream> #include <string> #include &

如何从打开并读取文本文件的命令行获取文本文件,然后计算该文件中的顶部单词,但同时删除任何特殊字符。我在这里完成了这段代码,并使用了地图,但它并没有计算每个单词。例如,“hello.”是一个词,也是“$#%hello?”/”。我有一个来自歌曲的文件,shake it off,应该读shake 78次,但我在这个代码中只数了26次

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <vector>

using namespace std;

string ask(const string& msg) {
  string ans;
  cout << msg;
  getline(cin, ans);
  return ans;
}
int main() {

  ifstream fin( ask("Enter file name: ").c_str() ) ;
  if (fin.fail()) {
    cerr << "ERROR"; // this is if the file fails to open
    return 1;
  }
  map<string, int> wordCount;
  string entity;
  while (fin >> entity) {
    vector<string> words;

for (int i = 0, a = 0; i < entity.length(); i++) {
  char& c = entity[i];
  if (c < 'A' || (c > 'Z' && c < 'a') || c > 'z') {
    string word = entity.substr(a, i - a);
    a = i + 1;
    if (word.length() > 0)
      words.push_back(word);
  }
}
for (auto & word : words)
  wordCount[word]++;

}
fin.close();

vector<string> topWords;
const size_t MAX_WORDS = 10;
for ( auto iter = wordCount.begin(); iter != wordCount.end(); iter ++ ) {

int som = 0, lim = topWords.size();
while (som < lim) {
  int i = ( som + lim ) / 2;
  int count = wordCount[topWords[i]];
  if ( iter -> second > count)
    lim = i;
  else if ( iter -> second < count )
    som = i + 1;
  else
    som = lim = i;

}
if (som < MAX_WORDS ) {
  topWords.insert( topWords.begin() + som, iter -> first );
  if ( topWords.size() > MAX_WORDS )
    topWords.pop_back();
}
}
for (auto & topWord : topWords)
  cout << "(" << wordCount[topWord] << ")\t" << topWord << endl;




return 0;

}
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
字符串询问(常量字符串和消息){
字符串ans;
cout实体){
向量词;
for(inti=0,a=0;i'Z'和&c<'A')|c>'Z')){
字符串字=entity.substr(a,i-a);
a=i+1;
if(word.length()>0)
单词。推回(单词);
}
}
用于(自动和文字:文字)
字数[字]+;
}
fin.close();
向量关键词;
const size\u t MAX\u WORDS=10;
对于(自动iter=wordCount.begin();iter!=wordCount.end();iter++){
int-som=0,lim=topWords.size();
while(som秒>计数)
lim=i;
否则如果(iter->秒<计数)
som=i+1;
其他的
som=lim=i;
}
if(somfirst);
if(topWords.size()>最大单词数)
topWords.pop_back();
}
}
用于(自动和主题词:主题词)

cout您的原始代码有点难以细化,我已经按照您的描述获得了一个使用STL的程序

  • 擦除
    删除_如果
    组合以删除不需要的字符
  • 使用
    set
    按计数
如果您对Boost有一定的经验,那么它是一个使用
multimap
bimap
的用例,它可以使代码更加干净

#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
字符串询问(常量字符串和消息){
字符串ans;
cout实体){
entity.erase(std::remove_if(entity.begin(),entity.end(),
[](char ch){return!isalpha(ch);}),
entity.end());
字数[实体]+=1;
}
自动cmp=[](常数标准::成对和左侧,
const std::pair&rhs){
返回左秒>右秒;
};
std::多集顶部(
wordCount.begin(),wordCount.end(),cmp);
auto it=top.begin();
const size\u t MAX\u WORDS=10;
for(size_t i=0;i请看链接页面底部使用erase-remove习惯用法的示例。看看您的实际代码,您正在进行一个非常疯狂的测试:
if(c<'a'| |(c>'Z'&&c<'a')| c>'Z')
,这不酷。如果(!std::isalpha(c))
如果(!(c>='A'&&c='A'&&c
返回!isalpha(ch);
--应该是
返回!静态_cast(isalpha(ch));
!hi!
@hi@
#hi#
$hi$
%hi%
^hi^
&hi&
*hi*
(hi(
)hi)
_hi_
-hi-
+hi+
=hi=
~hi~
`hi`
:hi:
;hi;
'hi'
"hi"
<hi<
>hi>
/hi/
?hi?
{hi{
}hi}
[hi[
]hi]
|hi|
\hi\

bob bob bob bob bob bob bob !@#@$$%#&@^*()@*#)_++(#<><#:":bob@#@$$%#&@^*()@*#)_++(#<><#:":
!@#@$$%#&@^*()@*#)_++(#<><#:":bob@#@$$%#&@^*()@*#)_++(#<><#:":  !@#@$$%#&@^*()@*#)_++(#<><#:":bob@#@$$%#&@^*()@*#)_++(#<><#:":
!@#@$$%#&@^*()@*#)_++(#<><#:":bob@#@$$%#&@^*()@*#)_++(#<><#:": !@#@$$%#&@^*()@*#)_++(#<><#:":bob@#@$$%#&@^*()@*#)_++(#<><#: