我想搜索文件中的特定单词&返回该文件中是否存在该单词的结果。我创建了一个执行此操作的函数。但是在返回程序时崩溃了。这是代码:
bool FindMyWord(const char *fileName)
{
ifstream myFile (fileName);
if(!myFile)
return false;
string wordSearch = "MyWord";
string endSearch = "LastWord";
bool result;
while(1)
{
char read[20];
myFile.getline(read, 1000, '\n');
string line(read, read+20);
if(line.find(wordSearch) != string::npos)
{
result = true;
break; //comes here after looping about 10 times
}
if(line.find(endSearch) != string::npos)
{
result = false;
break;
}
}
myFile.close();
return result;
} // <- crash when F10 is pressed after this
在调试VS2010中,我发现在执行&#34; return result;
&#34;之后发生了崩溃。在函数的倒数第二行,即当黄色光标用于函数的最后一个右括号时。
我收到了一条消息
A buffer overrun has occurred in myApp.exe which has corrupted the program's internal
state. Press Break to debug the program or Continue to terminate the program.
这是什么错误?我正在调用这样的函数:
bool result = FindMyWord("myFileName.stp");
更新:每行都有不同的字符和数字。他们是>我想看看前20个字符&amp;如果这些字符中不存在该单词,那么我想跳转到下一行。最初我使用过myFile.getline(read, 20, '\n');
但是在第一个循环之后,每个后续循环都会导致NULL传递给read。所以我读了1000,因为在读1000个字符之前它会找到&#39; \ n&#39; &安培;转到下一行。
实现这一目标的更好机制将非常有用。
答案 0 :(得分:4)
为什么不使用std::string
而不是固定长度的缓冲区?
bool FindMyWord(const char *fileName)
{
std::ifstream myFile (fileName);
if(!myFile) {
return false;
}
std::string wordSearch = "MyWord";
std::string endSearch = "LastWord";
bool result;
std::string line;
while(std::getline(myFile, line))
{
if(line.find(wordSearch) != std::string::npos)
{
result = true;
break; //comes here after looping about 10 times
}
if(line.find(endSearch) != std::string::npos)
{
result = false;
break;
}
}
myFile.close();
return result;
}
缓冲区溢出导致了太多的安全问题。只是不要使用固定长度的缓冲区!
这也更加正确,因为它会检查流上的错误。
PS我讨厌using namespace std
!
答案 1 :(得分:3)
myFile.getline(read, 1000, '\n');
将从地址read
开始向内存中读取最多1000个字节。 read
是一个20字节的堆栈缓冲区,因此您可能会超出已分配内存的末尾进行写入。这样做的效果是不确定的,但很可能发生崩溃。
要解决此问题,您应该将read
缓冲区的大小传递给getline
;
myFile.getline(read, sizeof(read), '\n');
(注意sizeof(read)
仅适用于堆栈缓冲区。如果在堆上分配read
,sizeof
只会告诉您指针的大小而不是分配的内存指向。)
答案 2 :(得分:0)
在您可以使代码生效之前,请忘记char[]
。 (如
其他人指出,你有一个缓冲区溢出。很容易
与任何C样式数组作为局部变量。)因为你是
寻找单词,初始代码可以是简单的东西
as:
std::string word;
while ( myFile >> word && word != "MyWord" && word != "LastWord" ) {
}
return word == "MyWord";
这当然可以更快,但如果"LastWord"
不是
在文件很远的地方,可能没有必要。 (BYW:是的
通常不需要关闭输入中使用的文件。该
析构函数会处理这个,因为你已经检查了
无论如何,每次输入后的状态,都没有错误检查
担心。)
答案 3 :(得分:0)
我在上面的代码中可以想到的一个地方导致缓冲区溢出:
myFile.getline(读取,1000,'\ n');
由于'read'是一个可容纳20个字符的缓冲区,因此如果文件的行大于该字符,则无法容纳。
另外,请进行eof检查。我会建议这样的事情:
bool FindMyWord(const char *fileName)
{
if(!myFile)
return false;
ifstream myFile (fileName);
const char* wordSearch = "MyWord";
const char* endSearch = "LastWord";
bool result = false;
string line;
while(std::getline(myFile, line))
{
if(line.find(wordSearch, 0, 20) != string::npos)
{
result = true;
break; //comes here after looping about 10 times
}
if(line.find(endSearch, 0, 20) != string::npos)
{
result = false;
break;
}
}
myFile.close();
return result;
}