Jump to page: 1 2
Thread overview
Scanf function changes value of in-loop variable
Apr 16, 2014
Capture_A_Lag
Apr 16, 2014
bearophile
Apr 16, 2014
FreeSlave
Apr 16, 2014
Justin Whear
Apr 16, 2014
Ali Çehreli
Apr 16, 2014
Dicebot
Apr 16, 2014
Capture_A_Lag
Apr 16, 2014
Justin Whear
Apr 16, 2014
FreeSlave
Apr 16, 2014
Ali Çehreli
Apr 16, 2014
FreeSlave
Apr 16, 2014
FreeSlave
Apr 16, 2014
Capture_A_Lag
April 16, 2014
Hi all!
I have this code:

------------------------------------------------------------------------------
ubyte N, M, K;
ubyte[][max][max] Matrix;

scanf("%d %d %d", &N, &M, &K);

ubyte tmp;

for(ubyte n = 1; n <= N; n++)
	for(ubyte m = 1; m <= M; m++)
	{
		scanf("%d", &tmp);
                // After this scanf n becomes 0 for no reason
		
                if(tmp) Matrix[m][tmp] ~= n;
        }

------------------------------------------------------------------------------

After scanf in loop variable n becomes 0. Is this a bug? Please help me!
April 16, 2014
Capture_A_Lag:

> After scanf in loop variable n becomes 0. Is this a bug? Please help me!

Have you tried to use a tmp of type int to avoid stomping?

Bye,
bearophile
April 16, 2014
On Wednesday, 16 April 2014 at 17:47:05 UTC, Capture_A_Lag wrote:
> Hi all!
> I have this code:
>
> ------------------------------------------------------------------------------
> ubyte N, M, K;
> ubyte[][max][max] Matrix;
>
> scanf("%d %d %d", &N, &M, &K);
>
> ubyte tmp;
>
> for(ubyte n = 1; n <= N; n++)
> 	for(ubyte m = 1; m <= M; m++)
> 	{
> 		scanf("%d", &tmp);
>                 // After this scanf n becomes 0 for no reason
> 		
>                 if(tmp) Matrix[m][tmp] ~= n;
>         }
>
> ------------------------------------------------------------------------------
>
> After scanf in loop variable n becomes 0. Is this a bug? Please help me!

I suppose it's because scanf wait for int variable (which 4 bytes), but you pass pointer to ubyte, and when you input data it overwrites neighbor bytes.
April 16, 2014
On Wed, 16 Apr 2014 17:47:03 +0000, Capture_A_Lag wrote:

> Hi all!
> I have this code:
> 
> 
------------------------------------------------------------------------------
> ubyte N, M, K;
> ubyte[][max][max] Matrix;
> 
> scanf("%d %d %d", &N, &M, &K);
> 
> ubyte tmp;
> 
> for(ubyte n = 1; n <= N; n++)
> 	for(ubyte m = 1; m <= M; m++)
> 	{
> 		scanf("%d", &tmp);
>                  // After this scanf n becomes 0 for no reason
> 
>                  if(tmp) Matrix[m][tmp] ~= n;
>          }
> 
> 
------------------------------------------------------------------------------
> 
> After scanf in loop variable n becomes 0. Is this a bug? Please help me!

You are using the wrong format spec for an unsigned ubyte; switch out all instances of "%d" with "%hhu" and it should work.  Short version: the "% d" instructs the C scanf function to overwrite 32bits of the stack starting at tmp which is only 8 bits long.

Even better than using the proper format spec, you could swap out the non- typesafe C functions and use the D equivalents readf and formattedRead (see std.stdio and std.format).

Justin
April 16, 2014
On 04/16/2014 10:47 AM, Capture_A_Lag wrote:

> ubyte tmp;

>          scanf("%d", &tmp);
>                  // After this scanf n becomes 0 for no reason

%d is for int.

Ali

P.S. A friendly request: It makes it much easier for the rest of the group if posts contained compilable, minimal but complete code. Thanks.

April 16, 2014
On Wednesday, 16 April 2014 at 17:47:05 UTC, Capture_A_Lag wrote:
> Hi all!
> I have this code:
>
> ------------------------------------------------------------------------------
> ubyte N, M, K;
> ubyte[][max][max] Matrix;
>
> scanf("%d %d %d", &N, &M, &K);
>
> ubyte tmp;
>
> for(ubyte n = 1; n <= N; n++)
> 	for(ubyte m = 1; m <= M; m++)
> 	{
> 		scanf("%d", &tmp);
>                 // After this scanf n becomes 0 for no reason
> 		
>                 if(tmp) Matrix[m][tmp] ~= n;
>         }
>
> ------------------------------------------------------------------------------
>
> After scanf in loop variable n becomes 0. Is this a bug? Please help me!

scanf is inherently unsafe routine and does not protect you from type mismatch. In your snipper "%d" implies that argument is address of integer variable, however you supply it address of ubyte one. As loop variable happens to be on stack right next to `tmp` variable, it gets stomped when sizeof(int) bytes get written to &tmp
April 16, 2014
Thank you everybody!!!
I thought %d is ok for all integral types.
April 16, 2014
On Wed, 16 Apr 2014 18:17:37 +0000, Capture_A_Lag wrote:

> Thank you everybody!!!
> I thought %d is ok for all integral types.

This is true when using the D format functions (e.g. readf) which are able to inspect the types of the variables being assigned, but scanf is a C function and not typesafe.

Justin
April 16, 2014
Note that readf is not equivalent to scanf since readf does not skip spaces and newline character. Input must completely match format.
April 16, 2014
On 04/16/2014 11:36 AM, FreeSlave wrote:
> Note that readf is not equivalent to scanf since readf does not skip
> spaces and newline character. Input must completely match format.

Just like in scanf, a single space character is sufficient to consume zero or more whitespace characters.

Ali

« First   ‹ Prev
1 2