麻烦修剪c中的字符串

时间:2012-08-10 16:26:48

标签: c string trim

我使用this question作为修剪C中字符串的指南。它适用于由空格(' ')专门限制的字符串,但在特殊空格('\r'上, '\n''\t'等),它失败了。这是一个例子:

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

size_t trim(char *out, size_t len, const char *str)
{
  if(len == 0)
    return 0;

  const char *end;
  size_t out_size;

  // Trim leading space
  while(isspace(*str)) str++;

  if(*str == 0)  // All spaces?
  {
    *out = 0;
    return 1;
  }

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace(*end)) end--;
  end++;

  // Set output size to minimum of trimmed string length and buffer size minus 1
  out_size = (end - str) < len-1 ? (end - str) : len-1;

  // Copy trimmed string and add null terminator
  memcpy(out, str, out_size);
  out[out_size] = 0;

  return out_size;
}

int main(){

    char *str = " \n\n  hello  \t    \r  ";
    char trimmed[strlen(str)];

    trim (trimmed, strlen(trimmed), str);
    printf("~%s~\n~%s~\n", str, trimmed);

    return 0;
}

产生输出:

~ 

  ~ello         
~~

任何人都可以修复代码以正确修剪所有空白字符吗?

第二个问题:引用答案中的第一个函数给了我一个段错误。有谁知道为什么会这样?

3 个答案:

答案 0 :(得分:2)

您调用该函数的方式不正确。

char *str = " \n\n  hello  \t    \r  ";
char trimmed[strlen(str)+1]; // Note that you must +1 for the terminating \0.

// Use sizeof() instead of strlen() because trimmed is containing garbage.
// strlen() measures the length of the content while sizeof() measure the allocated size of the array.
trim (trimmed, sizeof(trimmed), str); 

答案 1 :(得分:0)

尝试isgraph而不是/除了isspace

答案 2 :(得分:-1)

  

但是在特殊的空格('\ r','\ n','\ t'等)上,它会失败。

在C中,字符为unsigned integers,因此,如果您说white-space,则可以理解' ',其ASCII码为十进制32或HEX为0x20。您提到的字符不是空格!

' ' != '\r'

以下是trimleft-trimright-trim函数的实现,分别用于从chracter字符串中删除周围(即前导和尾随),前导和尾随空格。函数不需要额外的头,最可能只依赖于整数和指针算术的裸骨实现。

您可以修改代码(在您的情况下,您需要展开逻辑if案例以涵盖其他字符,例如\r\n\t等。,你在帖子中提到的)根据你的需要。

我会将这些功能添加到my string library, zString:)

char *zstring_trim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    int in_word=0;  /* logical check */
    int index=0;    /* index of the last non-space char*/

    while (*src)
        if(*src!=' '){
         /* Found a word */
            in_word = 1;
            *dst++ = *src++;  /* make the assignment first
                               * then increment
                               */
        } else if (*src==' ' && in_word==0) {
         /* Already going through a series of white-spaces */
            in_word=0;
            ++src;
        } else if (*src==' ' && in_word==1) {
         /* End of a word, dont mind copy white spaces here */
            in_word=0;
            *dst++ = *src++;
            index = (dst-str)-1; /* location of the last char */
        }

    /* terminate the string */
    *(str+index)='\0';

    return str;
}

char *zstring_ltrim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    int index=0;    /* index of the first non-space char */

    /* skip leading white-spaces */
    for(; *src && *src==' '; ++src, ++index)
        ;

    /* copy rest of the string */
    while(*src)
        *dst++ = *src++;

    /* terminate the string */
    *(src-index)='\0';

    return str;
}

char *zstring_rtrim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    int index=0;    /* index of the last non-space char*/

    /* copy the string */
    while(*src){
        *dst++ = *src++;
        if (*src!=' ' && *src)
            index = (src-str)+1;
    }

    /* terminate the string */
    *(str+index)='\0';

    return str;
}