-1

我使用这个问题作为在 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         
~~

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

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

4

3 回答 3

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); 
于 2012-08-10T16:37:27.053 回答
0

尝试 isgraph 而不是/除了 isspace

于 2012-08-10T16:31:36.647 回答
-1

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

在 C 中,字符是unsigned integers,所以如果你说white-space,就会明白' ',它的 ASCII 码是十进制的 32 或十六进制的 0x20。你提到的字符不是空格!

' ' != '\r'

下面是我对 、 和 函数的实现trimleft-trim分别right-trim从字符字符串中删除周围(即前导和尾随)、前导和尾随空格。函数不需要额外的标头,这是最可能的仅依赖整数和指针算术的准系统实现。

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

我会将这些函数添加到我的字符串库 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;
}
于 2016-02-24T21:17:12.900 回答