Jump to content
xisto Community
Sign in to follow this  
AeonLan

Top 10 Things To Avoid In C/c++ Found this so, I would like you to know it. Please read if you are con

Recommended Posts

:) WELCOME!

To avoid unimportant talks, i'll be straight to the point. I found this at a Website where I am currently registered too. This helps, really...

Things to Avoid in C/C++ -- gets() , Part 1

C/C++ programmers are allowed to do some things they shouldn't. We are given functions that are supposed to be useful but aren't because of hidden faults, or taught ways to do things that are bad, wrong, not necessary. These posts will discuss many of these as time goes on.
The code in this collection of electronic bits is specifically written in C. I'm using the free Borland 5.5 compiler for the code. For any code that is designed to show the errors, your results may be a little different. But rest assured, the problem exists in many if not all compilers. And if most compilers show these anomalies, wouldn't you rather not use the feature even if it works on your current compiler?

Most of these functions from C exist as methods in C++. Not being a guru in C++, if anyone would like to contact me with the C++ equivalent, I will add the information to these posts.

Enjoy, and clean up your code!

gets()
You should never use gets(). Never. Never. Never. I hope I am being clear. NEVER!!

gets() is a function that misbehaves badly. It has no internal checks which means it will read anything you give it. Define a 10 character buffer and gets() will happily accept the Declaration of Independance as its input.

Here's an example. Create and build this program:


#include <stdio.h>

int main()
{
char b1[] = "ABCD";
char b2[] = "LMNO";
char b3[] = "ZYXW";

puts(b1);
puts(b2);
puts(b3);
putchar('\n');

puts("Enter some characters:");
gets(b2);

putchar('\n');
puts(b1);
puts(b2);
puts(b3);

return(0);
}
You will notice there are 3 character arrays of 5 characters each (don't forget about the '\0' at the end of each).

Now run the program and enter "1234" when prompted. My output:


D:\C\GIDForum>gets
ABCDE
LMNOP
ZYXWV

Enter some characters:
1234

ABCDE
1234
ZYXWV

D:\C\GIDForum>
So far so good. Now run it again and enter all the numbers:


D:\wjp\C\GIDForum>gets
ABCDE
LMNOP
ZYXWV

Enter some characters:
1234567890

90
1234567890
ZYXWV

D:\wjp\C\GIDForum>
Whoa! What happened to b1?!? Well, gets() just happily accepted what you typed in and put it into memory starting at b2 and didn't give one hoot about anything but reading the characters. gets() overwrote memory it shouldn't have.

Keep in mind your results may be a little different, but the concept is the same. This function is dangerous!!!. Play around with this program. Some of you will find it crashes. Some will find it will accept a *lot* of characters. Who knows what it's doing with your memory, what it's writing over?

Avoid gets() like it's the bubonic plague with a rickets chaser.

fgets()
Instead, use fgets():


fgets(buffer, BufLength, stdin);
So in our program, use:


puts("Enter some characters:");
fgets(b2, 5, stdin); // 5 is the size of buffer b2
Not much harder, but much safer. fgets() will read up to BufLength-1 characters and stop. It will also stop if it reads a new-line '\n' which it unfortunately will place in the buffer. So there are 2 possible outcomes using fgets():


Outcome #1
You've entered exactly or more characters than the buffer holds.
your buffer contains BufLength-1 characters
the input stream still contains the rest and will be read on the next fgets().



The characters in the input stream will have to be dealt with. See the fflush() discussion.


Outcome #2
You've entered fewer characters than the buffer holds.
your buffer contains BufLength-1 characters, including the '\n' at the end.
the input stream is empty.



The input stream is clean so you have no I/O problems. But that '\n' may have to be dealt with. To remove it, include string.h in your file and add a line:


puts("Enter some characters:");
fgets(b2, 5, stdin); // 5 is the size of buffer b2
if (b2[strlen(b2)-1] == '\n') b2[strlen(b2)-1] = '\0';
This if statement will test the last character (b2[strlen(b2)-1]) for the new-line and change it to a null.

To deal with both options at once to either remove the trailing '\n' or clear the buffer, whichever situation exists, define a dummy buffer of say 50 characters (you choose the size) and use this code:


puts("Enter some characters:");
fgets(b2, 5, stdin); // 5 is the size of buffer b2
if (b2[strlen(b2)-1] == '\n')
{ // full input line read
b2[strlen(b2)-1] = '\0'; // remove the new-line
}
else
{ // parial input line read
b2[0] = 0; // empty the b2 buffer
do
{ // loop until the new-line is read
fgets(dummy, 50, stdin);
strcat(b2, dummy); // Save input but be sure
// sure to test your buffer size
} while (dummy[strlen(dummy)-1] != '\n');
}
OK, so it's not that easy. But it's better than having a program that will explode, isn't it? Anyway, just copy the code above and you'll be fine.



I've given part one, there are ten parts... Just go down the page to see other parts.

It is from: GIDNetwork

^_~ Happy Coding
Edited by AeonLan (see edit history)

Share this post


Link to post
Share on other sites
:) Lol. Sorry, I couldn't help myself reading this one.
Well I suppose that's what happens when you use a simple function for a complex task.
Isn't that the case with many other functions? Aren't they also useful?
#include <iostream>int main(){	char chard[] = "--Declaration of Independence--";	std::cout << chard;}
Oh no! We just wrote the declaration of independence on the screen!
Whatever shall we do? Lol. I know I made a strawman argument,
but suppose we were printing to the screen with a pointer to some
great text area in memory instead (if I was to say, write OS-development style)
and I cout'ed everything till I encountered a \n character.
(rather useful in some situations)
Next you're going to tell me don't use pointers because they override standard limits.
It's the same type of argument for using gotos.

It all depends on your needs and uses.
I wouldn't use gets() for a professional program,
but for my cracktroop write->compile->run programs I would.
And gotos are a useful implementation, it's just that you have
to handle unexpected combinations.

Those functions exist in C++ for a reason. I doubt ISO/IEC 14882:2003
allowed it to stay (after what, 30 years of usage?) if it was
never meant to be used. It goes back to the cliché: "never say never".

Share this post


Link to post
Share on other sites

IMHO, the tips are wrote mainly for new and moderate C/C++ programmers that get stuck on some bugs they don't know or encountered at some books or e-books.Professional or experienced programmers tend to make another way to make things work as they should be, as you've said. It is important for them to know the basics and modify/remove/add some ideas to it to have an efficient program.:)

Share this post


Link to post
Share on other sites

IMHO, the tips are wrote mainly for new and moderate C/C++ programmers that get stuck on some bugs they don't know or encountered at some books or e-books.

True, but the way we sometimes generalize things, you'd think that you should never use gets() or similar functions. Plus, sometimes the bets way of learning something is by trial-and-error. I encourage people to use gets() until it stops working and then learn why.

Professional or experienced programmers tend to make another way to make things work as they should be, as you've said. It is important for them to know the basics and modify/remove/add some ideas to it to have an efficient program.

Yep. I like your argument, but it's easier to become an experienced programmer when you've experienced all of the language. Including the bugs. :)

Share this post


Link to post
Share on other sites

Hm well this coud be come in handy think all bookmark it thanxs for posting it always love learning more stuff ^^

One is glad to be at service.... Just ask here if you have questions regarding the tips.

 

Yep. I like your argument, but it's easier to become an experienced programmer when you've experienced all of the language. Including the bugs. cool.gif

Then again it is not that easy to learn ALL programming languages and experience a lot of bugs if you're careful enough in coding and has a full-proof DESIGN & ANALYSIS of the problem that your solving.

 

:)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.