2010-03-15 31 views
7

可能重复:
Painless way to trim leading/trailing whitespace in C?
Trim a string in C写作String.trim(c)中

嗨,大家好, 我写在C字符串修剪法,这是代码我想出了。我认为它可以消除前后空白,但我希望代码更清晰。你能建议改进吗?

void trim(char *String) 
{ 
int i=0;j=0; 
char c,lastc; 
while(String[i]) 
{ 
    c=String[i]; 
    if(c!=' ') 
    { 
    String[j]=c; 
    j++; 
    } 
    else if(lastc!= ' ') 
    { 
    String[j]=c; 
    j++; 

    } 
    lastc = c; 
    i++; 
} 

此代码是否看起来干净?

+2

以及只针对*空间检查*性格。空白空间通常包括检查TAB,回车和换行 – 2010-03-15 21:47:01

+8

http://stackoverflow.com/questions/122616/painless-way-to-trim-leadingtrailing-whitespace-in-c – 2010-03-15 21:48:17

+0

添加评论将有助于 – Drakosha 2010-03-15 21:48:40

回答

4

它看起来不干净。假设第一个字符是空格,那么您使用的值为未定义的lastc。你在最后留下一个空格(如果末尾有一个空格,当它被击中c将是一个空格,并且lastc不会)。

你也没有终止字符串。假设你修复了未初始化的lastc问题,你会将“abc”转换为“abcbc”,因为它在任何时候都没有缩短。

该代码还会折叠字符串中的多个空格。这不是你所描述的;是期望的行为?

1

该代码有几个问题。它只检查空间。不是标签或换行符。您正在复制字符串的整个非空白部分。在设置之前你正在使用lastc。

下面是一个替代版本(编译但没有测试):

char *trim(char *string) 
{ 
    char *start; 
    int len = strlen(string); 
    int i; 

    /* Find the first non whitespace char */ 
    for (i = 0; i < len; i++) { 
     if (! isspace(string[i])) { 
      break; 
     } 
    } 

    if (i == len) { 
     /* string is all whitespace */ 
     return NULL; 
    } 

    start = &string[i]; 

    /* Remove trailing white space */ 
    for (i = len; i > 0; i--) { 
     if (isspace(string[i])) { 
      string[i] = '\0'; 
     } else { 
      break; 
     } 
    } 

    return start; 
} 
0

而不是比较的空格字符“”,我会用“isspace为”功能,我相信在定义字符ctype.h中。

0

我不清楚干净,但我觉得很难遵循。如果我需要这样做,我最初会考虑两个阶段:

  1. 找出多少个字符从头开始丢弃,然后将剩余的字符串(包括空终止符)移动到开头地址。 (如果允许你返回一个不同的开始指针,你可能不需要移除,但如果是这样的话,你需要对内存卫生非常小心。)
  2. 找出从(新)结束处放下多少个字符并设置那里有一个新的空终止符。

我可能会再更仔细一通的解决方案就像你似乎在试图实现,但前提是速度问题。

顺便说一句,您可能想要使用isspace()而不是仅检查空间。

1

存在一些问题:lastc可能未初始化。例如,您可以使用for循环而不是while循环。此外,trim/strip函数通常替换空格,制表符和换行符。

下面是使用我写了前一段指针的解决方案:

void trim(char *str) 
{ 
    char *ptr = str; 
    while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') ++ptr; 

    char *end = ptr; 
    while(*end) ++end; 

    if(end > ptr) 
    { 
     for(--end; end >= ptr && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'); --end); 
    } 

    memmove(str, ptr, end-ptr); 
    str[end-ptr] = 0; 
} 
1

这里是我的解决方案。

简短,简洁,干净,评论和轻微测试。

它使用“isspace”分类功能,因此您可以轻松更改要裁剪的“白色空间”的定义。

void trim(char* String) 
{ 
    int dest; 
    int src=0; 
    int len = strlen(String); 

    // Advance src to the first non-whitespace character. 
    while(isspace(String[src])) src++; 

    // Copy the string to the "front" of the buffer 
    for(dest=0; src<len; dest++, src++) 
    { 
     String[dest] = String[src]; 
    } 

    // Working backwards, set all trailing spaces to NULL. 
    for(dest=len-1; isspace(String[dest]); --dest) 
    { 
     String[dest] = '\0'; 
    } 
} 
+0

当strlen(字符串)为0时,这可能是危险的。 – user85509 2010-03-16 06:25:21

+0

还有比空间字符更多的空格 – Mawg 2017-01-09 14:51:12

3

它往往使你的代码更具可读性,如果你做出明智地使用标准库函数 - 例如,isspace()memmove()特别有用的位置:

#include <string.h> 
#include <ctype.h> 

void trim(char *str) 
{ 
    char *start, *end; 

    /* Find first non-whitespace */ 
    for (start = str; *start; start++) 
    { 
     if (!isspace((unsigned char)start[0])) 
      break; 
    } 

    /* Find start of last all-whitespace */ 
    for (end = start + strlen(start); end > start + 1; end--) 
    { 
     if (!isspace((unsigned char)end[-1])) 
      break; 
    } 

    *end = 0; /* Truncate last whitespace */ 

    /* Shift from "start" to the beginning of the string */ 
    if (start > str) 
     memmove(str, start, (end - start) + 1); 
} 
+1

我有你的许可证在商业软件中使用它吗? – Mawg 2017-01-09 14:52:11