简体   繁体   English

如何使用 scanf 从缓冲区中提取一些格式化的字符串?

[英]How to extract some formatted string from the buffer using scanf?

I need to extract both "rudolf" and "12" from that long string: "hello, i know that rudolph=12 but it so small..." using scanf , how can I do it?我需要从那个长字符串中提取“rudolf”“12”"hello, i know that rudolph=12 but it so small..."使用scanf ,我该怎么做?

This buffer can contains any formatted strings like ruby=45 or bomb=1 , and I dont know it in advance.这个缓冲区可以包含任何格式化的字符串,如ruby=45bomb=1 ,我事先不知道。

I am trying something like that, but it was unsuccessful我正在尝试类似的事情,但没有成功

#include <stdio.h>

int main()
{
    char sentence[] = "hello, i know that rudolph=12 but it so small...";
    char name[32];
    int value;

    sscanf(sentence, "%[a-z]=%d", name, &value);
    printf("%s -> %d\n", name, value);

    getchar();
    return 0;
}

Iterate through the sentence using a temporary pointer and %n to extract each sub-string.使用临时指针和%n遍历句子以提取每个子字符串。
%n will give the number of characters processed by the scan to that point. %n将给出扫描到该点处理的字符数。 Add that to the temporary pointer to advance through the sentence.将其添加到临时指针以推进句子。
Try to parse from each sub-string the name and value.尝试从每个子字符串解析名称和值。 The scanset %31[^=] will scan a maximum of 31 characters, leaving room in name for a terminating zero.扫描集%31[^=]将扫描最多 31 个字符,在name为终止零留出空间。 It will scan all characters that are not an = .它将扫描所有不是=字符。 Then the format string will scan the = and try to scan an integer.然后格式字符串将扫描=并尝试扫描一个整数。

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

int main (void) {
    char sentence[] = "hello, i know that rudolph=12 but it so small...";
    char string[sizeof sentence] = "";
    char name[32] = "";
    char *temp = sentence;
    int value = 0;
    int count = 0;
    int parsed = 0;

    while (1 == sscanf(temp, "%s%n", string, &count)) {
        temp += count;
        if (2 == sscanf(string, "%31[^=]=%d", name, &value)) {
            parsed = 1;
            break;
        }
    }
    if (parsed) {
        printf("%s %d\n", name, value);
    }

    return 0;
}

You can write your own string serach engine.您可以编写自己的字符串搜索引擎。 Which could be quite simple, let's for example:这可能很简单,例如:

  • advance until you find one of [az]前进,直到找到[az]
    • remember position记住位置
    • advance until the end of [az]前进到结束[az]
    • check if it's = now检查它是否是=现在
      • if it is, there was our variable name如果是,那就是我们的变量名
      • advance until end of value前进直到价值结束
      • return it把它返还
  • if there's no = , omit everything that is not a [az] ie.如果没有= ,则省略所有不是[az]即。 can't be variable name不能是变量名

A sample program:一个示例程序:

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

struct find_assignment_s {
    const char *line;
    const char *var;
    size_t varlen;
    const char *val;
    size_t vallen;
};

struct find_assignment_s find_assignment_init(const char *line) {
    return (struct find_assignment_s){.line = line};
}

int find_assignment(struct find_assignment_s *t) {
    while (*t->line) {
        const char *p = t->line;
        while (*p && isalpha((unsigned char)*p)) p++;
        // There is at least one alphabetic character and there is a space right after.
        if (t->line != p && *p == '=') {
            // Found a "variable="!
            t->var = t->line;
            t->varlen = p - t->line;
            // value is up until a space is found
            t->val = p + 1;
            while (*p && !isspace((unsigned char)*p)) p++;
            t->vallen = p - t->val;
            // Advance the pointer behind value.
            t->line = *p ? p + 1 : p;
            return 1;
        }
        // Ignore spaces
        while (*p && !isalpha((unsigned char)*p)) p++;
        // Advance over whole word.
        t->line = p;
    }
    return 0;
}

int main() {
    const char line[] =  "hello, i know that rudolph=12 but it so small... a=b c=d fdnajn=123";
    for (struct find_assignment_s fs = find_assignment_init(line);
            find_assignment(&fs) == 1; ) {
        printf("%.*s = %.*s\n", (int)fs.varlen, fs.var, (int)fs.vallen, fs.val);
    }
}

outputs:输出:

rudolph = 12
a = b
c = d
fdnajn = 123

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM