2

I'm trying to split a long string with white-spaces, using sscanf().

For example: I need to split this

We're a happy family

into

We're
a
happy
family

I tried the following approach

char X[10000];
fgets(X, sizeof(X) - 1, stdin); // Reads the long string
if(X[strlen(X) - 1] == '\n') X[strlen(X) - 1] = '\0'; // Remove trailing newline
char token[1000];
while(sscanf(X, "%s", token) != EOF) {
    printf("%s | %s\n", token, X);
}

The previous code goes into an infinite loop outputting We're | We're a happy family

I tried to replace sscanf() with C++ istringstream, it worked fine.

What makes X keep it's value? Shouldn't it be removed from buffer like normal stream?

Mahmoud Aladdin
  • 536
  • 1
  • 3
  • 13
  • try strtok instead. note, though, that it is not re-entrant. – thang Jan 18 '13 at 11:55
  • 1
    Why would you ask for sscanf and tag it with c++ only ? Trust me, there are c experts who have such snippets at the top of their head, and many c++ guys do not bother when `istringstream` works. – luk32 Jan 18 '13 at 11:57
  • See another option here [How do I tokenize a string in C++?](http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c) – Bo Persson Jan 18 '13 at 12:17

1 Answers1

2

sscanf() does store information about the buffer it previously read from and will always start from the address (buffer) passed to it. A possible solution would be to the use %n format specifier to record the position the last sscanf() stopped at and pass X + pos as the first argument to sscanf(). For example:

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

int main()
{
    const char* X = "hello again there";
    char token[1000];
    int current_pos = 0;
    int pos = 0;
    while (1 == sscanf(X + current_pos, "%999s%n", token, &pos))
    {
        current_pos += pos;
        printf("%s | %s\n", token, X + current_pos);
    }
    return 0;
}

See demo at http://ideone.com/XBDTWm .

Or just use istringstream and std::string:

std::istringstream in("hello there again");
std::string token;
while (in >> token) std::cout << token << '\n';
hmjd
  • 120,187
  • 20
  • 207
  • 252