如何让 scanf 继续使用空扫描集 [英] How to get scanf to continue with empty scanset

查看:37
本文介绍了如何让 scanf 继续使用空扫描集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试解析 UnicodeData.txt这种格式:ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html 但是,当我尝试阅读时遇到了一个问题,请说如下一行.

I am currently trying to parse UnicodeData.txt with this format: ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html However, I am hitting a problem in that when I try to read, say a line like the following.

something;123D;;LINE TABULATION;

我尝试通过如下代码从字段中获取数据.问题是没有填写 fields[3],并且 scanf 返回 2.in 是当前行.

I try to get the data from the fields by code such as the following. The problem is that fields[3] is not getting filled in, and scanf is returning 2. in is the current line.

char fields[4][256];
sscanf(in, "%[^;];%[^;];%[^;];%[^;];%[^;];",
    fields[0], fields[1], fields[2], fields[3]);

我知道这是 scanf() 的正确实现,但是除了制作我自己的 scanf() 之外,有没有办法让它起作用?

I know this is the correct implementation of scanf(), but is there a way to get this to work, short of making my own scanf()?

推荐答案

scanf 不处理空"字段.所以你必须自己解析它.

scanf does not handle "empty" fields. So you will have to parse it on your own.

以下解决方案是:

  • 快,因为它使用 strchr 而不是很慢的 sscanf
  • 灵活,因为它可以检测任意数量的字段,最多可达给定的最大值.

函数 parse 从输入 str 中提取字段,用分号分隔.四个分号表示五个字段,其中部分或全部可以为空.没有规定转义分号.

The function parse extracts fields from the input str, separated by semi-colons. Four semi-colons give five fields, some or all of which can be blank. No provision is made for escaping the semi-colons.

#include <stdio.h>
#include <string.h>

static int parse(char *str, char *out[], int max_num) {
    int num = 0;
    out[num++] = str;
    while (num < max_num && str && (str = strchr(str, ';'))) {
        *str = 0;           // nul-terminate previous field
        out[num++] = ++str; // save start of next field
    }
    return num;
}

int main(void) {
    char test[] = "something;123D;;LINE TABULATION;";
    char *field[99];
    int num = parse(test, field, 99);
    int i;
    for (i = 0; i < num; i++)
        printf("[%s]", field[i]);
    printf("\n");
    return 0;
}

这个测试程序的输出是:

The output of this test program is:

[something][123D][][LINE TABULATION][]

更新:一个稍短的版本,不需要额外的数组来存储每个子字符串的开头,是:

Update: A slightly shorter version, which doesn't require an extra array to store the start of each substring, is:

#include <stdio.h>
#include <string.h>

static int replaceSemicolonsWithNuls(char *p) {
    int num = 0;
    while ((p = strchr(p, ';'))) {
        *p++ = 0;
        num++; 
    }
    return num;
}

int main(void) {
    char test[] = "something;123D;;LINE TABULATION;";
    int num = replaceSemicolonsWithNuls(test);
    int i;
    char *p = test;
    for (i = 0; i < num; i++, p += strlen(p) + 1)
        printf("[%s]", p);
    printf("\n");
    return 0;
}

这篇关于如何让 scanf 继续使用空扫描集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆