7

可能的重复:
在 C 中修剪前导/尾随空格的无痛方法?
修剪C中的字符串

我正在用 c 编写 String trim 方法,这是我想出的代码。我认为它可以消除前导和尾随空格,但是,我希望代码可以更干净。你能提出改进建议吗?

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++;
}

这段代码看起来干净吗?

4

7 回答 7

4

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

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

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

于 2010-03-15T21:54:21.707 回答
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);
}
于 2010-03-15T22:38:38.110 回答
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';
    }
}
于 2010-03-15T22:28:28.947 回答
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;
}
于 2010-03-15T21:57:55.430 回答
1

有一些问题:lastc可以在未初始化的情况下使用。例如,您可以使用 for 循环而不是 while 循环。此外,修剪/剥离功能通常会替换空格、制表符和换行符。

这是一个使用我很久以前写的指针的解决方案:

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;
} 
于 2010-03-15T22:02:22.740 回答
0

我没有将字符与空格字符 ' ' 进行比较,而是使用“isspace”函数,我相信它在 ctype.h 中定义。

于 2010-03-15T21:59:33.897 回答
0

我不知道干净,但我发现很难理解。如果我需要这样做,我最初会分两个阶段考虑:

  1. 找出从开头删除多少个字符,然后将字符串的其余部分(包括空终止符)memmove 到起始地址。(如果允许您返回不同的开始指针,您可能不需要 memmove,但如果是这样,您需要非常小心内存卫生。)
  2. 找出从(新)端删除的字符数,并在那里设置一个新的空终止符。

然后,我可能会更仔细地查看您似乎正在尝试实施的一次性解决方案,但前提是存在速度问题。

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

于 2010-03-15T22:01:13.893 回答