2016-01-29 2 views
1

Я пытаюсь разобрать заголовки SIP в строку. Я делаю это путем итерации по строке по строкам. Каждый заголовок должен быть разделен новым символом строки.Чтение строки C по строкам

Строка ввода будет выглядеть нечто похожее на это:

INVITE sip:[email protected] SIP/2.0 
Via: SIP/2.0/UDP pc33.server1.com;branch=z9hG4bK776asdhds Max-Forwards: 70 
To: user2 <sip:[email protected]> 
From: user1 <sip:[email protected]>;tag=1928301774 
Call-ID: [email protected] 
CSeq: 314159 INVITE 
Contact: <sip:[email protected]> 
Content-Type: application/sdp 
Content-Length: 142 

Мой код:

void readlines(char *str){ 
    int i; 
    int reset; 
    char current_line[500]; 
    char tmp = 0; 
    for(i=0; i<strlen(str); i++){ 
     tmp = str[i]; 
    if (tmp == '\n'){ 
     strncpy(current_line, str+tmp, i); 
     strcat(current_line, '\0'); 
     printf("current line = %s", current_line); 
    } 
    } 
} 

В своем коде вы можете увидеть, если блок. В блоке if я печатаю текущую строку как дешевый способ протестировать мое решение, результат этого заявления печати ничего. Возможно, мое понимание того, как c интерпретирует символ \n, не является полным.

+1

посмотрите на 'strtok' функции –

+0

Спасибо за предложение, к сожалению, Я уже рассмотрел эту функцию. По моему мнению, это не потокобезопасное, что является требованием для меня. – btald1331

+1

Одна из проблем, которые я нашел и не понял, является ли я тестированием этой функции, передав аргумент командной строки с \ n. Но способ, которым я проходил тестовую строку, взял \ n буквально, а не как новый символ строки. – btald1331

ответ

1

Как указано в комментариях, strtok_r является идеальной функцией для этого. Он используется для синтаксического анализа строки на основе разделителей и занимает отдельный указатель состояния, чтобы он был безопасен в многопоточных программах.

void readlines(char *str){ 
    char *p, *temp; 
    p = strtok_r(str, "\n", &temp); 
    do { 
     printf("current line = %s", p); 
    } while ((p = strtok_r(NULL, "\n", &temp)) != NULL); 
} 

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

EDIT:

Как уже упоминалось в комментариях, strtok_r доступен только на системах POSIX, т.е. не Windows. Для Windows эквивалентная функция - strtok_s.

+0

Примечание: 'strtok_r' - только POSIX. – user694733

+0

@ user694733 Спасибо. Отредактировано, чтобы предоставить альтернативу Windows. – dbush

+0

FWIW: В приложении C11 K существует «strtok_s()» с аналогичной многопоточной функциональностью. – chux

0

Если вы находитесь на POSIX, использовать его getline функцию (вероятно, на FILE* который является вашим TCP сокет, например, с помощью fdopen;., Или вы могли бы получить FILE* ручку из буфера с помощью fmemopen). Если у вас нет getline, стандарт C99 имеет fgets, но вы либо ограничите длину строки до некоторой длины буфера фиксированного размера, либо перераспределите ее.

Если у вас есть уже все данные заголовка в некотором буфере, вы можете разобрать его с помощью sscanf (обрабатывать его возврата счета, использовать также %n), или разобрать его вручную (например, с помощью некоторых strcmp) и т.д. И конечно strtok_r как упоминалось другими.

Считаете ли вы использование какой-либо существующей библиотеки SIP implementation? В частности, GNU oSIP?

0

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

недостающие файлы заголовков:

#include <stdio.h> // printf() 
#include <string.h> // strlen(), strncpy(), strcat() 

strcat() ожидает оба параметра будут char* не фактический характер Так вызов strcat() должно быть:

strcat(current_line, "\0"); 

Теперь, что касается выполнение кода.

(предположим, что str является указателем на массив полукокса, который не завершенную нулем и менее чем 500 байт длиной)

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

void readlines(char *str) 
{ 
    size_t i; 
    char *current_line = NULL; 

    for(i = 0; i< 500 && '\n' != str[i]; i++); 

    if(NULL == (current_line = calloc(i+2, 1))) 
    { // then malloc failed 
     perror("calloc failed"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, calloc successful 

    memcpy(current_line, str, i); 
    printf("current line = %s", current_line); 
    free(current_line); 
} 
Смежные вопросы