首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >删除逗号之间的白色字符,而不是逗号内部的字符之间。

删除逗号之间的白色字符,而不是逗号内部的字符之间。
EN

Stack Overflow用户
提问于 2022-05-09 18:03:14
回答 6查看 134关注 0票数 3

我刚开始学习C和学习C90。我正在尝试将一个字符串解析为一个命令,但我很难尝试删除白色字符。

我的目标是解析这样的字符串:

代码语言:javascript
运行
复制
NA ME, NAME   , 123 456, 124   , 14134, 134. 134   ,   1   

这方面:

代码语言:javascript
运行
复制
NA ME,NAME,123 456,124,14134,134. 134,1

所以争论中的白字符仍然存在,但是其他的白字符被移除了。

我考虑使用strtok,但我仍然想保留逗号,即使有多个连续的逗号。

直到现在我用:

代码语言:javascript
运行
复制
void removeWhiteChars(char *s)
{
    int i = 0;
    int count = 0;
    int inNum = 0;
    while (s[i])
    {
        if (isdigit(s[i]))
        {
            inNum = 1;
        }
        if (s[i] == ',')
        {
            inNum = 0;
        }
        if (!isspace(s[i]) && !inNum)
            s[count++] = s[i];
        else if (inNum)
        {
            s[count++] = s[i];
        }

        ++i;
    }
    s[count] = '\0'; /* adding NULL-terminate to the string */
}

但是它只跳过数字,直到逗号之后才移除白色字符,这是完全错误的。

任何帮助我都会感激的,我已经坚持了两天了。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2022-05-09 19:50:32

当您遇到可能跳过的空格时,您需要执行查找头。下面的函数,每次它看到一个空格时,都会检查它是否以逗号结尾。同样,对于每个逗号,它检查并删除以下所有空格。

代码语言:javascript
运行
复制
// Remove elements str[index] to str[index+len] in place
void splice (char * str, int index, int len) {
  while (str[index+len]) {
    str[index] = str[index+len];
    index++;
  }
  str[index] = 0;
}

void removeWhiteChars (char * str) {
  int index=0, seq_len;

  while (str[index]) {
    if (str[index] == ' ') {
      seq_len = 0;

      while (str[index+seq_len] == ' ') seq_len++;

      if (str[index+seq_len] == ',') {
        splice(str, index, seq_len);
      }
    }
    if (str[index] == ',') {
      seq_len = 0;
      while (str[index+seq_len+1] == ' ') seq_len++;

      if (seq_len) {
        splice(str, index+1, seq_len);
      }
    }
    index++;
  }
}
票数 5
EN

Stack Overflow用户

发布于 2022-05-09 21:17:25

解决任何解析问题的一个简短而可靠的方法是使用一个状态循环,它只不过是对原始字符串中所有字符的循环,其中使用一个(或多个)标志变量来跟踪需要跟踪的所有字符的状态。在这里,您需要知道是否正在读取逗号后面的post (后)。

这控制您如何处理下一个字符。您将使用一个简单的计数器变量来跟踪已读取的空格数,当遇到下一个字符时,如果您不是后缀逗号,则将该空格数追加到新字符串中。如果您是后逗号,则丢弃缓冲空间。(您可以使用遇到','本身作为不需要保存在变量中的标志)。

要删除','分隔符周围的空格,您可以编写一个rmdelimws()函数,该函数使用新字符串填充,将旧字符串复制为参数,并执行类似以下操作:

代码语言:javascript
运行
复制
void rmdelimws (char *newstr, const char *old)
{
  size_t spcount = 0;               /* space count */
  int postcomma = 0;                /* post comma flag */
  
  while (*old) {                    /* loop each char in old */
    if (isspace (*old)) {           /* if space? */
      spcount += 1;                 /* increment space count */
    }
    else if (*old == ',') {         /* if comma? */
      *newstr++ = ',';              /* write to new string */
      spcount = 0;                  /* reset space count */
      postcomma = 1;                /* set post comma flag true */
    }
    else {                          /* normal char? */
      if (!postcomma) {             /* if not 1st char after comma */
        while (spcount--) {         /* append spcount spaces to newstr */
          *newstr++ = ' ';
        }
      }
      spcount = postcomma = 0;      /* reset spcount and postcomma */
      *newstr++ = *old;             /* copy char from old to newstr */
    }
    old++;                          /* increment pointer */
  }
  *newstr = 0;                      /* nul-terminate newstr */
}

(注意:更新为肯定nul-终止,如果newstr没有初始化所有为零,如下所示)

如果要在行中保存尾随空格(例如,示例中结束1后的空格),可以在nul-终止上面的字符串之前添加以下内容:

代码语言:javascript
运行
复制
  if (!postcomma) {                 /* if tailing whitespace wanted */
    while (spcount--) {             /* append spcount spaces to newstr */
      *newstr++ = ' ';
    }
  }

把它组合在一起是一个简短的例子:

代码语言:javascript
运行
复制
#include <stdio.h>
#include <ctype.h>

void rmdelimws (char *newstr, const char *old)
{
  size_t spcount = 0;               /* space count */
  int postcomma = 0;                /* post comma flag */
  
  while (*old) {                    /* loop each char in old */
    if (isspace (*old)) {           /* if space? */
      spcount += 1;                 /* increment space count */
    }
    else if (*old == ',') {         /* if comma? */
      *newstr++ = ',';              /* write to new string */
      spcount = 0;                  /* reset space count */
      postcomma = 1;                /* set post comma flag true */
    }
    else {                          /* normal char? */
      if (!postcomma) {             /* if not 1st char after comma */
        while (spcount--) {         /* append spcount spaces to newstr */
          *newstr++ = ' ';
        }
      }
      spcount = postcomma = 0;      /* reset spcount and postcomma */
      *newstr++ = *old;             /* copy char from old to newstr */
    }
    old++;                          /* increment pointer */
  }
  *newstr = 0;                      /* nul-terminate newstr */
}


int main (void) {
  
  char str[] = "NA ME, NAME   , 123 456, 124   , 14134, 134. 134   ,   1   ",
       newstr[sizeof str] = "";
  
  rmdelimws (newstr, str);
  
  printf ("\"%s\"\n\"%s\"\n", str, newstr);
}

示例使用/输出

代码语言:javascript
运行
复制
$ ./bin/rmdelimws
"NA ME, NAME   , 123 456, 124   , 14134, 134. 134   ,   1   "
"NA ME,NAME,123 456,124,14134,134. 134,1"
票数 2
EN

Stack Overflow用户

发布于 2022-05-09 19:50:58

下面的工作,至少对您的输入字符串。我绝对没有说它的效率和优雅。我没有尝试修改s,而是写到一个新的字符串中。我遵循的算法是:

  • startPos初始化为0。
  • 循环s,直到找到逗号为止。
  • 从那个位置备份,直到找到第一个非空格字符。
  • memcpystartPos到那个位置到一个新字符串。
  • 在新字符串的下一个位置添加一个逗号。
  • 从逗号位置向前看,直到找到第一个非空格字符,将其设置为startPos
  • 冲洗和重复
  • 在最后,用strcat追加最后的令牌
代码语言:javascript
运行
复制
void removeWhiteChars(char *s)
{
    size_t i = 0;
    size_t len = strlen(s);
    char* newS = calloc(1, len);
    size_t newSIndex = 0;
    size_t startPos = 0;

    while (i<len)
    {
        // find the comma
        if (s[i] == ',')
        {            
            // find the first nonspace char before the comma
            ssize_t before = i-1;
            while (isspace(s[before]))
            {
                before--;
            }
            
            // copy from startPos to before into our new string
            size_t amountToCopy = (before-startPos)+1;
            memcpy(newS+newSIndex, s+startPos, amountToCopy);
            newSIndex += amountToCopy;
            newS[newSIndex++] = ',';

            // update startPos
            startPos = i+1;
            while (isspace(s[startPos]))
            {
                startPos++;
            }
            
            // update i
            i = startPos+1;
        }
        else
        {
            i++;
        }
    }

    // finally tack on the end
    strcat(newS, s+startPos);

    // You can return newS if you're allowed to change your function
    // signature, or strcpy it to s
    printf("%s\n", newS);    
}

我还用您的输入字符串测试了它,它可能会在其他情况下中断。

游行示威

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72176391

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档