字符串解析C - 字符串与fomat说明符

时间:2018-05-17 08:30:20

标签: c string c-strings

我收到的日志文件看起来像

system%s disconnected: IP%s %s:%s,"1","100.100.100.100","port","1000"
Login by user %s,"TestUserName"
connecting to system%s,"29" 
Newlog by %s on %s,"TestUser2","Wednesday"

我需要转换为,

system1 disconnected: 100.100.100.100 port 1000
Login by user TestUserName
connecting to system29
Newlog by TestUser2 on Wednesday

到目前为止,我已将此字符串拆分为2个字符串,part1将包含具有格式说明符的字符串,Part2包含info / data。 例如:

1)
part1 = system%s disconnected: IP%s %s:%s
part2 =  "1","100.100.100.100","port","1000"

2) 
part1 = Login by user %s
part2 = "TestUserName"

3)
part1 = connecting to system%s
part2 = "29" 

我想用sprintf来获得所需的输出,

sprintf(testString,"%s,%s", part1, part2);
printf(testString); //This doesn't work.

printf("system%s disconnected: IP%s %s:%s","1","100.100.100.100","port","1000"); //This works, but not sure of getting here

1 个答案:

答案 0 :(得分:0)

我使用strtok来标记由','分隔的行。进入代币。我编写了非常简单的函数来从字符串中删除前导和结尾撇号。可能需要重写解析函数以更好地处理','内部字符串(尝试ao_string_tokenize)。以下程序:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#define DBG(...) do;while(0) 
//#define DBG(...) fprintf(stderr, __VA_ARGS__)
char *remove_leading_and_closing_apostrophe(char *str)
{
    if (str == NULL) 
        return str;
    if (str[0] == '"')
        ++str;
    size_t strleng = strlen(str);
    if (str[strleng - 1] == '"')
        str[strleng - 1] = '\0';
    return str;
}
int main()
{
    const char s[2] = ",";
    char line[200];
    const char *args[7];
    size_t argscnt = 0;
    while (fgets(line, 200, stdin) != NULL) {
        // remove newline
        assert(line[strlen(line)-1] == '\n');
        line[strlen(line)-1] = '\0';

        DBG("@ read line '%s'\n", line);

        argscnt = 0;
        args[argscnt] = strtok(line, s);
        assert(args[argscnt] != NULL); // not handled correctly
        DBG("@ read arg[%zu]='%s'\n", argscnt, args[argscnt]);
        argscnt++;
        assert(argscnt <= sizeof(args)/sizeof(args[0]));
        while (args[argscnt-1] != NULL) {
            args[argscnt] = remove_leading_and_closing_apostrophe(strtok(NULL, s));
            DBG("@ read arg[%zu]='%s'\n", argscnt, args[argscnt]);
            argscnt++;
            assert(argscnt <= sizeof(args)/sizeof(args[0]));
        }
        argscnt--; // incremented one time too much, FIXME

        const char * const * const a = args; // just shorter name
        // This is the most portable way.
        switch(argscnt) {
        case 0: break;
        case 1: printf(a[0]); break;
        case 2: printf(a[0],a[1]); break;
        case 3: printf(a[0],a[1],a[2]); break;
        case 4: printf(a[0],a[1],a[2],a[3]); break;
        case 5: printf(a[0],a[1],a[2],a[3],a[4]); break;
        case 6: printf(a[0],a[1],a[2],a[3],a[4],a[5]); break;
        case 7: printf(a[0],a[1],a[2],a[3],a[4],a[5],a[6]); break;
        default: assert(0); break;
        }
        puts("");
    }
    return 0;
}

用于stdin上的以下输入(格式正确,末尾有空换行符):

system%s disconnected: IP%s %s:%s,"1","100.100.100.100","port","1000"
Login by user %s,"TestUserName"
connecting to system%s,"29"
Newlog by %s on %s,"TestUser2","Wednesday"

产生以下输出:

system1 disconnected: IP100.100.100.100 port:1000
Login by user TestUserName
connecting to system29
Newlog by TestUser2 on Wednesday