从未知长度的缓冲区读取CString?

时间:2013-07-23 07:46:04

标签: c++ buffer cstring

假设我有一个档案。我将所有字节读入unsigned char缓冲区。从那里我试图读取一个c字符串(空终止),而不知道它的长度。

我尝试了以下内容:

char* Stream::ReadCString()
{
    char str[0x10000];
    int len = 0;
    char* pos = (char*)(this->buffer[this->position]);
    while(*pos != 0)
        str[len++] = *pos++;
    this->position += len+ 1;
    return str;
}

我想我可以填充str数组中的每个char,因为我检查了char是否为null终止。这不起作用。有什么帮助吗?

this-> buffer =字节数组
this-> position =数组中的位置

还有其他方法吗?我想我可以通过实际缓冲区的地址运行它: str[len++] = *(char*)(this->buffer[this->position++])

更新 我的新功能:

char* Stream::ReadCString()
{
    this->AdvPosition(strlen((char*)&(this->buffer[this->position])) + 1);
    return (char*)&(this->buffer[this->position]);
}

并用:

调用它
printf( "String: %s\n", s.ReadCString()); //tried casting to char* as well just outputs blank string

示例文件: enter image description here

4 个答案:

答案 0 :(得分:1)

str是一个本地c字符串。任何指向str outsider函数的引用指针都是未定义的行为:Undefined, unspecified and implementation-defined behavior,它可能会也可能不会引起明显的问题。

答案 1 :(得分:1)

检查一下:

#include <cstring>
#include <iostream>

class   A
{
  unsigned char buffer[4096];
  int   position;

public:
  A() : position(0)
  {
    memset(buffer, 0, 4096);
    char        *pos = reinterpret_cast<char*>(&(this->buffer[50]));
    strcpy(pos, "String");
    pos = reinterpret_cast<char*>(&(this->buffer[100]));
    strcpy(pos, "An other string");
  }

   const char *ReadString()
  {
    if (this->position != 4096)
      {
        while (std::isalpha(this->buffer[this->position]) == false && this->position != 4096)
               this->position++;
        if (this->position == 4096)
          return 0;
        void    *tmp = &(this->buffer[this->position]);
        char    *str  = static_cast<char *>(tmp);
        this->position += strlen(str);
        return (str);
      }
    return 0;
  }

};

reintrepret_cast仅适用于init,因为您正在从文件中读取

int     main()
{
  A     test;

  std::cout << test.ReadString() << std::endl;
  std::cout << test.ReadString() << std::endl;
  std::cout << test.ReadString() << std::endl;
}

http://ideone.com/LcPdFD

编辑我更改了 ReadString()

的结尾

答案 2 :(得分:0)

只要你小心,空终止可能是最好的方法,但它不适合你的原因很可能是因为你正在返回已经在堆栈上分配的内存。一旦你点击返回就会释放这个内存,因此会导致未定义的行为。相反,在堆上分配你的字符:

char* str = new char[0x10000];

并在呼叫者不再需要时释放内存。

答案 3 :(得分:0)

可以使用以下方法修复。我推进了这个职位,然后又回到了地址。

char* Stream::ReadCString()
{
    u64 str_len = strlen((char*)&(this->buffer[this->position])) + 1;
    this->AdvPosition(str_len);
    return (char*)&(this->buffer[this->position - str_len]);
}

希望这有助于任何人。