c、修剪字符串和宽字符

c, trimming strings, and wide characters

简而言之,我在需要宽字符的环境中解析从 libcurl 接收的 HTTP headers。 headers 作为 char * 字符串到达​​我这里,采用通用格式

name: value

我通过将 null 写入冒号的位置,然后 trimming:

将其分成两个字符串
        int offset = index_of( ':', s );

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

我用的trim函数是我自己写的:

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

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

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

我知道 this answer 并尝试了它推荐的 trim 功能,但它们没有解决我的问题,所以暂时我又回到了我自己的.

然后我将 trimmed 字符串提供给 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 is the highest signed 16-bit number, -1,这可能很重要;并向我暗示 mbstowcs 正在读取字符串的末尾,这反过来暗示 strlen 可能返回虚假值。

我能够从流中读取宽字符:

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

"λάμβδα"

我绝不是C专家;这是我将近 30 年来完成的第一个重要的 C 项目,所以我可能遗漏了一些非常明显的东西;并非常感谢帮助。完整的源代码,如果您有兴趣,请访问 here.

关闭 1

mbstowcs() 转换数组。如果结果还包括一个 空字符 ,请在传递给函数的长度中考虑该字符。

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

buffer 中缺少 空字符 可能会弄乱以下 make_cons().


其他

for ( i = strlen( s ); ( isblank( s[i] ) || iscntrl( s[i] ) ) && i >= 0; i-- )。被打破。在 s[i].

之前进行 i >= 0 测试

注意 is...(int ch) 预计 chunsigned charEOF 的范围内。此代码在s[i] < 0时为UB。通常的修复:is...((unsigned char) s[i]).