0

I'm trying to scan user input in a for loop except for the first iteration of the loop 2 pieces of data are required for it to continue to the next step and I don't understand why. I'll show my code below but as a heads up I'm really new to this and not very good, I'm not even sure if the method i'm using is the most efficient.

#include    <stdlib.h>
#include    <stdio.h>
#include    <math.h>

#define     w   1.0
#define     R   1.0

int main(int argc, char *argv[])
{
int     tmp;
double  *x, *v, *m, *k;

x = malloc((argc-1)*sizeof(double));
v = malloc((argc-1)*sizeof(double));
m = malloc((argc-1)*sizeof(double));
k = malloc((argc-1)*sizeof(double));

if(x != NULL)
{
    for(tmp=0; tmp<argc-1; tmp++)
    {
        sscanf(argv[tmp+1], "%lf", &x[tmp]);
    }
}
else
{
    printf("**************************\n");
    printf("**Error allocating array**\n");
    printf("**************************\n");
}

if(argc <= 2)
{
    printf("************************************\n");
    printf("**There must be at least 2 masses!**\n");
    printf("************************************\n");
}
else if(argc == 3)
{
    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the velocity of Block %d\n", tmp+1);
        scanf("%lf\n", &v[tmp]);
    }

    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the mass of Block %d\n", tmp+1);
        scanf("%lf\n", &m[tmp]);
    }

    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the spring constant of Spring %d\n", tmp+1);
        scanf("%lf\n", &k[tmp]);
    }
}
else
{
    for(tmp=0; tmp<argc-1; tmp++)
    {
        printf("Input a value for the velocity of Mass %d\n", tmp+1);
        scanf("%lf\n", &v[tmp]);
    }

    printf("Input a value for the mass of each Block\n");
    for(tmp=0; tmp<argc-1; tmp++)
    {   
        scanf("%lf\n", &m[tmp]);
    }

    printf("Input a value for the spring constant of each Spring\n");
    for(tmp=0; tmp<argc-1; tmp++)
    {
        scanf("%lf\n", &k[tmp]);
        printf("%lf\n", &k[tmp]);
    }
}   
}

So yes the main problem is when taking a value for the velocity of block 1 it requires two values

Carterini
  • 165
  • 7

1 Answers1

0

Remove the white-space "\n" after each format.

// scanf("%lf\n", &v[tmp]);
scanf("%lf", &v[tmp]);

The white-space "\n" after "%lf" directs scanf() to continue scanning and consuming white-space (e.g. ' ', '\n', '\t', '\r' and typically 4 others) until a non-white-space char is found. This will consume the Enter or '\n' and look for more white-space.

Since stdin is typically buffered, the entire next line needs to be entered, before the scanf("\n") sees any of it.

Once scanf("\n") encounters a non-white-space, it puts it back in to stdin for the next I/O operation.


scanf(), in general, presents challenges when errant input is entered. For robust handling of evil user input, consider an fgets()/sscanf() combo. (or fgets()/strtod())

char buf[50];
double d;
if (fgets(buf, sizeof buf, stdin) == NULL) Handle_EOForIOError();
if (sscanf(buf, "%d", &d) != 1) Handle_ParseError();
// good to go

The following does consume the character after the double, which is typically the Enter, but creates error handle challenges should input like "1.23.45" occurs.

// scanf("%lf\n", &m[tmp]);
scanf("%lf%*c", &m[tmp]);  // Not recommended.

Whatever code path taken, always a good idea to check the result of scanf()/sscanf()/fcanf(), especially when reading double.


The white-space directives " ", "\n", "\t", etc. all behave the same. Any white-space directive in the format string consumes any white-space.

// All work the same.    
scanf("%lf\n", &v[tmp]);
scanf("%lf\t", &v[tmp]);
scanf("%lf ", &v[tmp]);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256