Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Order of Variable Declartion

Reply
Thread Tools

Order of Variable Declartion

 
 
Interrupt
Guest
Posts: n/a
 
      01-14-2010
Hi folks, I'm trying to teach myself C, I’m finding it pretty hard
going!! Something’s don’t make sense- for example I’ve written a bit
of code if I declare variable int a; at the start of variable
declarations (in a watch window : the code doesn’t work because int a
=0 always; ) But if I declare it last the code works ie what ever the
user inputs???

************ Code *********************************************
#include <stdio.h>
#include <stdlib.h>
int manipulate(int a,int box,char c);
int main()
{
while(1)
{
// if I declare int a here code doesn’t work???????
char c;
int z;
int box;
int a; // when I declare it here it works ??????

puts("enter an integer b");
scanf("%d",&box);

puts( " the integer value a");
scanf("%d",&a);


puts("Enter the type of manipulation Required,/,*,+,-.");
scanf("%s",&c);

z = manipulate( a, box, c);

printf("the Answer is %d\n\n",z);
}
return 0;
}
************************ Code
************************************************** ********************
 
Reply With Quote
 
 
 
 
Nick
Guest
Posts: n/a
 
      01-14-2010
Interrupt <(E-Mail Removed)> writes:

> Hi folks, I'm trying to teach myself C, I’m finding it pretty hard
> going!! Something’s don’t make sense- for example I’ve written a bit
> of code if I declare variable int a; at the start of variable
> declarations (in a watch window : the code doesn’t work because int a
> =0 always; ) But if I declare it last the code works ie what ever the
> user inputs???


That is a sure sign that something has gone horribly wrong in your code,
and something is stamping on the space in memory that your variable is
held in.

> ************ Code *********************************************
> #include <stdio.h>
> #include <stdlib.h>
> int manipulate(int a,int box,char c);
> int main()
> {
> while(1)
> {
> // if I declare int a here code doesn’t work???????
> char c;
> int z;
> int box;
> int a; // when I declare it here it works ??????
>
> puts("enter an integer b");
> scanf("%d",&box);
>
> puts( " the integer value a");
> scanf("%d",&a);
>
>
> puts("Enter the type of manipulation Required,/,*,+,-.");
> scanf("%s",&c);


And here's where it happens. You read a string (%s) but c is char.

So even if the user only enters a single character, you will still read
that character and an "end of string" marker character ('\0'). Notice
that it's when you put 'a' next to 'c' in the declaration that it goes
wrong.

If your user enters "I'd like to multiply those two numbers together
please Bob", heaven knows what will happen.

You either need to scanf for a character, or create a suitable sized
string buffer for the result. I'm not a great user (or fan) of scanf,
so I'll leave detailed recommendations on that to others.

> z = manipulate( a, box, c);
>
> printf("the Answer is %d\n\n",z);
> }
> return 0;
> }
> ************************ Code
> ************************************************** ********************

--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
 
Reply With Quote
 
 
 
 
Andrew Poelstra
Guest
Posts: n/a
 
      01-14-2010
On 2010-01-14, Interrupt <(E-Mail Removed)> wrote:
> Hi folks, I'm trying to teach myself C, I?m finding it pretty hard
> going!! Something?s don?t make sense- for example I?ve written a bit
> of code if I declare variable int a; at the start of variable
> declarations (in a watch window : the code doesn?t work because int a
>=0 always; ) But if I declare it last the code works ie what ever the
> user inputs???
>
> ************ Code *********************************************
> #include <stdio.h>
> #include <stdlib.h>
> int manipulate(int a,int box,char c);
> int main()
> {
> while(1)
> {
> // if I declare int a here code doesn?t work???????
> char c;
> int z;
> int box;
> int a; // when I declare it here it works ??????
>
> puts("enter an integer b");
> scanf("%d",&box);
>
> puts( " the integer value a");
> scanf("%d",&a);
>
> puts("Enter the type of manipulation Required,/,*,+,-.");
> scanf("%s",&c);


Here is your problem. %s expects a pointer to an array of char of
indefinite length. Since such a thing does not exist, I'm not sure
why the specifier is allowed to be used this way. (If you were to
use, say, %20s, it would expect a pointer to an array of 20 char.)

BUT, you don't have, nor do you want, an array. You have a single
char, and for that you need to use the %c specifier.

%s can't tell if you've given it a proper array; it just assumes
that you have, even though you actually handed it an address of
a single char. So it happily writes '+' to c, '\n' to the byte
after c, and '\0' to the byte after that. But since you don't
own those bytes, anything could happen! In this case I think you
are overwriting the value of a, or something like that, which is
why your code appears not to work.

I hope this helps. I tried to be concise but I don't think I did.

>
> z = manipulate( a, box, c);
>
> printf("the Answer is %d\n\n",z);
> }
> return 0;
> }
> ************************ Code
> ************************************************** ********************

 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      01-14-2010
Interrupt <(E-Mail Removed)> wrote:
> Hi folks, I'm trying to teach myself C, I’m finding it pretty hard
> going!! Something’s don’t make sense- for example I’ve written a bit
> of code if I declare variable int a; at the start of variable
> declarations (in a watch window : the code doesn’t work because int a
> =0 always; ) But if I declare it last the code works ie what ever the
> user inputs???


The problem isn't related to the variable 'a' (that's only a
collateral damage) but to the fact that your variable 'c' is
defined as a single char but you try to read a string into it:

> ************ Code *********************************************
> #include <stdio.h>
> #include <stdlib.h>
> int manipulate(int a,int box,char c);
> int main()
> {
> while(1)
> {
> // if I declare int a here code doesn’t work???????
> char c;
> int z;
> int box;
> int a; // when I declare it here it works ??????


> puts("enter an integer b");
> scanf("%d",&box);


> puts( " the integer value a");
> scanf("%d",&a);



> puts("Enter the type of manipulation Required,/,*,+,-.");
> scanf("%s",&c);


Here you tell scanf() with "%s" that '&c' is a pointer to an array
of chars but 'c' is only a single char. And scanf() will try to
write the string the user enters into this location. Since there
isn't room enough it's going to overwrite some other unrelated data
(e.g. your variable 'a' if it's in the way). If you just need a
char use "%c" instead if "%s" - that tells scanf() that you only
expect a single char.

Obviously your compiler organizes the variables in an order
that, when you define 'a' before 'c', 'a' is located shortly
after 'c' in memory and thus writing past 'c' overwrites what
is stored in 'a'. But note that it could also the other way
round, the compiler is free to decide where to put the vari-
ables. And if you define 'a' after 'c' it may seem as if it
works, but that's pure bad luck, you're then just overwriting
some other (perhaps in this special case less essential) data.

Just a warning: using scanf() to read strings with a simple "%s"
is always dangerous since scanf() has no idea at all how much
space there is for the string, and if the users enters a string
that's longer than what would fit into the memory you set aside
for it it, will happily write past the end of the array, resul-
ting in a potentialy hard to find bug!

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-14-2010
Andrew Poelstra <(E-Mail Removed)> writes:

> On 2010-01-14, Interrupt <(E-Mail Removed)> wrote:
>> char c;

<snip>
>> puts("Enter the type of manipulation Required,/,*,+,-.");
>> scanf("%s",&c);

>
> Here is your problem. %s expects a pointer to an array of char of
> indefinite length. Since such a thing does not exist, I'm not sure
> why the specifier is allowed to be used this way. (If you were to
> use, say, %20s, it would expect a pointer to an array of 20 char.)
>
> BUT, you don't have, nor do you want, an array. You have a single
> char, and for that you need to use the %c specifier.


Beginners can get in a mess with %c because it does not skip white
space and there will (probably) be some there from the previous
numeric input.

To the OP: if you switch to %c put a space in front like this:

scanf(" %c", &c);

The space is another input directive and means "skip white space
characters".

> %s can't tell if you've given it a proper array; it just assumes
> that you have, even though you actually handed it an address of
> a single char. So it happily writes '+' to c, '\n' to the byte
> after c, and '\0' to the byte after that.


Nit: %s stops on white space so it will only write '+' followed by
'\0' when the '\n' is seen. The '\n' is left for the next input
operation to see.

Second to the OP: you really should be testing the return from scanf.
It is a great habit to get into, not because it is the right thing to
do (though it is) but because it gets you thinking about how the
program should be shaped to cope with thing going wrong. Coping with
things going wrong is one of the most important things to pick up, and
you can't start too early.

<snip>
--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-14-2010
Richard Heathfield <(E-Mail Removed)> writes:

> Interrupt wrote:

<snip>
>> scanf("%s",&c);

>
> Here's your problem. The easiest fix is to change %s to %c.


" %c" will be less confusing to a beginner.

> I suggest taking a good long look at the fgets() function. Not the
> broken, deprecated gets() function, but the good, solid, easy-to-use
> fgets() function, which reads a string from a file (you can use stdin,
> of course) into an array of char. Grab all your data that way, and
> convert it into numbers (where necessary) once you've got it safely
> out of the input stream. And leave scanf until you've got a lot more
> experience under your belt.


Hmm... I'm not sure about this often quoted advice. scanf is fiddly,
but so is line-based input and subsequent conversion. I agree that it
is often better in the long-run, so it is worth getting to know that
method, but I am not convinced that it is easier to /start/ doing
input that way.

--
Ben.
 
Reply With Quote
 
Andrew Poelstra
Guest
Posts: n/a
 
      01-14-2010
On 2010-01-14, Ben Bacarisse <(E-Mail Removed)> wrote:
>
> ...
>
> Nit: %s stops on white space so it will only write '+' followed by
> '\0' when the '\n' is seen. The '\n' is left for the next input
> operation to see.
>


That's more than a nit - I didn't know that and it probably would
have nailed me! (If I were ever to use scanf() on stdin.)

> Second to the OP: you really should be testing the return from scanf.
> It is a great habit to get into, not because it is the right thing to
> do (though it is) but because it gets you thinking about how the
> program should be shaped to cope with thing going wrong. Coping with
> things going wrong is one of the most important things to pick up, and
> you can't start too early.
>


That one I knew, but forgot to mention.

 
Reply With Quote
 
Interrupt
Guest
Posts: n/a
 
      01-16-2010

> > Second to the OP: you really should be testing the return from scanf.
> > It is a great habit to get into, not because it is the right thing to
> > do (though it is) but because it gets you thinking about how the
> > program should be shaped to cope with thing going wrong. *Coping with
> > things going wrong is one of the most important things to pick up, and
> > you can't start too early.


Hi folks thanks to the many replies very helpful !! As you’ll have
noticed I’m only starting so excuse my ignorance, how do you test the
return from scanf??

 
Reply With Quote
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      01-16-2010
Interrupt <(E-Mail Removed)> wrote:

> > > Second to the OP: you really should be testing the return from scanf.
> > > It is a great habit to get into, not because it is the right thing to
> > > do (though it is) but because it gets you thinking about how the
> > > program should be shaped to cope with thing going wrong. Â*Coping with
> > > things going wrong is one of the most important things to pick up, and
> > > you can't start too early.


> Hi folks thanks to the many replies very helpful !! As you’ll have
> noticed I’m only starting so excuse my ignorance, how do you test the
> return from scanf??


The return value tells you how many items scanf() found in the
input. Normally you want as many as you asked for, e.g. if you
have

scanf( "%d %d %d", &x, &y, &z );

then you should check if scanf() returned 3, i.e.

if ( scanf( "%d %d %d", &x, &y, &z ) != 3 ) {
fprintf( stderr, "Expected 3 int's but didn't find as many\n" );
exit( EXIT_FAILURE );
}

Or, if the return value is 2, then you know that 'z' hasn't been
set by the call of scanf() and thus it's not be safe to use its
value (unless it had been set to a sane default value before).

In your case, where you expect a single char, scanf() returns 1
on success - but if it returns 0 then the user didn't enter a
character (perhaps just hit the return key) and thus you should
e.g. ask again.
Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-16-2010
(E-Mail Removed) (Jens Thoms Toerring) writes:
<snip>
> In your case, where you expect a single char, scanf() returns 1
> on success - but if it returns 0 then the user didn't enter a
> character (perhaps just hit the return key) and thus you should
> e.g. ask again.


It is not obvious how scanf("%c", &c) could return 0 in any normal
use. If there is no more input or an input error occurs, scanf
returns EOF. Otherwise a character (any character) is read and
assigned. Obviously, if the behaviour is undefined because, for
example, c is a float not a char then anything could happen (including
a zero return).

In particular, if the next character is a new line it will be read and
scanf will return 1.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"Variable variable name" or "variable lvalue" mfglinux Python 11 09-12-2007 03:08 AM
If you get an order # does it mean the order is accepted? =?Utf-8?B?U3RldmUxMDc3?= Windows 64bit 3 05-12-2005 11:46 PM
How do I scope a variable if the variable name contains a variable? David Filmer Perl Misc 19 05-21-2004 03:55 PM
Traversion order cf. output order in XSL Soren Kuula XML 2 02-01-2004 09:10 AM
How to Display DropDownList with preserved order (custom order) cspoh ASP .Net Web Controls 0 07-31-2003 09:19 AM



Advertisments