【问题标题】:How can i use strtok?如何使用 strtok?
【发布时间】:2020-09-21 00:42:46
【问题描述】:
{"2014-02-13T06:20:00": "3.0", "2014-02-13T13:50:00": "7.0", "2014-02-13T06:00:00": "2", "2014-02-13T03:00:00": "3", "2014-02-13T13:00:00": "6", "2014-02-13T18:50:00": "4.0", "2014-02-13T13:20:00": "6.0", "2014-02-13T15:00:00": "6", "2014-02-13T08:50:00": "4.0", "2014-02-13T21:50:00": "4.0", "2014-02-13T08:00:00": "3", "2014-02-13T07:50:00": "3.0", "2014-02-13T08:20:00": "4.0", "2014-02-13T21:20:00": "3.0", "2014-02-13T11:50:00": "6.0", "2014-02-13T11:20:00": "6.0", "2014-02-13T17:50:00": "5.0", "2014-02-13T11:00:00": "6", "2014-02-13T05:50:00": "2.0", "2014-02-13T20:50:00": "3.0", "2014-02-13T20:20:00": "4.0", "2014-02-13T16:00:00": "6", "2014-02-13T23:50:00": "2.0", "2014-02-13T21:00:00": "3", "2014-02-13T07:20:00": "3.0", "2014-02-13T03:20:00": "3.0", "2014-02-13T07:00:00": "3", "2014-02-13T15:50:00": "6.0", "2014-02-13T03:50:00": "2.0", "2014-02-13T04:00:00": "2", "2014-02-13T12:00:00": "6", "2014-02-13T04:20:00": "2.0", "2014-02-13T12:20:00": "6.0", "2014-02-13T12:50:00": "6.0", "2014-02-13T22:50:00": "3.0", "2014-02-13T09:00:00": "4", "2014-02-13T09:20:00": "4.0", "2014-02-13T09:50:00": "4.0", "2014-02-13T18:00:00": "5", "2014-02-13T05:20:00": "2.0", "2014-02-13T15:20:00": "6.0", "2014-02-13T00:50:00": "4.0", "2014-02-13T14:50:00": "7.0", "2014-02-13T00:00:00": "4", "2014-02-13T00:20:00": "4.0", "2014-02-13T06:50:00": "3.0", "2014-02-13T22:00:00": "4", "2014-02-13T18:20:00": "5.0", "2014-02-13T02:50:00": "3.0", "2014-02-13T02:20:00": "3.0", "2014-02-13T04:50:00": "2.0", "2014-02-13T02:00:00": "3", "2014-02-13T23:00:00": "3", "2014-02-13T16:50:00": "5.0", "2014-02-13T19:50:00": "4.0", "2014-02-13T19:20:00": "4.0", "2014-02-13T05:00:00": "2", "2014-02-13T19:00:00": "4", "2014-02-13T23:20:00": "3.0", "2014-02-13T14:20:00": "7.0", "2014-02-13T10:20:00": "5.0", "2014-02-13T10:00:00": "4", "2014-02-13T10:50:00": "5.0", "2014-02-13T17:00:00": "5", "2014-02-13T01:00:00": "4", "2014-02-13T17:20:00": "5.0", "2014-02-13T01:20:00": "4.0", "2014-02-13T01:50:00": "4.0", "2014-02-13T22:20:00": "3.0", "2014-02-13T16:20:00 :"6.0"}

我有这段文字,它代表(例如): 日期 -> 2014-02-13T06:20:00 湿度率 -> 4.0

起初,我想有一个输出日期\n湿度率\n日期\n湿度率等。我尝试使用strtok,但我做不了太多。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINESIZE 128

int main()
{
    FILE *fp = fopen("tempm.txt", "r");
    char line[LINESIZE];
    char *value;

    while(fgets(line, sizeof(line), fp))
    {
        value = strtok(line, "\" \":");
        printf("\n%s", value);  
    }

    return 0;
}

这是我目前写的代码。

【问题讨论】:

  • 从您发布的内容看来,您可以在 1 行中获得所有内容。对吗?
  • 既然看起来像 JSON 数据,为什么不试试 JSON 解析器呢?如果您真的想使用strtok,请查看如何正确使用它。第一次调用strtok 时,您将缓冲区传递给解析。如果要继续解析缓冲区,请使用 NULL 调用 strtok 而不是新缓冲区。
  • 您必须知道您不能使用strtok 进行嵌套解析。 IE。您只能在一组数据后拆分输入,而不是在该组内。此外,为分隔符传递的字符串并不表示子字符串,而是一组充当分隔符的单个字符。正如 Cheatah 已经建议的那样,使用一些 JSON 解析器会更容易。
  • @Gerhard - 您必须知道您不能使用 strtok 进行嵌套解析。 这不是真的。对于可重复的、明确定义的输入,例如给定的内容,可以有效地使用对 strtok 的嵌套调用。
  • strtok 有点原始,如果可能我会避免它。

标签: c file output strtok


【解决方案1】:

fscanf 使用扫描集可能会起作用。

#include <stdio.h>
#include <stdlib.h>

int main ( void) {
    char *filename = "tempm.txt";
    char date[30] = "";
    char humidity[30] = "";
    FILE *fp = NULL;
    if ( NULL == ( fp = fopen ( filename, "r"))) {
        perror ( filename);
        exit ( EXIT_FAILURE);
    }
    fscanf ( fp, "%*[^0123456789]");//scan and discard up to first digit
    while ( 1 == fscanf ( fp, "%29[^\"]", date)) {//scan up to a quote
        fscanf ( fp, "%*[^0123456789]");//scan and discard up to next digit
        if ( 1 == fscanf ( fp, "%29[^\"]", humidity)) {//scan up to a quote
            printf ( "%s\n%s\n", date, humidity);
        }
        fscanf ( fp, "%*[^0123456789]");//scan and discard up to next digit
    }
    fclose ( fp);
    return 0;
}

【讨论】:

    【解决方案2】:

    您显示的数据似乎更适合使用JSON parser。 (但那不是你问的。)

    如何使用 strtok?
    首先,研究输入数据的模式。你的是可重复的,使strtok() 的使用可行,但它的格式化方式将使解析变得有趣。

    对于您提供的输入文件,分隔符很不幸!例如在时间字符串段之间使用“:”分隔符,并且在用于湿度的第二个子字符串前面:

    "2014-02-13T06:20:00": "3.0", 
                  ^  ^   ^
                  |  |   |_this would be better as a comma ","
                  |__|_____These are fine as is
    

    但只要输入文件实际上是你所拥有的形状,下面的代码就会解析它。

    对于您的问题:我如何使用 strtok?,下面的实现说明了如何做到这一点。它结合使用嵌套的strtok() 和对strchr() 的调用来遍历文件,将每个项目分成变量。

    int fsize(FILE *fp);
    
    int main(void)
    {
        FILE *fp = fopen("tempm.txt", "r");
    
        char *value;
        char hr[4];
        char min[4];
        char sec[4];
        char date[12];
        char hum_rate[6];
        char *data;
        char line[100][50];//change if file size changes!
        double num = 0.0;
    
        char *tok;
    
        int filesize = fsize(fp);//get file size
        data = calloc(filesize+1, 1);//size the buffer to contain file contents
        if(!data) //failed, exit
        {
            return 0    
        }
        fgets(data, filesize+1, fp);//read file int buffer (its one line)
    
       int i = 0;
        value = strtok(data, ",");//get string segmemts
        while(value)
        {   //separate into data into date-time-hum_rate segments
            strcpy(line[i++], value);//line segments
            value = strtok(NULL, ",");
        }
        //we now have data segments separated
        int count = i;//preserve value of i into count
        for(i=0;i<count;i++)
        {
            value = strtok(line[i], "T");//get date
            if(value)
            {
                tok = strchr(value, '"');
                strcpy(date, tok+1);//consume the extra "
                value = strtok(NULL, ":");//hour
                if(value)
                {
                    strcpy(hr, value);
                    value = strtok(NULL, ":");//minute
                    if(value)
                    {
                        strcpy(min, value);//second
                        value = strtok(NULL, ":\"");
                        if(value)
                        {
                            strcpy(sec, value);
                            value = strtok(NULL, ":");//humidity
                            if(value)
                            {
                                tok = strchr(value, '"');//consume the extra "
                                num = strtod(tok+1, NULL);
                                sprintf(hum_rate, "%.1lf", num);
                            }
                        }
                    }
                }
            }
            //output to test results:
            printf("%d)\nDate: %s\nTime: %s:%s:%s\nHumidity Rate: %s\n\n", i+1, date, hr, min, sec, hum_rate);
            free(data);
        }
    
        return 0;
    }
    
    int fsize(FILE *fp)
    {
        int prev=ftell(fp);
        fseek(fp, 0L, SEEK_END);
        int sz=ftell(fp);
        fseek(fp,prev,SEEK_SET); //go back to where we were
        return sz;
    }
    

    【讨论】:

    • 反对的选民愿意发表评论吗?我知道使用strtok() 存在敌意,但这个答案只是直接响应 OP 关于如何使用它的明确请求。
    猜你喜欢
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    相关资源
    最近更新 更多