繁体   English   中英

C / C ++ isspace()跳过多字节字符串字符

[英]C/C++ isspace() skipping multibyte string characters

我有以下函数返回字符串中的空格,

char *rtrim(char *l_ptr)
{
    char *lptr = l_ptr + strlen(l_ptr) - 1;
    for (; lptr != l_ptr && isspace((int)*lptr); lptr--)
        ;
    *lptr = '\0';
       return lptr;
}

char *ltrim(char *l_ptr)
{
    char *lptr;
    for (lptr = l_ptr; *lptr != '\0' && isspace((int)*lptr); lptr++)
        ;
    return lptr;
}


char *trim(char *l_ptr) {
return rtrim(ltrim(l_ptr));
}

问题是其修剪特征如下-

从“中删除前导空格

            Ć"

删除前导空格,结果为“”

字符是0xc6,前面有几个空格。 我已经检查了包含setlocale(LC_ALL,“”);的代码。 LANG设置为pl_PL.isoo88592。 任何帮助,不胜感激。

谢谢。

问题是您如何调用isspace 仅当输入在[0,UCHAR_MAX]范围内(或为EOF )时[0,UCHAR_MAX] isspace才会定义结果。 在您的系统上, char可能是带符号的,这意味着(int)*lptr将导致带重音符号的字符(代码点大于127的字符)为负值,该值不在合法范围内。

调用is...的一种参数形式( <cctype><ctype.h>那些参数)时,应始终将任何char类型的类型isspace( static_cast<unsigned char>( *lptr ) )unsigned charisspace( static_cast<unsigned char>( *lptr ) ) (将unsigned char隐式转换为int会做正确的事情。)

您的rtrim函数以

*lptr = '\0';
return lptr;

除了将被视为空字符串之外,它永远不会返回任何内容。 trim你然后直接返回该结果。

根据你想如何将这些功能的工作,你应该要么使rtrim原值返回l_ptr ,它一直保持不变,并指向字符串的开头,或使trim忽略的返回值rtrim

您可能会对所有字符都'Ć'同样的问题,而不仅仅是'Ć'

如果您正在使用多字节字符,则可能更容易切换到wchar ,以避免使用char(pointer)操作不必要的麻烦?

您可以使用iswspace来检查字符是否为空白。

rtrim()有多个问题。

  1. isspace()仅在unsigned char和EOF范围内为int定义。 对于超出0到CHAR_MAX范围(通常为0到127)范围内的值,需要在隐式转换为int之前转换为unsigned char (@詹姆斯·坎泽)

    C11dr§7.4.1“ ...其值应表示为unsigned char或等于宏EOF的值。如果自变量具有任何其他值,则行为是不确定的。”

  2. char *lptr = l_ptr + strlen("") - 1; 不好,因为该指针值未知有效。 需要新的方法。 这也开始了一个漫长的循环

    for (; lptr != l_ptr ... ; lptr--)

  3. *lptr = '\\0'; return lptr; 总是重播"" @hvd可能希望以字符串开头。

  4. 建议改写:

     #include "ctype.h" char *rtrim(char *l_ptr) { unsigned char *ptr = (unsigned char *) l_ptr; unsigned char *end = ptr; while (*ptr) { if (!isspace(*ptr++)) { end = ptr; } } *end = '\\0'; return l_ptr; } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM