Home > Back-end >  Splitting a string without a delimeter in c
Splitting a string without a delimeter in c

Time:01-06

I want to trim this string below (which is a log.txt file) into the substring below.
Since there are no delimeters, I can't use strtok().
So how could I do it?
Log file's contents:

[INFO][2019-10-2323:21:45.638]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0001"}
[INFO][2019-10-2323:22:11.936]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0001"}
[INFO][2019-10-2323:22:29.232]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0002"}
[INFO][2019-10-2323:22:29.256]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0002"}
[INFO][2019-10-2323:22:33.192]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0003}
[INFO][2019-10-2323:22:48.075]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0003"}
[INFO][2019-10-2323:22:48.098]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0004"}
[INFO][2019-10-2323:22:52.034]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0004"}
[INFO][2019-10-2323:25:58.509]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0005"}
[INFO][2019-10-2323:26:42.425]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0005"}
[INFO][2019-10-2323:27:15.467]{"cmd":"set","objects":[{"type":"switch","data":["zwave-dc53:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"DC530401010001","reqid": "0006"}
[INFO][2019-10-2323:27:42.030]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-dc53:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"DC53010401000000","reqid": "0006"}
[INFO][2019-10-2323:32:45.088]{"cmd":"set","objects":[{"type":"switch","data":["zwave-ffa2:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"FFA20401010001","reqid": "0033"}
[INFO][2019-10-2323:33:11.934]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-ffa2:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"FFA2010401000000","reqid": "0007"}
[INFO][2019-10-2323:36:39.262]{"cmd":"set","objects":[{"type":"switch","data":["zwave-ffa2:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"FFA20401010001","reqid": "0008"}
[INFO][2019-10-2323:36:39.267]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-ffa2:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"FFA2010401000000","reqid": "0008"}
[INFO][2019-10-2323:36:39.267]{"cmd":"set","objects":[{"type":"switch","data":["zwave-ffa2:4-1"],"execution":{"command":"OnOff","params":{"on":true}}}],"raw":"FFA20401010001","reqid": "0022"}
[INFO][2019-10-2323:36:39.332]{"cmd":"status","objects":[{"bridge_key":"zwave","data":[{"hash":"zwave-ffa2:8-0","states":{"OnOff":{"on":false}}}],"type":"switch"}],"raw":"FFA2010401000000","reqid": "0009"}

The substring I want to find is the raw data's value, for example: FFA2010401000000

CodePudding user response:

This should work to extract the raw data, assuming it's hex-encoded data (error checking, memory freeing, and proper headers are omitted for clarity):

#define RAW_STR ",\"raw\":\""

FILE *logfile = fopen( filename, "rb" );

char *line = NULL;
size_t len = 0;

for ( ;; )
{
    ssize_t bytesRead = getline( &line, &len, logfile );
    if ( bytesRead == -1 )
    {
        break;
    }

    char *rawData = strstr( line, RAW_STR );
    if ( !raw )
    {
        continue;
    }

    // jump over the "raw":" string to the  actual value
    rawData  = strlen( RAW_STR );

    // assume the data is hex
    unsigned long long value = strtoull( rawData, NULL, 16 );

    ...
}

This simple method depends on the log file being consistently formatted. If the log file doesn't always have the RAW_STR in that exact format, it won't work.

I've also assumed you're running on a POSIX system and have access to getline().

CodePudding user response:

You might find regular expression useful in this scenario. Specifically regexec seems appropriate here.

int regexec(const regex_t *preg, const char *string, size_t nmatch,
            regmatch_t pmatch[], int eflags);

Or a proper json parser. Checkout the c library section on the json format description website.

  •  Tags:  
  • Related