0

嗨朋友们正在从文件中读取数据并在“,”的帮助下分隔值。输入文件:

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 

因为在第二行中间数据的输入文件中为空?你能帮我解决这个问题吗?我知道发生这种情况是因为输入文件的第二行中的 , 之间没有空格?请告诉我还有其他替代方法吗?或者我应该在读取之前更改输入文件?

4

5 回答 5

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]

如你所愿。它只处理分隔符的单个字符,但在这种情况下似乎就足够了。

于 2011-04-20T07:34:10.540 回答
2

从联机帮助页:“解析字符串中两个或多个连续分隔符的序列被认为是单个分隔符。字符串开头或结尾的分隔符被忽略。换句话说:strtok() 返回的标记总是非空字符串。”

因此,如果您必须使用 strtok,则必须先以某种方式修改输入。

于 2011-04-20T07:18:39.950 回答
0

您可以检查每个的长度item以确保它不为 0。

更好的是,将此与循环每一行(example)结合起来,这样您就不会局限于三个值。

于 2011-04-20T07:16:07.020 回答
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]
==========

您需要注意没有足够分隔符(或太多)的情况,但这应该是一个小的修改。

于 2011-04-20T08:11:32.423 回答
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);
}

我没有测试上面的代码,所以可能会有一些小缺陷。不过,主要思想应该很清楚。

于 2011-04-20T08:31:50.373 回答