Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей.
Здесь обсуждаются безопасность, программирование, технологии и многое другое.
Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
 |
|
Разбиение буфера на переменные ( строки ) |

17.12.2008, 00:50
|
|
Участник форума
Регистрация: 01.04.2008
Сообщений: 200
Провел на форуме: 1059196
Репутация:
39
|
|
Разбиение буфера на переменные ( строки )
У меня опять проблема с буферами.
у меня есть буфер такого вида
string1 x00 string2 x00 string2 x00 и так далее
тоесть буфер состоит из нескольких строк разделенных нулями
я побывал создавать структуру
и с помощью нее разделять строки, но проблема в том что длина отдельных строк в буфере мне не известна
и длина строк может меняться
тоесть если я подогнал структуры под определенное количество байт, то не факт что и в следующий раз строки совпадут
|
|
|

17.12.2008, 01:55
|
|
Участник форума
Регистрация: 03.01.2008
Сообщений: 156
Провел на форуме: 414311
Репутация:
110
|
|
да проблема с буфЕрами это пять ^______^
используй динамический двумерный массив + в конце исходного буфера ставь дополнительный символ '\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;
}
Последний раз редактировалось izlesa; 17.12.2008 в 02:44..
|
|
|

17.12.2008, 10:29
|
|
Участник форума
Регистрация: 19.05.2007
Сообщений: 281
Провел на форуме: 2823587
Репутация:
106
|
|
если я все правильно понял то достаточно фунукции strtok(). Получаеш количество вхождений в строку разделителей и в цикле с помощью этой функции делиш.
|
|
|

17.12.2008, 10:47
|
|
Reservists Of Antichat - Level 6
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
Так вешь еще проще - динамический массив pchar'ов
затем циклом проходишь от начала строки до конца и при встрече нуля ставишь умеличиваешь позицию в массиве и ставишь номер следующего элемента+адрес начала строки. При этом \0 сам будет сведетельствовать о конце строки.
Другими словами не выдирать сами строки из буфера, а лишь ставить указатели на них.
|
|
|

17.12.2008, 10:52
|
|
Участник форума
Регистрация: 03.01.2008
Сообщений: 156
Провел на форуме: 414311
Репутация:
110
|
|
2St0nX
а разве strtok() умеет работать с '\0' в качестве раздилителей корректно?
Последний раз редактировалось izlesa; 17.12.2008 в 10:54..
|
|
|

17.12.2008, 16:04
|
|
Участник форума
Регистрация: 01.04.2008
Сообщений: 200
Провел на форуме: 1059196
Репутация:
39
|
|
izlesa, спасибо за код, так же спасибо всем остальным за советы
|
|
|

17.12.2008, 16:59
|
|
Участник форума
Регистрация: 01.04.2008
Сообщений: 200
Провел на форуме: 1059196
Репутация:
39
|
|
izlesa, с кодом что то не так
иногда ( видимо зависит от содержимого буфера ), программа крешится
отладчик показал на строку
PHP код:
for(i = 0, j = 0;counter < count; i++, 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".
|
|
|

17.12.2008, 17:05
|
|
Участник форума
Регистрация: 23.07.2008
Сообщений: 202
Провел на форуме: 3075657
Репутация:
122
|
|
Сообщение от fire64
...
если точно, то if(ClBuf[i] != '\0')
значения были такие
count 13
counter 12
i 52430
j 678
а размер ClBuf[i] какой? скорее всего произошол выход за границы массива
__________________

|
|
|

17.12.2008, 17:11
|
|
Участник форума
Регистрация: 01.04.2008
Сообщений: 200
Провел на форуме: 1059196
Репутация:
39
|
|
размер самого ClBuf 10024
хм увеличил temp до 1024, толку никакого
если надо могу выложить весь код проги
Последний раз редактировалось fire64; 17.12.2008 в 17:22..
|
|
|

17.12.2008, 17:25
|
|
Познающий
Регистрация: 07.09.2008
Сообщений: 79
Провел на форуме: 272452
Репутация:
10
|
|
Сообщение от 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));
Надеюсь,что разницу видите.
|
|
|
|
 |
|
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|