C++ C++;读取文件直到找到字符

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

我想创建一个函数,它可以连续地逐字符读取文件,直到遇到特定的字符

这是我在类FileHandler中的方法

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
,并在调用函数中使用它。至于您遇到的问题-function
strcat
需要以null结尾的字符串作为第二个参数。显然,
缓冲区
不是以null结尾的,因此您遇到了一个大问题。此外,
text
不够大,无法容纳2个或更多的
char
s。使用
new
按块分配
char
,效率极低,还有不必要的内存消耗。那么,如果我不使用
new
,我如何在不知道字符数组长度的情况下分配字符数组?您永远不会
删除
缓冲区指向的内存,从而导致内存泄漏。@yunhasnawa您应该使用类似
std::string
std::getline()
的内容,因此,您无需将注意力集中在内存管理上。同样,为了阅读
char
wise,可以使用
charc;输入文件流->获取(c)您应该多读一些关于指针的内容。让这个函数返回一个
char*
,有什么意义?是否要一个以null结尾的字符串,并包含一个字符?在这种情况下,您必须分配
新字符[2]
。另一方面,这有什么意义?只需从此函数返回一个
char
,并在调用函数中使用它。至于您遇到的问题-function
strcat
需要以null结尾的字符串作为第二个参数。显然,
缓冲区
不是以null结尾的,因此您遇到了一个大问题。此外,
text
不够大,无法容纳2个或更多的
char
s。尽管在
if(buffer[0]==seek)
中做了一些更改,但该代码仍然有效,并为我理解指针的概念提供了很多视野。非常感谢。尽管在if(buffer[0]==seek)
中做了一些更改,但该代码仍然有效,并为我提供了大量的视野,让我更好地理解指针的概念。非常感谢。