Разбиение буфера на переменные ( строки )

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by fire64, 16 Dec 2008.

  1. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    У меня опять проблема с буферами.

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

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

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

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

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

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

    izlesa Elder - Старейшина

    Joined:
    3 Jan 2008
    Messages:
    112
    Likes Received:
    32
    Reputations:
    5
    да проблема с буфЕрами это пять ^______^
    используй динамический двумерный массив + в конце исходного буфера ставь дополнительный символ '\0' для обозначения конца. Сначала определяешь количество строк в буфере и выделяешь место под указатели на строки. Потом проходишь и считывая строки во временный буфер, определяешь размеры строк - выделяешь место под строку в массиве двумерном и копируешь туда строку из временного буфера. Если хочешь, завтра наверно напишу пример на plain C , а то сейчас спааааать надо ^______^

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

    Code:
     
    
    #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;
    }
    
    
     
    #2 izlesa, 17 Dec 2008
    Last edited: 17 Dec 2008
    2 people like this.
  3. St0nX

    St0nX Elder - Старейшина

    Joined:
    19 May 2007
    Messages:
    257
    Likes Received:
    46
    Reputations:
    0
    если я все правильно понял то достаточно фунукции strtok(). Получаеш количество вхождений в строку разделителей и в цикле с помощью этой функции делиш.
     
    1 person likes this.
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Так вешь еще проще - динамический массив pchar'ов
    затем циклом проходишь от начала строки до конца и при встрече нуля ставишь умеличиваешь позицию в массиве и ставишь номер следующего элемента+адрес начала строки. При этом \0 сам будет сведетельствовать о конце строки.
    Другими словами не выдирать сами строки из буфера, а лишь ставить указатели на них.
     
    1 person likes this.
  5. izlesa

    izlesa Elder - Старейшина

    Joined:
    3 Jan 2008
    Messages:
    112
    Likes Received:
    32
    Reputations:
    5
    2St0nX
    а разве strtok() умеет работать с '\0' в качестве раздилителей корректно?
     
    #5 izlesa, 17 Dec 2008
    Last edited: 17 Dec 2008
  6. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    izlesa, спасибо за код, так же спасибо всем остальным за советы
     
  7. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    izlesa, с кодом что то не так
    иногда ( видимо зависит от содержимого буфера ), программа крешится

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

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

    если точно, то if(ClBuf != '\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".
     
  8. Feonor

    Feonor Elder - Старейшина

    Joined:
    23 Jul 2008
    Messages:
    128
    Likes Received:
    52
    Reputations:
    19

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

    __________________
    [​IMG]
     
  9. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    размер самого ClBuf 10024


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

    если надо могу выложить весь код проги
     
    #9 fire64, 17 Dec 2008
    Last edited: 17 Dec 2008
  10. xismyname

    xismyname Elder - Старейшина

    Joined:
    7 Sep 2008
    Messages:
    77
    Likes Received:
    7
    Reputations:
    -5

    Вы допустили ошибку :
    Code:
    buffer = (char **)malloc(counter * sizeof(char **));
    указатель на указатель создаеться так :
    Code:
    buffer = (char **)malloc(counter * sizeof(char *));
    тоже самое вы сделали в цикле :
    Code:
    buffer[counter] = (char *)malloc((strlen(temp)+1)*sizeof(char *));
    а должно быть так :
    Code:
    buffer[counter] = (char *)malloc((strlen(temp)+1)*sizeof(char));

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

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    xismyname, всеравно падает
     
  12. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    мне только что на винграде дали более простой код

    const char str[] = {'s','s','\0','a','\0','g','g','g','\0','\0'};
    // Код последовательно выводит все разделенные слова
    for (const char* p = str ; *p ; p += strlen(p) + 1)
    {
    puts(p);
    }

    надеюсь что теперь падать не будет
     
  13. izlesa

    izlesa Elder - Старейшина

    Joined:
    3 Jan 2008
    Messages:
    112
    Likes Received:
    32
    Reputations:
    5
    Что я вчера за кусок гу*на накодил? Ппц. ^_____^

    2xismyname
    согласен, хотя первый косяк не такой страшный ) хотя признаюсь, это ппц )

    2fire64
    Этот код с винграда восхитителен, великолепен. Он завораживает своим остроумием и профессионализмом. Если я когда-нибудь приближусь хоть на немного к такому же ясному изложению мысли на Си я буду счастлив. Пользуйся им ^____^ и забей на мой. Там выход за пределы массива имеет место быть при некоторых вводных, т.к. условием завершения является количество посчитанных слов и счётчик тупо выбежал за пределы массива, а слова не были посчитаны. Если бы ты дал пример строки с которой вылетае, то было бы проще найти багу, а желание такое есть, ибо опыт.
     
  14. fire64

    fire64 Elder - Старейшина

    Joined:
    1 Apr 2008
    Messages:
    251
    Likes Received:
    22
    Reputations:
    5
    izlesa, окей сегодня скину строку
     
    #14 fire64, 18 Dec 2008
    Last edited: 18 Dec 2008