Everything2
Near Matches
Ignore Exact
Full Text
Everything2

Reading a string in C

created by CentrX

(idea) by Coffee (4 mon) (print)   ?   (I like it!) Sat Nov 25 2000 at 11:06:18

The most effective way that I've ever found:

char str[256]; /* Actually, this is sometimes too small. But caveat emptor. */

fgets(str, 256, f);

This NUL terminates the string as a free gift, and stops before the array ends, guaranteed, which makes it much harder to blow the buffer. It's especially handy for reading user input, and it makes it far more difficult for the user to overflow your buffer and cause a segfault (or local variant). It does store the newline as well, so you might want to do something like:

str[strlen(str)-1] = 0;

As long as you got the string from fgets(), and the file hasn't hit EOF (you do check that, right?), there's at least one character in the array, so this is safe. Note that fgets() promises to 0-terminate the string for you, come hell or high water, so the strlen() will be okay.

If the user pounded on the keys like a wild monkey before hitting enter, most of their input will not make it into the fgets(), and will be waiting around for the next time you try to read. But what you got will be safe, so the constant buffer is okay. (Well, as I said, it may be smaller than you want for your code, but you can always change the size if you recompile.)


As an aside to cbond's, er, Furious George's comment, recursion is quite expensive, especially if you're getting a truly monstrous stack as a free gift. If getline() isn't on your target system, or if your target has a pathetically small stack (which could then cause you to blow your stack) you might run into problems... But "to each their own," said the woman as she kissed the cow.

Update: To each their own. Since I've never been on a system with getline() and I have been on systems with tiny stacks, I suppose there is some paranoia going on here. Use my solution, use Furious George's solution, but please, use something besides gets().

Oh, and when I say tiny stacks, they were big enough for one buffer of 256 bytes - but not a series of stack frames and 16 byte buffers and so on. Yes, I do sometimes wake up twitching, why do you ask?


(idea) by Furious George (5.6 y) (print)   ?   (I like it!) Wed Jan 24 2001 at 23:36:28

The only problem when dealing with fgets() is that you have to use a buffer with a static length. Fuck me in the goat ass! This is extremely problematic when dealing with user input, and should be avoided.

More convenient is the non-standard getline() interface, which allows you to read strings of unlimited length and usually guarantees only one malloc() call. Apparently, it does this by allocating small chunks of stack each time getline() is called and using them to store pieces of the string, calling itself recursively if it needs more space. When the end of the line/file is reached, it allocates a buffer and unwinds. When each instance of getline() is returned to, it prepends its buffer to the malloc()'d space until it has fully unwound and you're left with your string. Clever, no?

Anyway, the moral of the story is to be clever about your fgets() use, or use getline().


Coffee: Your implementation uses the stack to store the string as well. It's silly to worry about the few bytes that the getline recursion would cost (for return address, etc.). That stack space is recovered as soon as the stack frame is dismantled and the string is put into malloced memory. Besides, I'd rather risk running out of stack space than arbitrarily truncating input with fgets.


printable version
chaos

Not reading a string in C C Programming Tips and Tricks How to convert binary to English in your head Caveat emptor
Crying when you go to the bathroom C string Fuck Me General Public Disclaimer getline
Why programmers don't comment their code Essential C Functions gets How interactive fiction works (part 5)
Harry Potter G-string Extra Terrestrial Goat Creatures from the Fuck Galaxy The word "Depressed" is overrated
free hacking zone Fuck me like you fucked that horse segfault buffer overflow attack
marijuana EOF strings finite state automaton
Y'know, if you log in, you can write something here, or contact authors directly on the site. Create a New User if you don't already have an account.
  Epicenter
Login
Password

password reminder
register

Everything2 Help

Cool Staff Picks
Look at this mess the Death Borg made!
Baking bread
Alfred Bester
Edith Piaf
Red Headed Stranger
Fake words and broken definitions in dictionaries
Waking Life
Five sonnets of vanity
Interstate Numbering System
Sensei
Generation X
I sincerely hope you have one of these somewhere in your life.
Golden ratio
Malhavoc
New Writeups
Cuckowski
Slavonic Princess(poetry)
Heitah
Posthumous Oscar(thing)
ignis_glaciesque
University of South Florida(place)
ignis_glaciesque
Flogstaskriket(idea)
liveforever
Caesar's last breath(idea)
dagnyswaggart
she wants to believe(personal)
antigravpussy
he doesn't know, but her eyes widen too far(thing)
dagnyswaggart
Wild tides guard her secrets(poetry)
Lord Brawl
Caesar's last breath(poetry)
locke baron
Forgotten things in space(fiction)
sitaraika
Colours(idea)
etouffee
Wild tides guard her secrets(poetry)
Lord Brawl
Dr. Horrible's Sing-Along Blog(review)
a8ksh4
regret(idea)
Heisenberg
Editor Log: July 2008(log)
Everything 2 is brought to you by the letter C and The Everything Development Company