Steven Lu
Steven Lu

Reputation: 43427

equivalent of fgets on a buffer?

I was originally parsing a file line by line using fgets().

Now I changed things so that I already have my entire file in a buffer. I still like to read that buffer line by line for parsing purposes. Is there something designed for this, or do I need to make a loop that inspects for 0x0A chars at this point?

Upvotes: 6

Views: 4713

Answers (5)

John Lindgren
John Lindgren

Reputation: 867

For C, this should work, I think:

// str (in/out): the unconsumed portion of the input string
static char *sgets(char *buf, int n, const char **str)
{
    const char *s = *str;
    const char *lf = strchr(s, '\n');
    int len = (lf == NULL) ? strlen(s) : (lf - s) + 1;

    if (len == 0)
        return NULL;
    if (len > n - 1)
        len = n - 1;

    memcpy(buf, s, len);
    buf[len] = 0;
    *str += len;
    return buf;
}

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215193

memchr (with a little bit of your own wrapper code, ending with memcpy) is the exact equivalent - like fgets it takes a maximum length it will process (should be the min of the remaining input buffer size and the size of your output buffer) and scans until it hits the desired character (which will be '\n') or runs out of input/output space.

Note that for data already in a buffer in memory, though, you might want to skip the step of copying to a separate output buffer, unless you need to null-terminate the output without modifying the input. Many beginner C programmers often make the mistake of thinking they need null termination, when it would really suffice to just improve some of your interfaces to take a (pointer, length) pair, allowing you to pass/process substrings without copying them. For instance you can pass them to printf using: printf("%.*s", (int)length, start);

Upvotes: 7

user149341
user149341

Reputation:

If you're looking for C functions, strtok() and strsep() will both split a string on a specified character.

Upvotes: 0

Mat
Mat

Reputation: 206659

You could use the sscanf function for this. If you actually need a whole line, something like this should do the trick:

sscanf(your_buffer, "%50[^\n]", line);

(This will read lines at most 50 chars long. As always, careful with the length and 0 terminators. And check the return value of sscanf in case something went wrong.)

You can use pointer arithmetics to move your buffer along (just add "returned" line length + 1).

Upvotes: 2

Joshua
Joshua

Reputation: 43188

There is sscanf which may or may not work for you.

Upvotes: 0

Related Questions