strtok - 如何避免换行和放入字符串数组?

时间:2011-03-01 14:54:20

标签: c arrays string split strtok

如果我愚蠢的主题我真的很抱歉,我搜索它没有结果在这里。 我有代码

void split(char* str, char* splitstr)
{
     char* p;
     char splitbuf[32];
     int i=0;
     p = strtok(str,",");
     while(p!= NULL)
     {
               printf("%s", p);    
               sprintf(&splitstr[i],"%s",p);
               i++;
               p = strtok (NULL, ",");

     }
}

我如何使用正确的sprintf将strtok的分裂单词放入字符串数组? 我可以以某种方式避免strtok创建的breaklines吗? 我在ANSI C编程。我以相同的方式声明了数组splitstr和str。

char* splitstr;//in main char splitstr[32];

感谢您的帮助。


编辑:

i would like do something like this:
INPUT (it is a string) > "aa,bbb,ccc,ddd"
I declare: char tab[33];
OUTPUT (save all items to array of strings if it is even possible) > 
tab[0] is "aa"
tab[1] is "bbb"
...
tab[3] is "ddd" but not "ddd(newline)"

edit2 [18:16]

我忘了添加数据字符串来自文件的读取行。这就是我写“ddd(换行)”的原因。之后我发现新线也是由strtok展示的,但作为另一个项目。顺便说一句,所有答案都可以很好地思考问题。几秒钟前我的笔记本电脑坏了(我不知道为什么屏幕变黑)一旦我控制了我的电脑,我就会检查代码。 : - )

3 个答案:

答案 0 :(得分:1)

如果我理解正确,你想保存strtok获得的字符串。在这种情况下,你需要将splitstr声明为char [MAX_LINES] [32]并使用strcpy,如下所示:

strcpy(splitstr[i], p);

其中i是使用strtok读取的第i个字符串。

答案 1 :(得分:1)

请注意,我不是ansi C专家,更多是C ++专家,但这里是工作代码。它使用固定大小的数组,这可能是也可能不是问题。要做任何其他事情,需要更复杂的内存管理:

/* Not sure about the declaration of splitstr here, and whether there's a better way.
   char** isn't sufficient. */
int split(char* str, char splitstr[256][32])
{
   char* p;
   int i=0;
   p = strtok(str,",");
   while(p) {
   strcpy(splitstr[i++], p);
       p = strtok (NULL, ",");
   }
   return i;
}

int main(int argc, char* argv[])
{
 char input[256];
  char result[256][32];
  strcpy(input, "aa,bbb,ccc,ddd");
  int count = split(input, result);

  for (int i=0; i<count; i++) {
    printf("%s\n", result[i]);
  }
      printf("the end\n");
}

请注意,我提供“aa,bbb,ccc,ddd”,我得到{“aa”,“bbb”,“ccc”,“ddd”}。结果没有换行。

答案 2 :(得分:1)

试一试:

#include <stdlib.h>
#include <string.h>
...
void split(char *str, char **splitstr) 
{      
  char *p;      
  int i=0;      

  p = strtok(str,",");      
  while(p!= NULL)      
  {                
    printf("%s", p);
    splitsr[i] = malloc(strlen(p) + 1);
    if (splitstr[i])
      strcpy(splitstr[i], p);
    i++;
    p = strtok (NULL, ",");       
  } 
}

然后,在main

#define MAX_LEN  ... // max allowed length of input string, including 0 terminator
#define MAX_STR  ... // max allowed number of substrings in input string

int main(void)
{
  char input[MAX_LEN]; 
  char *strs[MAX_STR] = {NULL}; 
  ...
  split(input, strs);
  ...
}

一些解释。

strsmain中定义为指向char的指针数组。每个数组元素都将指向从输入字符串中提取的字符串。在main中,所有分配的是指针数组,每个元素最初为NULL;根据子字符串的长度,使用splitmalloc函数内分配每个元素的内存。在完成strs之后某处,您将需要使用free解除分配这些指针:

for (i = 0; i < MAX_STR; i++)
  free(strs[i]);

现在,为什么splitstr声明为char **而不是char *[MAX_STR]?除非它是sizeof&运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,否则数组表达式将从{{1}隐式转换其类型}到N-element array of T,表达式的值将是数组中第一个元素的位置。

当我们致电pointer to T时:

split

数组表达式split(input, strs); 隐式地从类型input转换为char [MAX_LENGTH](T == char *),并且数组表达式char被隐式转换从类型strschar *[MAX_STRS](T == char **)。因此char *接收两个参数的指针值,而不是数组值。