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
char
s at this point?
If a newline is encountered and fgets returns, you can run it again as many times as necessary to read as many lines as you want. A loop is useful for this. If EOF is encountered, you have reached the end of the file(/stream) and there is no point in running it again, because there is nothing left to read.
man fgets: fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a new‐line is read, it is stored into the buffer.
The fgets() and gets_s() functions can still result in buffer overflows if the specified number of characters to input exceeds the length of the destination buffer.
fgets is likely going to be the better choice. You can then use sscanf() to evaluate it. For numeric types, scanf() does not need to do bounds checking. For string types, you can tell scanf() to do boundary checking.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With