vaib said:
When I run the following code on gcc it gives me "Segmentation fault".
Can anyone throw some light on what's happening ? It compiles fine. I
used RHEL 5.
That something compiles without any hickups only shows that
the syntax is right, it unfortunately doesn't ensures that
the logic of your program is correct.
I hope you don't mind that I don't just point out the
direct caus of your problem but also point out a few
other things that could be problems beside...
#include<stdio.h>
#include<stdlib.h>
int main()
Since your main() function doesn't take arguments it's
clearer if you write
int main( void );
While there's nothing wrong about declaring functions
in a functions it's rarely done n most programs I have
seen. But that's your decision.
Here you ask for a pointer to char. That pointer now points
to a random position in memory.
printf("\nEnter number as string:");
There's nothing else than a string the user could enter;-)
A problem here is that the output isn't guaranteed to
appear immediately, so the user may see nothing of it.
To make sure that outout of printf() appears on the
users screen the string either has to end in '\n' or
you have to enforce it by calling
fflush( stdout );
Here things go badly wrong. 's' is just a pointer, pointing
to some unknown place. You can be lucky in that it points
to a position in memory you don't have permission to write
to because in that case you may get a segementation fault,
telling you that something is badly wrong immediately. But
you also could be less lucky and 's' points to memory that
you can write to but are not allowed to, and in that case
it might look as if everything is fine while in reality you
just overwrote some data important for your program, but
that only get used at some later time. That could result
in the program crashing later or in computing some results
that are wrong.
So, having just a pointer doesn't mean that you also
have memory it is pointing to it. The pointer must be
initialized to point to memory that's yours. One way
to make sure that's the case is to define an array of
chars and pass that to scanf() like
char s[ 100 ];
or to allocate memory and make 's' point to that, like
in
s = malloc( 100 * sizeof *c )
if ( s == NULL ) {
fprintf( stderr, "Sorry, not enough memory\n" );
exit( EXIT_FAiLURE );
}
Note that you always should check if malloc() did give
you the memory you asked for and react accordingly!
(The 'sizeof *s' is a bit redundant since. as long as
's' is a pointer to char, it's 1 by definition, putting
it in or not in this case is a question of taste.)
But when you do that then there's another problem due
to the use of scanf(). Let's assume that you have memory
that can hold 100 chars. That looks like long enough
for an integer in string form. But the user who enters
the number can do stupid things, he could enter a lot
more characters, and then you still would write over
memory that's not your's, again with possibly catas-
trophic consequences. So, using scanf() to try to
get input from the user is inherently unsafe in thed
form you have used it. You can get around that by
specifying the maximum number of characters you're
prepared to read, e.g.
char s[ 100 ];
scanf( "%99s", s );
or also
scanf( "%99[0-9]", s );
if you want to make sure that reading stops when a non-
digit character gets found in the input. Note the '99'
instead of 100 - that's necessary since scanf() still
needs to but a '\0' character at the end of the string.
If you use scanf() it's also prudent to check its return
value which allows you to check how many items it got.
If the user e.g. hits Ctrl-D (or Ctrl-Z if he's using
Windows) instead of entering a stitrng, then scanf()
wouldn't be able to read anything and 's' would remain
unchanged (and since the 's' array isn't initialized
you would go on converting random chars from it).
An alternative to scanf() is fgets(). You have to tell
fgets() how many chars it's supposed to read at maximum
and you then can take the returned string apart in your
program.
x = fun(s);
printf("\nThe entered number was %d",x);
Again, keep in mind that strings not ending in '\n' may
get stuck in the internal buffers of printf() until some
later time (or until you call fflush()). Here it's not a
real problem since ending the program will flush these
buffers, but in a real program that might be different.
While calling exit() does the job of ending the program
why not simply return?
int fun(char *s)
{
int i;
i=0;
That can be done in a single line
int i = 0;
You don't need paranthesis around '*s', the '*' operator
"binds" rather strongly.
{
i=i*10;
i=i + (*s - '0');
s++;
}
return i;
}
I hope you realize that, if the user entered anything else
than digits, this function will give you strange results.
In a real program you also would probably use e.g. strtol()
instead of writing your own version...
Regards, Jens