Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   Разбиение буфера на переменные ( строки ) (https://forum.antichat.xyz/showthread.php?t=96754)

fire64 17.12.2008 00:50

Разбиение буфера на переменные ( строки )
 
У меня опять проблема с буферами.

у меня есть буфер такого вида

string1 x00 string2 x00 string2 x00 и так далее

тоесть буфер состоит из нескольких строк разделенных нулями

я побывал создавать структуру
и с помощью нее разделять строки, но проблема в том что длина отдельных строк в буфере мне не известна

и длина строк может меняться

тоесть если я подогнал структуры под определенное количество байт, то не факт что и в следующий раз строки совпадут

izlesa 17.12.2008 01:55

да проблема с буфЕрами это пять ^______^
используй динамический двумерный массив + в конце исходного буфера ставь дополнительный символ '\0' для обозначения конца. Сначала определяешь количество строк в буфере и выделяешь место под указатели на строки. Потом проходишь и считывая строки во временный буфер, определяешь размеры строк - выделяешь место под строку в массиве двумерном и копируешь туда строку из временного буфера. Если хочешь, завтра наверно напишу пример на plain C , а то сейчас спааааать надо ^______^

впрочем держи ^____^ написано через задницу, но работает.

Код:



#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

int main(void)
{
        char str[] = {'s','s','\0','a','\0','g','g','g','\0','\0'};
        char **buffer;
        char temp[100];
        int flagstr = 0;
        int counter = 0;
        int count = 0;
        int i, j;
       

        for(i = 0;; i++)
        {
                if((str[i] != '\0') && (flagstr == 0))
                {
                        counter++;
                        flagstr = 1;
                }
                else if(str[i] == '\0')
                {       
                        if(str[i + 1] == '\0') break;
                        flagstr = 0;
                }
               
        }
        printf("%d\n", counter);

        buffer = (char **)malloc(counter * sizeof(char **));
        flagstr = 0;
        count = counter;
        counter = 0;       

        for(i = 0, j = 0;counter < count; i++, j++)
        {
                if(str[i] != '\0')
                {
                        temp[j] = str[i];
                        flagstr = 1;
                }
                else
                {
                        temp[j] = '\0';
                        buffer[counter] = (char *)malloc((strlen(temp)+1)*sizeof(char *));
                        memcpy(buffer[counter], temp, strlen(temp)+1);
                        buffer[counter][j]='\0';
                        counter++;
                        flagstr = 0;
                        j = -1;
                }
               
        }

        for(i = 0; i < counter; i++)
        {
                printf("%s\n", buffer[i]);
                free(buffer[i]);       
        }       
       
        free(buffer);
        getch();       
       

        return 0;
}


St0nX 17.12.2008 10:29

если я все правильно понял то достаточно фунукции strtok(). Получаеш количество вхождений в строку разделителей и в цикле с помощью этой функции делиш.

slesh 17.12.2008 10:47

Так вешь еще проще - динамический массив pchar'ов
затем циклом проходишь от начала строки до конца и при встрече нуля ставишь умеличиваешь позицию в массиве и ставишь номер следующего элемента+адрес начала строки. При этом \0 сам будет сведетельствовать о конце строки.
Другими словами не выдирать сами строки из буфера, а лишь ставить указатели на них.

izlesa 17.12.2008 10:52

2St0nX
а разве strtok() умеет работать с '\0' в качестве раздилителей корректно?

fire64 17.12.2008 16:04

izlesa, спасибо за код, так же спасибо всем остальным за советы

fire64 17.12.2008 16:59

izlesa, с кодом что то не так
иногда ( видимо зависит от содержимого буфера ), программа крешится

отладчик показал на строку

PHP код:

    for(00;counter counti++, j++)
    {
        if(
ClBuf[i] != '\0'

если точно, то if(ClBuf[i] != '\0')

значения были такие

count 13
counter 12
i 52430
j 678

Поток 'Поток Win32' (0xb2c) завершился с кодом 0 (0x0).
Необработанное исключение в "0x0040162a" в "server.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00137c6a".
Первый этап обработки исключения в "0x0040162a" в "server.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00137c6a".
Необработанное исключение в "0x0040162a" в "server.exe": 0xC0000005: Нарушение прав доступа при чтении "0x00137c6a".

Feonor 17.12.2008 17:05

Цитата:

Сообщение от fire64
...
если точно, то if(ClBuf[i] != '\0')

значения были такие

count 13
counter 12
i 52430
j 678

а размер ClBuf[i] какой? скорее всего произошол выход за границы массива

__________________
http://forum.korol-i-shut.ru/info/ub/119.gif

fire64 17.12.2008 17:11

размер самого ClBuf 10024


хм увеличил temp до 1024, толку никакого

если надо могу выложить весь код проги

xismyname 17.12.2008 17:25

Цитата:

Сообщение от izlesa
да проблема с буфЕрами это пять ^______^
используй динамический двумерный массив + в конце исходного буфера ставь дополнительный символ '\0' для обозначения конца. Сначала определяешь количество строк в буфере и выделяешь место под указатели на строки. Потом проходишь и считывая строки во временный буфер, определяешь размеры строк - выделяешь место под строку в массиве двумерном и копируешь туда строку из временного буфера. Если хочешь, завтра наверно напишу пример на plain C , а то сейчас спааааать надо ^______^

впрочем держи ^____^ написано через задницу, но работает.

Код:



#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

int main(void)
{
        char str[] = {'s','s','\0','a','\0','g','g','g','\0','\0'};
        char **buffer;
        char temp[100];
        int flagstr = 0;
        int counter = 0;
        int count = 0;
        int i, j;
       

        for(i = 0;; i++)
        {
                if((str[i] != '\0') && (flagstr == 0))
                {
                        counter++;
                        flagstr = 1;
                }
                else if(str[i] == '\0')
                {       
                        if(str[i + 1] == '\0') break;
                        flagstr = 0;
                }
               
        }
        printf("%d\n", counter);

        buffer = (char **)malloc(counter * sizeof(char **));
        flagstr = 0;
        count = counter;
        counter = 0;       

        for(i = 0, j = 0;counter < count; i++, j++)
        {
                if(str[i] != '\0')
                {
                        temp[j] = str[i];
                        flagstr = 1;
                }
                else
                {
                        temp[j] = '\0';
                        buffer[counter] = (char *)malloc((strlen(temp)+1)*sizeof(char *));
                        memcpy(buffer[counter], temp, strlen(temp)+1);
                        buffer[counter][j]='\0';
                        counter++;
                        flagstr = 0;
                        j = -1;
                }
               
        }

        for(i = 0; i < counter; i++)
        {
                printf("%s\n", buffer[i]);
                free(buffer[i]);       
        }       
       
        free(buffer);
        getch();       
       

        return 0;
}



Вы допустили ошибку :
Код:

buffer = (char **)malloc(counter * sizeof(char **));
указатель на указатель создаеться так :
Код:

buffer = (char **)malloc(counter * sizeof(char *));
тоже самое вы сделали в цикле :
Код:

buffer[counter] = (char *)malloc((strlen(temp)+1)*sizeof(char *));
а должно быть так :
Код:

buffer[counter] = (char *)malloc((strlen(temp)+1)*sizeof(char));

Надеюсь,что разницу видите.


Время: 01:09