朋友们,我正在从文件中读取数据并借助','来分隔值。 输入文件:
shankar,kumar,ooty
ravi,,cbe
代码:
while ( fgets ( mem_buf, sizeof mem_buf, infile ) != NULL )
{
item = strtok(mem_buf,delims);
printf("1 val:%s",item);
item = strtok(NULL,delims);
printf("2 val:%s",item);
item = strtok(NULL,delims);
printf("3 val:%s",item);
}
对于上面的输入文件输出如:
1:shankar 2:kumar 3:ooty
1:ravi 2:cbe 3:
但我需要输出,
1:shankar 2:kumar 3:ooty
1:ravi 2: 3:cbe
因为在第二行的输入文件中,中间数据为空?你能帮帮我吗? 我知道这是因为在第二行输入文件之间没有空格吗?请告诉我任何其他替代方法?或者我应该在读取之前更改输入文件?
答案 0 :(得分:3)
没有什么可以阻止您编写自己的 strtok
- 就像函数一样:
#include <stdio.h>
#include <string.h>
static char *myStrTok (char *s, int c) {
static char *nextS = NULL; // Holds modified delimiter.
static int done = 1; // Flag to indicate all done.
// Initial case.
if (s != NULL) {
// Return NULL for empty string.
if (*s == '\0') { done = 1; return NULL; }
// Find next delimiter.
nextS = s;
while ((*nextS != c) && (*nextS != '\0')) nextS++;
done = (*nextS == '\0');
*nextS = '\0';
return s;
}
// Subsequent cases.
if (done) return NULL;
// Put delimiter back and find next one.
*nextS++ = c;
s = nextS;
while ((*nextS != c) && (*nextS != '\0')) nextS++;
done = (*nextS == '\0');
*nextS = '\0';
return s;
}
static int prt (char *s) {
char *s2 = myStrTok (s, ','); printf ("1: [%s]\n", s2);
s2 = myStrTok (NULL, ','); printf ("2: [%s]\n", s2);
s2 = myStrTok (NULL, ','); printf ("3: [%s]\n", s2);
s2 = myStrTok (NULL, ','); if (s2 != NULL) printf ("4: [%s]\n", s2);
printf ("==========\n");
}
int main (void) {
char x[] = "shankar,kumar,ooty"; char y[] = "ravi,,cbe";
prt (x); prt (y);
printf ("[%s] [%s]\n", x, y);
return 0;
}
输出:
1: [shankar]
2: [kumar]
3: [ooty]
==========
1: [ravi]
2: []
3: [cbe]
==========
[shankar,kumar,ooty] [ravi,,cbe]
如你所愿。它只处理分隔符的单个字符,但在这种情况下似乎足够了。
答案 1 :(得分:2)
从联机帮助页:“一个包含两个或多个连续分隔符的序列 解析的字符串被认为是单个分隔符。字符串开头或结尾的分隔符字符将被忽略。换一个 方式:strtok()返回的标记总是非空字符串。“
因此,如果你必须使用strtok,你将不得不以某种方式修改输入。
答案 2 :(得分:0)
您可以检查每个item
的长度,以确保它不是0.
更好的是,将它与循环每一行(example)结合起来,这样你就不会受限于三个值。
答案 3 :(得分:0)
如果strtok
无法完成您想要的工作,您可以对自己的解析器进行编码,类似于以下内容:
#include <stdio.h>
#include <string.h>
static int prt (char *s) {
char *s2;
s2 = strchr (s, ','); printf ("1: [%*.*s]\n", s2-s, s2-s, s); s = s2 + 1;
s2 = strchr (s, ','); printf ("2: [%*.*s]\n", s2-s, s2-s, s); s = s2 + 1;
printf ("3: [%s]\n", s);
printf ("==========\n");
}
int main (void) {
char x[] = "shankar,kumar,ooty"; char y[] = "ravi,,cbe";
prt (x2); prt (y2);
return 0;
}
该小样本显示了strtok
解决方案与手动strchr
解决方案之间的区别,输出为:
1: [shankar]
2: [kumar]
3: [ooty]
==========
1: [ravi]
2: []
3: [cbe]
==========
您需要注意没有足够分隔符(或太多分隔符)的情况,但这应该是一个小修改。
答案 4 :(得分:0)
这是我从Rob Pike无耻地复制的一种技术:
void print_tokens(char *s)
{
char *p, *last;
last = s;
for (p = strchr(s, ','); p; p=strchr(p+1, ',')){
*p = 0;
puts(last);
*p = ',';
last = p+1;
}
puts(last);
}
我没有测试上面的代码,因此可能存在一些小缺陷。不过,主要的想法应该是清楚的。