Android learner
Android learner

Reputation: 1871

Reading a string with spaces and special character with sscanf

For a project I'm trying to read an int and a string from a string. Here the only problem is sscanf appears to break reading an %s when it sees a space and some special character. I want to print only String which is present inside special character. Is there anyway to get around this limitation? Here is an example of what I'm trying to do:

Similar to this link with little change

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

int main(int argc, char** argv) {
    int age;
    char* buffer;
    buffer = malloc(200 * sizeof(char));
    sscanf("19 cool kid >>> ram <<<", "%d %[^\t\n] >>> %*s <<<", &age, buffer);

    printf("%s is %d years old\n", buffer, age);
    return 0;
}

What it prints is: "cool kid >>> ram <<< is 19 years old" where I need "ram is 19 years old". Is there any work around?

Note: some time "cool kid" string come "coolkid" like this also.

Upvotes: 0

Views: 2608

Answers (3)

chux
chux

Reputation: 154255

Could use sscanf(input, "%d%*[^>]>>>%199s", &age, buffer);. Anything after the %s is irrelevant in scanning for age and buffer. Not checking if all scanned can lead to trouble.

Suggest checking that the entire line parsed as expected. The simple solution is to use " %n" at the end. This saves the count of char scanned if scanning gets that far.

const char *input =  "19 cool kid >>> ram <<<";
int n = 0;
sscanf(input, "%d%[^>]>>>%*199s <<< %n", &age, buffer, &n);
if (n == 0 || input[n]) {
  puts("Bad Input");
}

Upvotes: 2

David C. Rankin
David C. Rankin

Reputation: 84579

You had it, you just had your discard in the wrong place (along with a slight capitalization issue):

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

int main (void) {

    int age;
    char* buffer;
    if (!(buffer = malloc(200 * sizeof *buffer))) {
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }
    sscanf("19 cool kid >>> ram <<<", "%d %*[^>] >>> %s <<<", &age, buffer);

    printf("%s is %d years old\n", buffer, age);

    free (buffer);

    return 0;
}

Output

$ ./bin/sscanf_strange
ram is 19 years old

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 754550

You need to look for things that aren't a >, and you need to suppress assignment on the correct bits:

sscanf("19 cool kid >>> ram <<<", "%d %*[^>] >>> %199s <<<", &age, buffer);

The length quoted in the format is one less than the number of characters available; it doesn't count the terminal null byte, in other words.

Upvotes: 1

Related Questions