Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Убрать обрезание по ноль символу


Автор: Xaotuk 8.4.2009, 12:21
Проблема: необходимо обрабатывать массив байт, но так как такого типа в С++ нет использую unsigned char. При записи в массив должны использоваться любые символы, в том числе может встречаться и ноль символ '\0'. При обработке полученного массива не могу корректно определить конец строки, при записи str[i]!=NULL все равно идет остановка на ноль символе.

К примеру функция определения длины массива:

Код

typedef unsigned char byte;

long strLength(byte * str)
{
    int i=0;
    while(str[i++]!=NULL);
    return i;
}


Вернет только до '\0' несмотря на то что проверяется на NULL.

Вопрос: как сделать проверку на инициализацию ячеек памяти, а не на их содержимое в этом случае. Использую динамические массивы, на всякий случай полный код:

Код

#include <stdlib.h>

typedef unsigned char byte;

long strLength(byte * str)
{
    int i=0;
    while(str[i++]!=NULL);
    return i;
}

class f_string
{
    byte * items;
    long count;
public:
    f_string();    
    void Add(byte *);
    long length(void);
    ~f_string();
    byte * toArray(void);
    long Count(void);
};

long f_string::Count(void)
{
    return count;
}

byte * f_string::toArray(void)
{
    return items;
}

f_string::f_string()
{
    count=0;    
    items=(byte*)malloc(sizeof(byte));
}

f_string::~f_string()
{
    free(items);
}

void f_string::Add(byte * str)
{
    int i=count,j=0;
    count+=strLength(str);
    items=(byte*)realloc(items,sizeof(byte)*(count+1));
    for(i;i<count;i++)
        items[i]=str[j++];
    items[i]='\0';
}


В функции Add при определении длины входного массива и начинаются косяки если в середине массива встречается '\0'.

Автор: GoldFinch 8.4.2009, 12:25
Xaotuk, 0==NULL

"инициализацию ячеек памяти"
такого понятия не существует

Автор: Xaotuk 8.4.2009, 12:30
Тогда как решить проблему?

Автор: zim22 8.4.2009, 12:40
Цитата(Xaotuk @  8.4.2009,  12:30 Найти цитируемый пост)
Тогда как решить проблему?

Код

#include <vector>
...
std::vector<unsigned char> vc;

Автор: Xaotuk 8.4.2009, 13:03
Не годится. Во-первых, vector не вернет мне указатель на массив, а он мне нужен чтобы вызывать функцию генерации хэш кода, во-вторых, если и сделать возврат указателя будет первая проблема...

Автор: cutwater 8.4.2009, 13:06
Явно хранить и передавать размер массива (или размер хранящихся данных)

Автор: Xaotuk 8.4.2009, 13:15
Поясню подробнее.
1. Есть массив типа unsigned char, служащий для накопления данных извне.
2. Есть поток байт приходящий извне, его я пихаю в массив накопитель.
3. Мне надо определять длину приходящего потока, причем определением конца потока не должен быть ноль-символ.
И вот как сделать последнее не знаю.

Автор: X-3R1 8.4.2009, 13:23
Цитата(Xaotuk @  8.4.2009,  11:03 Найти цитируемый пост)
Не годится. Во-первых, vector не вернет мне указатель на массив, а он мне нужен чтобы вызывать функцию генерации хэш кода, во-вторых, если и сделать возврат указателя будет первая проблема... 


Вектор это последовательный контейнер, т.е. память в нём находится последовательно. Поэтому указатель на первый элемент. Это и будет твой "указатель на массив".

Только советую получать указатель на массив, перед его использованием, ибо при добавлении новых элементов, м. произойти перераспределение памяти, и указатель станет невалидным.

Автор: zim22 8.4.2009, 13:31
Цитата(X-3R1 @  8.4.2009,  13:23 Найти цитируемый пост)
Поэтому указатель на первый элемент. Это и будет твой "указатель на массив".

Код

&vc.front();

Автор: Dem_max 8.4.2009, 13:39
Код

vector не вернет мне указатель на массив

сделай так 
Код

#include <vector>
...
std::vector<char *> vc;
char *pc = new char[20];
vc.push_back(pc);
strcpy(vc[0], "Привет");


Код

3. Мне надо определять длину приходящего потока, причем определением конца потока не должен быть ноль-символ.

Выбери концом данных другой символ

Автор: X-3R1 8.4.2009, 13:43
Цитата(Dem_max @  8.4.2009,  11:39 Найти цитируемый пост)
сделай так 

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

Автор: GoldFinch 8.4.2009, 14:42
X-3R1, и что, что исключение? в исключении и освобождай, по finally

Автор: X-3R1 8.4.2009, 14:52
GoldFinch, удачи smile

Автор: JackYF 8.4.2009, 14:53
Цитата(GoldFinch @  8.4.2009,  13:42 Найти цитируемый пост)
в исключении и освобождай, по finally 

Двойная работа, не комильфо.

Автор: Fazil6 8.4.2009, 15:03
Цитата(Xaotuk @  8.4.2009,  12:21 Найти цитируемый пост)
Вернет только до '\0' несмотря на то что проверяется на NULL.

Вопрос: как сделать проверку на инициализацию ячеек памяти, а не на их содержимое в этом случае. 

красиво звучит.... Вопросительный знак долженбыть не конце.


Автор: zim22 8.4.2009, 15:36
Цитата(X-3R1 @  8.4.2009,  13:43 Найти цитируемый пост)
Да ну , ты чего ? Это ж надо заботиться о выделенной памяти. Ладно бы ещё потом не забыть её через delete удалить. А если исключение ?

auto_ptr позаботится, если не массивы конечно динамические.
ну или методику RAII прменить

Автор: X-3R1 8.4.2009, 18:07
Цитата(zim22 @  8.4.2009,  13:36 Найти цитируемый пост)
auto_ptr позаботится, если не массивы конечно динамические.
ну или методику RAII прменить

Ну в примере во-первых динамические массивы, а во-вторых, auto_ptr не может быть элементом контейнера 
smile имхо, пошёл флейм.

Автор: Dov 8.4.2009, 18:33
Цитата(Xaotuk @  8.4.2009,  12:30 Найти цитируемый пост)
Тогда как решить проблему?

Код

// ...
#include <malloc.h>
// ...

size_t  strLength(byte * str)
{ 
    return _msize(str);
}
// ...


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)