【问题标题】:Writing String.trim() in C [duplicate]用 C 编写 String.trim() [重复]
【发布时间】:2010-03-15 21:42:42
【问题描述】:

可能的重复:
Painless way to trim leading/trailing whitespace in C?
Trim a string in 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++;
}

这段代码看起来干净吗??

【问题讨论】:

标签: c trim


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    如果您明智地使用标准库函数,通常会使您的代码更具可读性 - 例如,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);
    }
    

    【讨论】:

    • 您是否允许我在商业软件中使用它?
    【解决方案3】:

    该代码存在几个问题。它只检查空间。不是制表符或换行符。您正在复制字符串的整个非空白部分。你在设置它之前使用 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;
    }
    

    【讨论】:

      【解决方案4】:

      有一些问题: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;
      } 
      

      【讨论】:

        【解决方案5】:

        这是我的解决方案。

        简短、简单、干净、注释和轻微测试。

        它使用“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';
            }
        }
        

        【讨论】:

        • 当 strlen(String) 为 0 时这可能很危险。
        • 空白比空格字符更多
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-11-21
            • 2019-07-24
            • 1970-01-01
            • 2015-03-09
            • 2020-10-18
            • 2016-11-28
            • 1970-01-01
            相关资源
            最近更新 更多