需要有关 strtok 函数的想法吗?

发布于 2024-11-02 10:11:49 字数 652 浏览 3 评论 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 

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

hi friends am reading the data from the file and delimiting the value with the help of ','.
input file:

shankar,kumar,ooty
ravi,,cbe

code:

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);
}

for the above input file output like:

1:shankar 2:kumar 3:ooty
1:ravi 2:cbe 3:

but i need output like,

1:shankar 2:kumar 3:ooty
1:ravi 2: 3:cbe 

because in the input file for the second row middle data is null? could you please help me on this?
i know this happens because no space between ,, in the second row of input file?please tell me any other alternative way? or i should for alter the input file before it read?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

往日情怀 2024-11-09 10:11:49

没有什么可以阻止您编写自己的自己 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]

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

There's nothing stopping you from coding up your own strtok-like function:

#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;
}

This outputs:

1: [shankar]
2: [kumar]
3: [ooty]
==========
1: [ravi]
2: []
3: [cbe]
==========
[shankar,kumar,ooty] [ravi,,cbe]

as you desire. It only handles a single character for the separator but that appears to be adequate in this case.

顾北清歌寒 2024-11-09 10:11:49

来自联机帮助页:“两个或多个连续分隔符的序列
解析后的字符串被视为单个分隔符。字符串开头或结尾的分隔符将被忽略。再放一个
方式:strtok() 返回的标记始终是非空字符串。”

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

From the manpage: "A sequence of two or more contiguous delimiter characters in the
parsed string is considered to be a single delimiter. Delimiter characters at the start or end of the string are ignored. Put another
way: the tokens returned by strtok() are always nonempty strings."

So if you must use strtok, you will have to modify the input first somehow.

别念他 2024-11-09 10:11:49

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

更好的是,将其与循环每行结合起来 (示例),以便您不限于三个值。

You could check the length of each item to make sure it's not 0.

Better yet, combine this with looping each line (example) so that you're not limited to three values.

ぶ宁プ宁ぶ 2024-11-09 10:11:49

如果 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]
==========

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

If strtok cannot do the job you want, you can code up your own parser, something along the lines of:

#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;
}

That little sample shows you the difference between a strtok solution and a manual strchr solution, the output being:

1: [shankar]
2: [kumar]
3: [ooty]
==========
1: [ravi]
2: []
3: [cbe]
==========

You'll need to watch out for cases where you don't have enough delimiters (or too many) but that should be a minor modification.

难得心□动 2024-11-09 10:11:49

这是我无耻地从 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);
}

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

Here's a technique that I shamelessly copied from 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);
}

I didn't test the above code, so there may be some minor flaws. The main idea should be clear, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文