简体   繁体   中英

C++ read file until char found

I want to create a function that can read a file char by char continuously until some specific char encountered.

This is my method in a class 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;
}

I test this function and it actually works. This is an example to read a file content until new line character '\\n' found.

size_t startPosition = 0;
char* text = this->fileHandler->readUntilCharFound(startPosition, '\n');

However, I am sure that something not right is exists somewhere in the code because if I use those method in a loop block, the app will just hangs. I guess the 'not right' things are about pointer but I don't know exactly where. Could you please point out for me?

C++ provides some easy-to-use solutions. For instance:

istream& getline (istream& is, string& str, char delim);

In your case, the parameter would be the equivalent of your text variable and delim would be the equivalent of your seek parameter. Also, the return value of getline would in some way be the equivalent of your goOn flag (there are good FAQs regarding the right patterns to check for EOF and IO errors using the return value of getline)

The lines

        if(strcmp(buffer, &seek) != 0)

and

            strcat(text, buffer); // Execution stops here

are causes for undefined behavior. strcmp and strcat expect null terminated strings.

Here's an updated version, with appropriate comments.

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;
}

You can further simplify the function to:

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;
}
        this->inputFileStream->read(buffer, 1);

No error checking.

        if(strcmp(buffer, &seek) != 0)

The strcmp function is used to compare strings . Here you just want to compare two characters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM