c, обрезка строк и широкие символы - PullRequest
0 голосов
/ 31 января 2019

Вкратце, я анализирую заголовки HTTP, полученные из libcurl, в среде, где мне нужны широкие символы.Заголовки приходят ко мне как строки char * в общем формате

name: value

Я разделяю это на две строки, записывая ноль в позицию двоеточия, а затемобрезка:

        int offset = index_of( ':', s );

        if ( offset != -1 ) {
            s[offset] = ( char ) 0;
            char *name = trim( s );
            char *value = trim( &s[++offset] );

Я использую функцию обрезки, которую я написал сам:

char *trim( char *s ) {
    int i;

    for ( i = strlen( s ); ( isblank( s[i] ) || iscntrl( s[i] ) ) && i >= 0;
          i-- ) {
        s[i] = '\0';
    }
    for ( i = 0; ( isblank( s[i] ) || iscntrl( s[i] ) ) && s[i] != '\0'; i++ );

    return ( char * ) &s[i];
}

Я знаю этот ответ и попробовалФункции обрезки, рекомендованные им, но они не решили мою проблему, поэтому пока я вернулся к своей собственной.

Затем я подаю обрезанные строки в функцию mbstowcs:

struct cons_pointer add_meta_string( struct cons_pointer meta, wchar_t *key,
                                     char *value ) {
    wchar_t buffer[strlen( value ) + 1];
    /* \todo something goes wrong here: I sometimes get junk characters on the
     * end of the string. */
    mbstowcs( buffer, value, strlen( value ) );
    return make_cons( make_cons( c_string_to_lisp_keyword( key ),
                                 c_string_to_lisp_string( buffer ) ), meta );
}

Символ барахла, который я получаю, кажется, всегда один и тот же:

:: (inspect (assoc :owner (meta l)))

    STRG (1196577875) at page 7, offset 797 count 2
        String cell: character 's' (115) next at page 7 offset 798, count 2
         value: "simon翾"
"simon翾"
:: (inspect (cdr (cdr (cdr (cdr (cdr (assoc :owner (meta l)))))))))

    STRG (1196577875) at page 7, offset 802 count 2
        String cell: character '翾' (32766) next at page 0 offset 0, count 2
         value: "翾"

32766 - это 16-битное число со старшим знаком , -1, что, вероятно,значительное;и подразумевает для меня, что mbstowcs считывает конец строки, что, в свою очередь, означает, что strlen может возвращать ложное значение.

Я могу читать широкие символы из потока:

:: (assoc :x-lambda (meta l))

"λάμβδα"

Я ни в коем случае не эксперт C;это первый значительный C-проект, который я сделал за почти 30 лет, поэтому я могу упустить что-то очень очевидное;и помощь очень ценится.Полный исходный код, если вам интересно, это здесь .

1 Ответ

0 голосов
/ 31 января 2019

Выкл. На 1

mbstowcs() преобразует массивы.Если результат также должен включать нулевой символ , учетная запись fo будет иметь длину, переданную функции.

// mbstowcs( buffer, value, strlen( value ) );
mbstowcs( buffer, value, strlen( value ) + 1);

Отсутствие нулевого символа in buffer, вероятно, испортит следующее make_cons().


Прочее

for ( i = strlen( s ); ( isblank( s[i] ) || iscntrl( s[i] ) ) && i >= 0; i-- ).сломано.Выполните i >= 0 тестирование до s[i].

Примечание. is...(int ch) ожидает ch в диапазоне unsigned char и EOF.Этот код UB, когда s[i] < 0.Обычное исправление: is...((unsigned char) s[i]).

...