从C字符串中删除多余的空白?(Remove extra white space from insid

2019-07-18 22:29发布

我已阅读文本的几行成C-字符串数组。 该行有标签或空格分隔栏的任意号码,我试图找出如何删除它们之间的所有多余的空格。 最终目标是使用的strtok分手列。 这是列的一个很好的例子:

Cartwright   Wendy    93
Williamson   Mark     81
Thompson     Mark     100
Anderson     John     76
Turner       Dennis   56

我怎样才能消除所有,但列之间的空格或制表符的一个,这样的输出是这样的?

Cartwright Wendy 93

另外,可我只是一个不同的字符全部替换列之间的空白,以使用strtok的? 像这样的事情?

Cartwright#Wendy#93

编辑:多伟大的答案,但必须选择一个。 感谢您的帮助所有。

Answer 1:

如果可能我的声音“你这样做是错误的”的意见,为什么不消除空白而读? 使用fscanf("%s", string); 读一个“字”(无空格),然后读取空白。 如果是空格或制表符,请继续阅读到数据的一个“行”。 如果它是一个新行,开始新的条目。 这可能比较容易在C获取数据到的格式,你可以用尽快工作,而不是试图做重型文本操作。



Answer 2:

为什么不使用strtok()直接? 无需修改输入

所有你需要做的就是重复strtok()直到你得到3个非空间令牌,然后你做!



Answer 3:

编辑 :我原来有一个malloced工作区,我虽然可能会更清晰。 然而,这样做W / O额外的内存几乎一样简单,而且我被推评论和个人即时这样,所以,在这里来... ... :-)

void squeezespaces(char* row, char separator) {
  char *current = row;
  int spacing = 0;
  int i;

  for(i=0; row[i]; ++i) {
    if(row[i]==' ') {
      if (!spacing) {
        /* start of a run of spaces -> separator */
        *current++ = separator
        spacing = 1;
      }
    } else {
      *current++ = row[i];
      spacing = 0;
  }
  *current = 0;    
}


Answer 4:

The following code modifies the string in place; if you don't want to destroy your original input, you can pass a second buffer to receive the modified string. Should be fairly self-explanatory:

#include <stdio.h>
#include <string.h>

char *squeeze(char *str)
{
  int r; /* next character to be read */
  int w; /* next character to be written */

  r=w=0;
  while (str[r])
  {
    if (isspace(str[r]) || iscntrl(str[r]))
    {
      if (w > 0 && !isspace(str[w-1]))
        str[w++] = ' ';
    }
    else
      str[w++] = str[r];
    r++;
  }
  str[w] = 0;
  return str;
}

int main(void)
{
  char test[] = "\t\nThis\nis\ta\b     test.";
  printf("test = %s\n", test);
  printf("squeeze(test) = %s\n", squeeze(test));
  return 0;
}


Answer 5:

char* trimwhitespace(char *str_base) {
    char* buffer = str_base;
    while((buffer = strchr(str_base, ' '))) {
        strcpy(buffer, buffer+1);
    }

    return str_base;
}


Answer 6:

你可以读取一行然后扫描它来寻找每一列的开始。 然后使用列数据,但是你会喜欢。

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

#define MAX_COL 3
#define MAX_REC 512

int main (void)
{
    FILE *input;
    char record[MAX_REC + 1];
    char *scan;
    const char *recEnd;
    char *columns[MAX_COL] = { 0 };
    int colCnt;

    input = fopen("input.txt", "r");

    while (fgets(record, sizeof(record), input) != NULL)
    {
        memset(columns, 0, sizeof(columns));  // reset column start pointers

        scan = record;
        recEnd = record + strlen(record);

        for (colCnt = 0; colCnt < MAX_COL; colCnt++ )
        {
          while (scan < recEnd && isspace(*scan)) { scan++; }  // bypass whitespace
          if (scan == recEnd) { break; }
          columns[colCnt] = scan;  // save column start
          while (scan < recEnd && !isspace(*scan)) { scan++; }  // bypass column word
          *scan++ = '\0';
        }

        if (colCnt > 0)
        {
            printf("%s", columns[0]);
            for (int i = 1; i < colCnt; i++)
            {
             printf("#%s", columns[i]);
            }
            printf("\n");
        }
    }

    fclose(input);
}

请注意,该代码仍然可以使用一些稳健-ification:检查文件错误瓦特/ FERROR; 确保EOF被击中W / FEOF; 确保整个记录(所有列数据)中的溶液处理。 它也可以通过使用链接的列表,而不是一个固定的阵列,并且可以修改为不假定每列仅包含单个字更加灵活(只要列通过一个特定的字符分隔)。



Answer 7:

下面是挤出重复的空格字符,如通过定义一个替代函数isspace()<ctype.h> 。 它返回“squidged”字符串的长度。

#include <ctype.h>

size_t squidge(char *str)
{
    char *dst = str;
    char *src = str;
    char  c;
    while ((c = *src++) != '\0')
    {
        if (isspace(c))
        {
            *dst++ = ' ';
            while ((c = *src++) != '\0' && isspace(c))
                ;
            if (c == '\0')
                break;
        }
        *dst++ = c;
    }
    *dst = '\0';
    return(dst - str);
}

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buffer[256];
    while (fgets(buffer, sizeof(buffer), stdin) != 0)
    {
        size_t len = strlen(buffer);
        if (len > 0)
            buffer[--len] = '\0';
        printf("Before: %zd <<%s>>\n", len, buffer);
        len = squidge(buffer);
        printf("After:  %zd <<%s>>\n", len, buffer);
    }
    return(0);
}


Answer 8:

我取得了约翰·波特的小改良效果去除尾随空白,以及:

#include <ctype.h>

char *squeeze(char *str)
{
  char* r; /* next character to be read */
  char* w; /* next character to be written */
  char c;
  int sp, sp_old = 0;

  r=w=str;

  do {
    c=*r;
    sp = isspace(c);
    if (!sp) {
      if (sp_old && c) {
        // don't add a space at end of string
        *w++ = ' ';
      }
      *w++ = c;
    }
    if (str < w) {
      // don't add space at start of line
      sp_old = sp;
    }
    r++;
  }
  while (c);

  return str;
}

#include <stdio.h>

int main(void)
{
  char test[] = "\t\nThis\nis\ta\f     test.\n\t\n";
  //printf("test = %s\n", test);
  printf("squeeze(test) = '%s'\n", squeeze(test));
  return 0;
}

BR。



Answer 9:

下面的代码只是需要输入字符明智,然后检查每个角色是否有空间不止一次它跳过它否则打印的字符更多。 同样的逻辑也可以使用标签。 希望它可以帮助解决你的问题。 如果有任何问题,此代码,请让我知道。

    int c, count = 0;
    printf ("Please enter your sentence\n");
    while ( ( c = getchar() ) != EOF )  {
        if ( c != ' ' )  {
            putchar ( c );
            count = 0;
        }
        else  {
            count ++;
            if ( count > 1 )
                ;    /* Empty if body */
            else
                putchar ( c );
         }
     }
}


文章来源: Remove extra white space from inside a C string?