我需要读取一个文件然后向用户询问一个单词,之后我需要逐行显示该单词的出现。另外我需要用char数组来检查它。你可以检查我的 输出示例;
Line 2: 1 occurrence(s)
line 4: 2 occurrence(s)
Line 7: 1 occurrence(s)
正如您所看到的,我通过searchString lenght划分了行长度,这是searchString发生的可能性的最大时间。因此,我需要显示出现但是我的代码将此分区显示为出现。你能帮我解决这个问题吗?
#include <iostream>
#include <string>
#include <fstream>
#include <istream>
using namespace std;
int number_of_lines = 1;
void numberoflines();
unsigned int GetFileLength(std::string FileName)
{
std::ifstream InFile(FileName.c_str());
unsigned int FileLength = 0;
while (InFile.get() != EOF) FileLength++;
InFile.close();
cout<<"Numbers of character in your file : "<<FileLength<<endl;
return FileLength;
}
int main()
{
string searchString, fileName, line;
int a;
string *b;
char *c,*d;
int wordCount = 0, count = 0,count1=0;
cout << "Enter file name : " << endl;
cin >> fileName;
GetFileLength(fileName);
cout << "Enter a word for searching procces : " << endl;
cin >> searchString;
ifstream in (fileName.c_str(), ios::in);
d= new char[searchString.length()+1];
strcpy(d,searchString.c_str());
a=GetFileLength(fileName);
b= new string [a];
if(in.is_open()){
while(!in.eof()){
getline(in,line);
c= new char[line.length()+1];
count++;
strcpy(c,line.c_str());
count1=0;
for (int i = 0; i < line.length()/searchString.length(); i++)
{
char *output = NULL;
output = strstr (c,d);
if(output) {
count1++;
}
else count1--;
}
if(count1>0){cout<<"Line "<<number_of_lines<<": "<<count1<<" occurrence(s) "<<endl;}
number_of_lines++;
if (count==10)
{
break;
}
}
numberoflines();
}
return 0;
}
void numberoflines(){
number_of_lines--;
cout<<"number of lines in text file: " << number_of_lines << endl;
}
答案 0 :(得分:0)
这个循环:
for (int i = 0; i < line.length()/searchString.length(); i++)
{
char *output = NULL;
output = strstr (c,d);
if(output) {
count1++;
}
else count1--;
}
不计算该行中字符串的所有匹配项,因为每次调用c
时d
和strstr()
都相同。当您重复搜索时,您必须从上一场比赛后的某个地方开始。
当您找不到匹配项时,也没有理由从count1
中减去。当发生这种情况时,你应该退出循环。使用for
循环没什么意义,因为你没有对i
做任何事情;只需使用while
循环。
char *start = c;
size_t searchlen = searchString.length();
while (true)
{
char *output = strstr (start,d);
if(output) {
count1++;
start = output + searchlen;
} else {
break;
}
}
答案 1 :(得分:0)
您无需将整个文件读入数组或std::string
。我建议你在优化之前保持这个程序的简单。
如您的问题所述,您需要使用字符数组并逐行阅读。
查找istream::getline
function因为它非常有用。
让我们声明最大行长度为1024。
这是阅读文件部分:
#define MAX_LINE_LENGTH (1024)
char text_buffer[MAX_LINE_LENGTH]; // Look, no "new" operator. :-)
//...
while (my_text_file.getline(text_buffer, MAX_LINE_LENGTH, '\n'))
{
//... TBD
}
上面的代码片段将一行文本读入变量text_buffer
。
因为您正在使用字符数组,请阅读您喜欢的文本中的“str”函数,例如strstr
;或者你可能要写自己的。
下一步是从文本行中提取“单词”。
为了提取单词,我们需要知道它的起始位置和结束位置。因此,需要搜索文本行。请参阅isalpha
funciton,因为它会很有用。
这是一个查找单词开头和结尾的循环:
unsigned int word_start_position = 0; // start at beginning of the line.
unsigned int word_end_position = 0;
const unsigned int length = strlen(text_buffer); // Calculate only once.
while (word_start_position < length)
{
// Find the start of a word.
while (!isalpha(text_buffer[word_start_position]))
{
++word_start_position;
}
// Find end of the word.
word_end_position = word_start_position;
while (isalpha(text_buffer[word_end_position]))
{
++word_end_position;
}
}
上述代码片段中仍存在一些逻辑问题,供O.P.解决。
下一部分是添加使用单词的开始和结束位置的代码,将单词中的字符复制到另一个变量。然后,此变量将用于 map 或关联数组或字典,其中包含出现次数。
换句话说,在容器中搜索单词。如果单词存在,则递增关联的出现变量。如果它不存在,请将该单词添加到容器中,出现次数为1。
祝你好运!