如何使用strtok()函数改进搜索?

时间:2018-11-11 14:01:44

标签: c++

我有一个文件“ Shalespeare_Hamlet.txt”,其中包含

  

哈姆雷特,一些文字,哈姆雷特,样本文本。

程序必须搜索文本中单词出现的次数。
如何使用strtok()改善代码?

using namespace std;
int main() {
const int len = 101;
char word[len], line[len];
cout << "Word: ";
cin >> word;

int l_word = strlen(word); 
ifstream fin("Shakespeare_Hamlet.txt"); 
if (!fin) {
    cout << "Error! Can't open the file.";
    system("pause");
    return 1;
}

int count = 0;
while (fin.getline(line, len)) { 
    char *p = line; 
    while (p = strstr(p, word)) {
        char *c = p; 
        p += l_word; 
        if (ispunct(*p) || isspace(*p) || (*p == '\0')) count++;
    }
}
cout << "Count of words: " << word << ": " << count << endl;
system("pause");
}

谢谢!

3 个答案:

答案 0 :(得分:2)

我完全重做了代码,希望对大家有所帮助
    使用命名空间std;

int main() {
ifstream fin("Shakespeare_Hamlet.txt");
if (!fin) {
    cout << "Opening error!!!\n";
    system("PAUSE");
    return EXIT_FAILURE;
}

fin.seekg(0, ios::end);  
long length = fin.tellg();  
char *file = new char[length + 1];
fin.seekg(0, ios::beg);  
fin.read(file, length);  

int k = 0;
char* arr[50000];
char* str;
str = strtok(file, "\n ,.-!?:;");

while (str != NULL) {
    arr[k] = str;
    k++;
    str = strtok(NULL, "\n ,.-!?:;");
}

char word[20];
cout << "Enter word: ";
gets_s(word); 
int count = 0;
for (int i = 0; i < k; i++) {
    if (strcmp(arr[i], word) == 0) {
        count++;
    }
}
cout << "Count of words: " << word << " : "<< count << endl;

delete[] file;
fin.close();
system("PAUSE");
return EXIT_SUCCESS;
}

答案 1 :(得分:1)

strtok和iostream等更好的工具可以解决此工作时,您就无法使用C ++中的std::string“改善”程序。

答案 2 :(得分:1)

您的代码在某些情况下将无法正常工作:

  • 如果搜索到的单词在行中的位置上,该行在两个get之间进行拆分,例如单词“ Hamlet”在行的char位置98处开始,并拆分为“ Ham”和“ let”。
  • 如果单词的开头有标点符号,例如“ Hamlet ...,则只检查字符串的末尾,而不检查开头。

我认为您的算法应如下:

  1. 使用std::string将整个行读入std::getline
  2. 从该行中删除所有标点符号,
  3. 使用std :: istringstream将行拆分为单词。
  4. 对于每个单词,检查是否等于输入单词,如果相等,则递增计数。

例如:

std::string line;
//read whole line to std::string 
while (std::getline(fin, line)) 
{ 
   std::string result;
   //remove punctuation and copy to result
   std::remove_copy_if(line.begin(), line.end(), std::back_inserter(result), std::ptr_fun<int, int>(&std::ispunct) );
   //use string stream to parse line without punctuation 
   std::istringstream istr(result);
   std::string str;
   while(istr>>str)
   {
      if(word==str)
      {
        count++;
      }
   }
}