在C中分隔可以有任意空格的字符串

在C中分隔可以有任意空格的字符串,c,whitespace,c-strings,C,Whitespace,C Strings,我有一个字符串数组,需要将每个字符串分成几个不同的部分。字符串可能有也可能没有任意空格和制表符 Example string: str[0]: " apple e 3 a a fruit " I need it to become: word[0] = "apple" row[0] = "e" column[0] = "3" direction[0] = "a" clue[0] = "a fruit" 因此,我需要删除任何前导/尾随空格,以及除线索字段之外的字段

我有一个字符串数组,需要将每个字符串分成几个不同的部分。字符串可能有也可能没有任意空格和制表符

Example string:
str[0]: "   apple  e     3   a     a fruit    "
I need it to become:
word[0] = "apple"
row[0] = "e"
column[0] = "3"
direction[0] = "a"
clue[0] = "a fruit"
因此,我需要删除任何前导/尾随空格,以及除线索字段之外的字段之间的任何空格。线索中的空间需要保留。我真的不知道该怎么做。我有一些基本的想法,但我不知道如何去实现它们,或者它们是否对编码有新的能力,并且相当无知。到目前为止,我所尝试的一切要么无法编译,要么无法工作

我最近尝试拉出第一个字段:

for (i=0; i<MAX_LENGTH; i++) {
   for (j=0; j<MAX_INPUT; j++) {
      if (isSpace(&input[i][j]) == FALSE) {
      //if whitespace is not present, find the location of the next
      //space and copy the string up til there
         static int n = j;

         for (n=0; n<MAX_INPUT; n++) {
            if (isSpace(&input[i][n]) == TRUE) {
               strncpy(word[i],&input[i][j],(n-j));
               //printf("Word[%d]: %s\n",i,word[i]);
               break;
            }
         }

      }
   }
}

它不起作用并不奇怪。我还没有完全理解这个问题。请帮忙?

您当前的代码似乎太复杂了。下面是一个三步算法,如果我对其进行编码,我将实现该算法:

当前角色为空格时:移动到下一个角色; 当当前字符不是空格时:将其附加到输出中,然后移动到下一个字符; 重复步骤1和2,直到到达输入字符串的末尾。 您可以使用strtok_r函数。 它将字符串拆分为标记,由您选择的内容分隔


只需使用sscanf阅读由空格分隔的“单词”:

char str[][100] = { "   apple  e     3   a     a fruit    ", ... }
char word[100][100],row[100][100],column[100][100],direction[100][100],clue[100][100];
int i;

for( i=0; i<...; ++i )
  sscanf(str[i],"%s%s%s%s%[^\n]",word[i],row[i],column[i],direction[i],clue[i]);

首先将n设置为j,然后在最里面的循环中始终将n重置为零。完全可以一次性解析,但可以在解析之前修剪/规范化输入中的空格。什么是strtok\r?这似乎不是标准的。strtok已经足够了。strtok_r是strtok的可重入版本。后者使用静态变量,这使得它在多线程情况下不可用。@nhahtdh,我更喜欢避免使用strtok,不管多线程,因为它很脆弱,例如在嵌套循环中使用时会失败。我认为只使用strtok_r是一种很好的做法。@ugoren:我认为你应该将这些信息添加到你的答案中,再加上strtok_r仅在POSIX平台上可用这一事实。对于最后一部分,即允许使用空格的线索,这样做是不对的。或者,可以递归地用一个空间替换两个空间的每次出现。它的效率不是很高,但最终会将任何一组空间缩减为一个空间,并且到此为止。如果您的输入中有空格/制表符混合,则会变得更加复杂。如果strlen恰好为零,trimEnd将做一些糟糕的事情。
char str[][100] = { "   apple  e     3   a     a fruit    ", ... }
char word[100][100],row[100][100],column[100][100],direction[100][100],clue[100][100];
int i;

for( i=0; i<...; ++i )
  sscanf(str[i],"%s%s%s%s%[^\n]",word[i],row[i],column[i],direction[i],clue[i]);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char *trimEnd(char *str){
    char *p;
    if(str == NULL || *str == '\0') return str;
    p=str+strlen(str);
    while(isspace(*--p) && p >= str){
        *p = '\0';
    }
    return str;
}

int main(){
    char str[100][100] = { "   apple  e     3   a     a fruit    " };
    char word[100][100], row[100][100], column[100][100], direction[100][100], clue[100][100];
    const char *delim= " \t";
    int i;
    const dataSize = 1;//for sample

    for(i=0;i<dataSize;++i){
        char *pwk, *p = strdup(str[i]);
        strcpy(word[i], strtok(p, delim));
        strcpy(row[i], strtok(NULL, delim));
        strcpy(column[i],strtok(NULL, delim));
        strcpy(direction[i], pwk=strtok(NULL, delim));
        pwk = pwk+strlen(pwk)+1;
        strcpy(clue[i], trimEnd(pwk+strspn(pwk, delim)));
fprintf(stderr,"DEBUG:%s,%s,%s,%s,%s.",word[i],row[i],column[i],direction[i],clue[i]);
        free(p);
    }

    return 0;
}