2014-02-13 101 views
1

我有以下函数返回剥离从字符串中的空格,C/C++ isspace()所能跳过多字节字符串字符

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。任何帮助非常感谢。

谢谢。

+0

什么字符编码您使用的? –

+0

@JohnZwinck从他的LANG设置中,我猜测ISO 8859-2(Latin-2,东欧)。 –

+0

注意:'char * lptr = l_ptr + strlen(l_ptr) - 1;'如果'l_ptr'为'“”'则为UB。 (也可能是一个_long_循环。) – chux

回答

0

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;总是retruns ""。 @ 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; 
    } 
    
+0

谢谢,您提出的更改使我的代码正常工作。 – user3305937

+0

@ user3305937如果其中一个答案能够很好地满足您的帖子的需求,请接受它。获得15个以上的代表积分后,请务必对所有您认为有用的答案进行投票。 – chux

0

rtrim函数结束的

*lptr = '\0'; 
return lptr; 

这永远不能返回比将被视为一个空字符串的任何其他。在trim你然后直接返回该结果。

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

你也有同样的问题,所有的字符,而不仅仅是'Ć'

+0

我认为在'rtrim'中返回字符串的结尾不是*有问题,而是''rtrim'用于实现'trim'的方式。 – hmn

+0

@hmn哦,当然,我想这也是一个有效的方法。将编辑。 – hvd

4

的问题是你如何调用isspaceisspace仅 已经定义的结果,如果输入是在[0,UCHAR_MAX] 范围(或是EOF)。在您的系统上,char可能已签名,其中 表示(int)*lptr将导致 重音字符(代码点大于127的字符), (不在合法范围内)为负值。

当调用的is...的一个参数的形式(那些 <cctype><ctype.h>),你应该始终char类型unsigned char什么:isspace( static_cast<unsigned char>( *lptr ) )。 (中unsigned charint的隐式转换会做正确的事。)

+0

虽然基于标准完全正确,但您确定这是导致OP的问题吗?如果我没有记错,至少glibc有意支持函数中的负值,例如'isspace'作为标准要求的扩展。 – hvd

+0

@ hvd这将解释症状。尽管如你所说,一些 实现_do_尽力使它工作(除了 对于Latin-1中的'''',其代码点为0xFF);我记得 这是Solaris下的情况。 (我不记得在Linux下尝试了 ,看看'glibc'的功能。)我还需要至少一次过去的一次,在Windows (使用VC++)时不是这种情况。 –

0

如果与多字节字符工作可能会比较容易切换到wchar,以避免与CHAR(指针)操纵不必要的麻烦?

你也可以使用iswspace检查如果字符是一个空白。

+0

他的环境似乎说他正在使用不是多字节的ISO 8859-2。 –