2013-07-23 1 views
1

Предположим, у меня есть файл. Я прочитал все байты в unsigned char buffer. Оттуда я пытаюсь прочитать строку c (нуль завершен), не зная ее длины.Чтение CString из буфера с неизвестной длиной?

Я попытался следующие:

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

Я думал, что я мог бы заполнить каждый символ в массиве ул как я прошел, проверяя, если символ был нулем или нет. Это не работает. Любая помощь?

this-> буфер = массив байтов
this-> положение = положение в массиве

Существуют ли какие-либо другие методы, чтобы сделать это? Я думаю, я мог бы запустить его по адресу фактического буфера: str[len++] = *(char*)(this->buffer[this->position++])?

Update: Моя новая функция:

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

+0

Вы пытаетесь вернуть локальную переменную – Alexis

+0

правильно, например: printf ("% s \ n", Stream.ReadCString()); – MysteryDev

+1

Не уверен, что понимаете, пусть ваш буфер [0,0,0, 'H', 'E', 'L', 'L', O ', 0] и позиция 3, почему вы не возвращаетесь & (буфер [позиция])?и позиция + = strlen (& buffer [position]) – Alexis

ответ

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 только для инициализации, так как вы читаете из файла

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

Edit Я изменил конецReadString()

+0

Я попытался и не смог с reinterpret_cast , в чем же разница и регулярное кастинг? – MysteryDev

+0

проверить эту новую версию и для актеров: http://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-and-reinterpret-cast-be-used. Но reinterpret_cast более сильный (и ближе к литу C), чем static_cast – Alexis

+0

Хотя мне нравится ваш ответ для моего старого метода, это кажется более подходящим: char * Stream :: ReadCString() { this-> AdvPosition (strlen ((char *) & (this-> buffer [this-> position])) + 1); возвращение (char *) & (этот-> буфер [это-> позиция]); } Есть ли способ отображения строки с использованием этого метода? – MysteryDev

1

ул является локальным с струна. Любой указатель ссылки на str посторонней функции - это неопределенное поведение: Undefined, unspecified and implementation-defined behavior, это может или не может вызвать заметную проблему.

+0

Это объясняет, почему теперь мне нужно найти для него работу haha ​​ – MysteryDev

+0

@ Jakes625 Если вам нравится, ха-ха. – lulyon

0

Нулевое завершение, вероятно, лучший способ пойти до тех пор, пока вы будете осторожны, но причина его не работает для вас, скорее всего, потому что вы возвращаете память, которая была выделена в стеке. Эта память будет освобождена, как только вы нажмете на возврат, что приведет к неопределенному поведению. Вместо этого, выделить свои символы на куче:

char* str = new char[0x10000]; 

и освободить память, когда абонент не нужен.

+0

Строка в файле уже завершена нулем. Поэтому, я думаю, я мог бы просто получить адрес текущей позиции. Сейчас у меня проблемы с отображением. – MysteryDev

+0

От адреса первого pos до нулевого терминатора, да. Я все еще беспокоюсь о том, что вы пытаетесь сделать: P, но удачи! –

+0

Я читаю все содержимое файла и сохраняю его в байтовом массиве (unsigned char *). После этого я начинаю читать данные внутри. Вот мой файл http://puu.sh/3JC0B/f69dc57519.png. Я пытаюсь отобразить «entry_n» и переместить позицию в байт после него. Я могу успешно продвигать позицию, но строка не будет отображаться с помощью printf («% s \ n», stream.ReadCString()); – MysteryDev

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

Надеюсь, это поможет кому угодно.