Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Проблема с указателями в реализации парсинга "на лету"

22K
10 августа 2007 года
SMiX
18 / / 23.05.2007
Соединяюсь с сокетом, который сразу при подключении выводит мне строку вида
 
Код:
domain:port\n

Я ее получаю и тут же разделяю: пока не встретил двоеточие, записываю символы в *domain, после него и до \n - в port. Реализую с помощью динамической памяти ради саморазвития, предполагая, что длина и домена, и порта может быть больше чем ожидается.
Код:
char buf;
            int res;
            int size=1;
            char * domain=(char*)calloc(1,sizeof(char));
            char * port=(char*)malloc(sizeof(char));    
// Просто экспериментирую. В курсе, что некорректно выделять и потом перевыделять на тот же размер(первое прохждение цикла)
            while((res=recv(s,&buf,1,0))>0)
            {
                if(isdomain){
                    if(buf!=':'){
           
                        domain=(char*)realloc(domain,size*sizeof(char));
                        *(domain+size-1)=buf;
                        size++;
                    }
                    else{ isdomain=false; size=1;}
                }
                else if(buf!='\n'){
                    port=(char*)realloc(port,size*sizeof(char));
                    *(port+size-1)=buf;
                    size++;
                   
                }
               
               
            }


Программа выводит следующее:
 
Код:
domain.ru¤¤¤¤лллллллл:1234¤¤¤¤лллллллл

Сколько ни бился - ничего не помогает. Как от этого избавиться? Спасибо.
22K
10 августа 2007 года
Pastor
43 / / 16.05.2007
А завершающий ноль? Забыл?
412
10 августа 2007 года
grgdvo
323 / / 04.07.2007
Может быть рассмотреть варианты попроще. strchr - поиск символа в строке.

Код:
while(recv(buf.....)
{
...

char*dots=strchr(buf,':');
char*lf=strchr(buf,'\n');
if(dots&&lf)
{
    int len=dots-buf;
    char*domain=(char*)malloc(len+1);
    strncpy(domain,buf,len);
    domain[len+1]=0;

    len=lf-dots;
    char*port=(char*)malloc(lf-dots+1);
    strncpy(port,dots+1,len);
    port[len+1]=0;
}

...
}


Если содержимое buf не важно после выполнения преобразования, то можно еще упростить.

 
Код:
char*dots=strchr(buf,':');
char*lf=strchr(buf,'\n');
if(dots&&lf)
{
    char*domain=buf;
    *dots=0;
    char*port=dots+1;
    *lf=0;
}


Пример писал без проверки, поэтому если обнаружаться ошибки, прошу меня простить - отладка поможет :)

Удачи
12K
10 августа 2007 года
__AleXX__
133 / / 02.04.2007
Цитата: SMiX
Соединяюсь с сокетом, который сразу при подключении выводит мне строку вида
 
Код:
domain:port\n

Я ее получаю и тут же разделяю: пока не встретил двоеточие, записываю символы в *domain, после него и до \n - в port. Реализую с помощью динамической памяти ради саморазвития, предполагая, что длина и домена, и порта может быть больше чем ожидается.
Код:
char buf;
            int res;
            int size=1;
            char * domain=(char*)calloc(1,sizeof(char));
            char * port=(char*)malloc(sizeof(char));    
// Просто экспериментирую. В курсе, что некорректно выделять и потом перевыделять на тот же размер(первое прохждение цикла)
            while((res=recv(s,&buf,1,0))>0)
            {
                if(isdomain){
                    if(buf!=':'){
           
                        domain=(char*)realloc(domain,size*sizeof(char));
                        *(domain+size-1)=buf;
                        size++;
                    }
                    else{ isdomain=false; size=1;}
                }
                else if(buf!='\n'){
                    port=(char*)realloc(port,size*sizeof(char));
                    *(port+size-1)=buf;
                    size++;
                   
                }
               
               
            }


Программа выводит следующее:
 
Код:
domain.ru¤¤¤¤лллллллл:1234¤¤¤¤лллллллл

Сколько ни бился - ничего не помогает. Как от этого избавиться? Спасибо.





Pastor +1.

А надо realloc делать на размер больший на 1, и в последний элемент массива-строки вписывать '\0'.
Тогда будет Ок.

To grgdvo:
Если уз считывать сначала все в один буфер, а потом по нему искать,
то я бы лучше использовал std::string :))

22K
10 августа 2007 года
SMiX
18 / / 23.05.2007
Пашет, спасибо всем =)
grgdvo, мне кажется, что реализация этого дела с чтением по 1 байту лучше, т.к. она универсальней. Например, если предположить, что сервер может дать не domain:port\n, а user:pass@domain:port\n
Вот исправленный код
Код:
char buf;
            int res;
            int size=1;
            bool isdomain=true;

            char * domain=(char*)calloc(2,sizeof(char));
            char * port=(char*)malloc(sizeof(char)*2);    
            while((res=recv(s,&buf,1,0))>0)
            {
                if(isdomain){
                    if(buf!=':'){
           
                        domain=(char*)realloc(domain,size*sizeof(char));
                        *(domain+size-1)=buf;
                        size++;
                    }
                    else{
                        isdomain=false;
                        domain=(char*)realloc(domain,size*sizeof(char));
                        *(domain+size-1)='\0';
                        size=1;
                    }
                }
                else if(buf!='\n'){
                    port=(char*)realloc(port,size*sizeof(char));
                    *(port+size-1)=buf;
                    size++;
                }else{
                    port=(char*)realloc(port,size*sizeof(char));
                    *(port+size-1)='\0';
                }
               
               
               
            }
           
            cout<<domain<<':'<<port<<endl;
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог