C++ C++;读取文件直到找到字符
我想创建一个函数,它可以连续地逐字符读取文件,直到遇到特定的字符 这是我在类FileHandler中的方法C++ C++;读取文件直到找到字符,c++,file,C++,File,我想创建一个函数,它可以连续地逐字符读取文件,直到遇到特定的字符 这是我在类FileHandler中的方法 char* tysort::FileHandler::readUntilCharFound(size_t start, char seek) { char* text = new char; if(this->inputFileStream != nullptr) { bool goOn = true; size_t see
char* tysort::FileHandler::readUntilCharFound(size_t start, char seek)
{
char* text = new char;
if(this->inputFileStream != nullptr)
{
bool goOn = true;
size_t seekPos = start;
while (goOn)
{
this->inputFileStream->seekg(seekPos);
char* buffer = new char;
this->inputFileStream->read(buffer, 1);
if(strcmp(buffer, &seek) != 0)
{
strcat(text, buffer); // Execution stops here
seekPos++;
}
else
{
goOn = false;
}
}
}
//printf("%s\n", text);
return text;
}
我测试了这个函数,它确实可以工作。这是一个在找到新行字符'\n'
之前读取文件内容的示例
size_t startPosition = 0;
char* text = this->fileHandler->readUntilCharFound(startPosition, '\n');
但是,我确信代码中的某些地方存在不正确的地方,因为如果我在循环块中使用这些方法,应用程序将挂起。我猜“不对”的事情是关于指针的,但我不知道确切的位置。你能给我指一下吗
this->inputFileStream->read(buffer, 1);
无错误检查
if(strcmp(buffer, &seek) != 0)
strcmp
函数用于比较字符串。在这里,您只需要比较两个字符
无错误检查
if(strcmp(buffer, &seek) != 0)
strcmp
函数用于比较字符串。这里您只需要比较两个字符。行
if(strcmp(buffer, &seek) != 0)
及
是未定义行为的原因strcmp
和strcat
需要以null结尾的字符串
这是一个更新版本,有适当的注释
char* tysort::FileHandler::readUntilCharFound(size_t start, char seek)
{
// If you want to return a string containing
// one character, you have to allocate at least two characters.
// The first one contains the character you want to return.
// The second one contains the null character - '\0'
char* text = new char[2];
// Make it a null terminated string.
text[1] = '\0';
if(this->inputFileStream != nullptr)
{
bool goOn = true;
size_t seekPos = start;
while (goOn)
{
this->inputFileStream->seekg(seekPos);
// No need to allocate memory form the heap.
char buffer[2];
this->inputFileStream->read(buffer, 1);
if( buffer[0] == seek )
{
buffer[1] = '\0';
strcat(text, buffer);
seekPos++;
}
else
{
goOn = false;
}
}
}
return text;
}
您可以进一步简化该功能,以:
char* tysort::FileHandler::readUntilCharFound(size_t start, char seek)
{
// If you want to return a string containing
// one character, you have to allocate at least two characters.
// The first one contains the character you want to return.
// The second one contains the null character - '\0'
char* text = new char[2];
text[1] = '\0';
if(this->inputFileStream != nullptr)
{
this->inputFileStream->seekg(start);
// Keep reading from the stream until we find the character
// we are looking for or EOF is reached.
int c;
while ( (c = this->inputFileStream->get()) != EOF && c != seek )
{
}
if ( c != EOF )
{
text[0] = c;
}
}
return text;
}
台词
if(strcmp(buffer, &seek) != 0)
及
是未定义行为的原因strcmp
和strcat
需要以null结尾的字符串
这是一个更新版本,有适当的注释
char* tysort::FileHandler::readUntilCharFound(size_t start, char seek)
{
// If you want to return a string containing
// one character, you have to allocate at least two characters.
// The first one contains the character you want to return.
// The second one contains the null character - '\0'
char* text = new char[2];
// Make it a null terminated string.
text[1] = '\0';
if(this->inputFileStream != nullptr)
{
bool goOn = true;
size_t seekPos = start;
while (goOn)
{
this->inputFileStream->seekg(seekPos);
// No need to allocate memory form the heap.
char buffer[2];
this->inputFileStream->read(buffer, 1);
if( buffer[0] == seek )
{
buffer[1] = '\0';
strcat(text, buffer);
seekPos++;
}
else
{
goOn = false;
}
}
}
return text;
}
您可以进一步简化该功能,以:
char* tysort::FileHandler::readUntilCharFound(size_t start, char seek)
{
// If you want to return a string containing
// one character, you have to allocate at least two characters.
// The first one contains the character you want to return.
// The second one contains the null character - '\0'
char* text = new char[2];
text[1] = '\0';
if(this->inputFileStream != nullptr)
{
this->inputFileStream->seekg(start);
// Keep reading from the stream until we find the character
// we are looking for or EOF is reached.
int c;
while ( (c = this->inputFileStream->get()) != EOF && c != seek )
{
}
if ( c != EOF )
{
text[0] = c;
}
}
return text;
}
C++提供了一些易于使用的解决方案。例如:
istream& getline (istream& is, string& str, char delim);
在您的情况下,该参数将等效于
text
变量,而delim将等效于seek
参数。另外,getline的返回值在某种程度上与您的goOn
标志等效(关于使用getline的返回值检查EOF和IO错误的正确模式,有一些很好的FAQ)C++提供了一些易于使用的解决方案。例如:
istream& getline (istream& is, string& str, char delim);
在您的情况下,该参数将等效于
text
变量,而delim将等效于seek
参数。此外,getline的返回值在某种程度上相当于您的goOn
标志(关于使用getline的返回值检查EOF和IO错误的正确模式,有一些很好的常见问题解答)将char
的分块分配给new
将变得极为低效,还有不必要的内存消耗。那么,如果我不使用new
,我如何在不知道字符数组长度的情况下分配字符数组?您永远不会删除缓冲区指向的内存,从而导致内存泄漏。@yunhasnawa您应该使用类似std::string
和std::getline()
的内容,因此,您无需将注意力集中在内存管理上。同样,为了阅读char
wise,可以使用charc;输入文件流->获取(c)代码>您应该多读一些关于指针的内容。让这个函数返回一个char*
,有什么意义?是否要一个以null结尾的字符串,并包含一个字符?在这种情况下,您必须分配新字符[2]
。另一方面,这有什么意义?只需从此函数返回一个char
,并在调用函数中使用它。至于您遇到的问题-functionstrcat
需要以null结尾的字符串作为第二个参数。显然,缓冲区
不是以null结尾的,因此您遇到了一个大问题。此外,text
不够大,无法容纳2个或更多的char
s。使用new
按块分配char
,效率极低,还有不必要的内存消耗。那么,如果我不使用new
,我如何在不知道字符数组长度的情况下分配字符数组?您永远不会删除缓冲区指向的内存,从而导致内存泄漏。@yunhasnawa您应该使用类似std::string
和std::getline()
的内容,因此,您无需将注意力集中在内存管理上。同样,为了阅读char
wise,可以使用charc;输入文件流->获取(c)代码>您应该多读一些关于指针的内容。让这个函数返回一个char*
,有什么意义?是否要一个以null结尾的字符串,并包含一个字符?在这种情况下,您必须分配新字符[2]
。另一方面,这有什么意义?只需从此函数返回一个char
,并在调用函数中使用它。至于您遇到的问题-functionstrcat
需要以null结尾的字符串作为第二个参数。显然,缓冲区
不是以null结尾的,因此您遇到了一个大问题。此外,text
不够大,无法容纳2个或更多的char
s。尽管在if(buffer[0]==seek)
中做了一些更改,但该代码仍然有效,并为我理解指针的概念提供了很多视野。非常感谢。尽管在if(buffer[0]==seek)
中做了一些更改,但该代码仍然有效,并为我提供了大量的视野,让我更好地理解指针的概念。非常感谢。