如何预期不同数量的空格sscanf

68bkxrlz  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(124)

我试图使用sscanf解析一个大的代理txt文件(即带有代理信息(ip,port,protocol.)的文件),我遇到了一个问题,其中有不相同长度的ip地址,如示例所示,该行留下了不同的空白:

72.210.221.197  4145    Socks5  United States   Elite   932ms   93.8%   10 minutes
176.98.90.20    8080    HTTP    Ukraine Elite   183ms   77.3%   4 minutes

在ip和port之间的第一行有2个空格,在第二行有4个空格。由于%s一直读到空格,sscanf有没有办法忽略所有的空格?

liwlm1x9

liwlm1x91#

一个非常简单的函数实现:

char **split(char **argv, int *argc, const char *str, const char *delimiter, int allowempty)
{
    char *string = malloc(strlen(str + 1));
    strcpy(string, str);
    *argc = 0;
    do
    {
        if(*string && (!strchr(delimiter, *string) || allowempty))
        {
            argv[(*argc)++] = string;
        }
        while(*string && !strchr(delimiter, *string)) string++;
        if(*string) *string++ = 0;
        if(!allowempty) 
            while(*string && strchr(delimiter, *string)) string++;
    }while(*string);

    for(int arg = 3; arg < *argc - 5 - 1; arg++)
    {
        argv[3][strlen(argv[3])] = ' ';
        memmove(&argv[4], &argv[arg + 2], sizeof(*argv) * (*argc - 4));
        *argc -= 1;
    }
    return argv;
}


int main(void)
{
    char *argv[20];
    char str[1024];
    int argc;

    while(fgets(str, sizeof(str), stdin))
    {
        split(argv, &argc, str, " ", 0);
        for(int arg = 0; arg < argc; arg++)
        {
            printf("arg[%d] = `%s`\n", arg, argv[arg]);
        }
        free(*argv);
        printf("\n");
    }
}

对于你的输入,它是:

arg[0] = `72.210.221.197`
arg[1] = `4145`
arg[2] = `Socks5`
arg[3] = `United States`
arg[4] = `Elite`
arg[5] = `932ms`
arg[6] = `93.8%`
arg[7] = `10`
arg[8] = `minutes
`

arg[0] = `176.98.90.20`
arg[1] = `8080`
arg[2] = `HTTP`
arg[3] = `Ukraine`
arg[4] = `Elite`
arg[5] = `183ms`
arg[6] = `77.3%`
arg[7] = `4`
arg[8] = `minutes`

PS它可以写得更好,但宿醉是禁止我的大脑形式太复杂的数学

v2g6jxz6

v2g6jxz62#

当人们仔细观察这两条样品线时,似乎这是一个TSV。制表符分隔值列表.如果文件确实包含制表符,那么去掉各个字段将是strtok()的一个简单用法。(scanf()处理 * 空白 *。任何这样的实现都是《双城之战》。)

#include <stdio.h>

int main( void ) {
    // simulate two lines of fgets() input
    char *strs[] = {
        "72.210.221.197\t4145\tSocks5\tUnited States\tElite\t932ms\t93.8%\t10 minutes\n",
        "176.98.90.20\t8080\tHTTP\tUkraine\tElite\t183ms\t77.3%\t4 minutes\n",
    };

    for( size_t i = 0; i < sizeof strs / sizeof strs[0]; i++ ) {
        char *flds[ 8 ];
        size_t nf = 0;

        for( char *cp = strs[i]; ( cp = strtok( cp, "\t\n" ) ) != NULL; cp = NULL )
            flds[ nf++] = cp;

        for( size_t j = 0; j < nf; j++ )
            printf( "'%s'\n", flds[ j ] );
        putchar( '\n' );
    }

    return 0;
}

测试结果:

'72.210.221.197'
'4145'
'Socks5'
'United States'
'Elite'
'932ms'
'93.8%'
'10 minutes'

'176.98.90.20'
'8080'
'HTTP'
'Ukraine'
'Elite'
'183ms'
'77.3%'
'4 minutes'

简单的解决方案是最好的解决方案。

相关问题