1

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?

This buffer can contains any formatted strings like ruby=45 or bomb=1, and I dont know it in advance.

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;
}
5
  • IMO your best bet will be to call char *rudi = strstr(sentence, "rudolph=") and take it from there. But you say you want to extract "rudolf" too, so it is unclear whether the sentence is known to contain that keyword, or perhaps some other, such as "reindeer=42", Commented Jul 17, 2021 at 18:30
  • Since you already know it is "rudolf" and "12", you can just do strcpy(name, "rudolf"); value=12; and ignore the long string and scanf altogether. If you don't know that the input string contains "rudolf" and "12", please explain what you do know, and what you need to extract in terms of what you know. Commented Jul 17, 2021 at 18:39
  • @WeatherVane, yes, that buffer can contain any strings like "name=value" Commented Jul 17, 2021 at 18:46
  • @n.1.8e9-where's-my-sharem., that buffer can contain any string, including (for e.g. "abc=14" or "mike=34" Commented Jul 17, 2021 at 18:47
  • Look for the '=' character with char *eptr = strchr(sentence, '='); then work left to find the keyword and right for its value. If the sentence may contain more than one such, continue the search from there. Commented Jul 17, 2021 at 18:47

2 Answers 2

5

Iterate through the sentence using a temporary pointer and %n to extract each sub-string.
%n will give the number of characters processed by the scan to that point. 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. 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;
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can write your own string serach engine. Which could be quite simple, let's for example:

  • advance until you find one of [a-z]
    • remember position
    • advance until the end of [a-z]
    • 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 [a-z] ie. 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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.