-3

I'm helping a friend with her programming class, and we've come across something funny. We have the code:

void ingresardatos(struct alumno *lista){
int i=0;
char continuar='s';
while(continuar=='s' && i<20){
    printf("Valor de i al iniciar: %d  \n", i);
    printf("Introduzca el nombre del alumno:\n");
    scanf("%s",&(lista[i].nombre));
    printf("Introduzca la matricula:\n");
    scanf("%s",&lista[i].matricula);
    printf("Introduzca la primera calificacion:\n");
    scanf("%f",&lista[i].calf1);
    printf("Introduzca la segunda calificacion:\n");
    scanf("%f",&lista[i].calf2);
    printf("Introduzca la tercera caificacion:\n");
    scanf("%f",&lista[i].calf3);

    lista[i].prom=(lista[i].calf1+lista[i].calf2+lista[i].calf3)/3;

    if(lista[i].prom<=5.9){
       strcpy(lista[i].nota,"NA");
    }
    else if(lista[i].prom>=6 && lista[i].prom<=7.3){
       strcpy(lista[i].nota,"S");
    }
    else if(lista[i].prom>=7.4 && lista[i].prom<=8.6){
      strcpy(lista[i].nota,"B");
    }
    else if(lista[i].prom>=8.7 && lista[i].prom<=10){
       strcpy(lista[i].nota,"MB");
    }
    printf("Valor de i antes: %d \n", i);
    i++;
    printf("Valor de i después: %d \n", i);
    printf("¿Desea continuar? (S/N)");
    scanf("%s",&continuar);
}
}

It's supposed to be a grade list for a class of 20; you introduce the student's data until you press "n", and it saves them on a list. Now, I figured out the pointer part (I just really know Java, so it's kinda weird working on C), but what I can't figure out is how to make the i++ part work. If you run it like it is, it'll start with i=0 on the first pass, then go through all the code, and finally do i++ before asking if you want to continue (it prints it on the screen). But then, when you press "s" to indicate you want to continue, it'll start with i=0 again, and for the life of me I can't figure out why. I tried i++, ++i, i=i+1, and so on, but nothing seems to work. I even tried making i a pointer, but Windows didn't like it and crashed my program every time I ran it.

If someone could explain just why it isn't working, I'd be eternally grateful.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Omar Vega
  • 1
  • 2
  • 3
    `scanf("%s",&continuar);` - `continuar` is a single `char` type. It will break the system since the string input will be at least 2 characters at that address. – Weather Vane Jun 07 '16 at 18:48
  • It's not really valid to explain what happened after *undefined behaviour* but suppositions can be satisfying. It *might be* that because `i` is just above `continuar` on the stack, when you enter data for a **string** the `'s'` goes to `char continuar` and the string terminator `'\0'` goes to the least significant byte of the [little-endian](https://en.wikipedia.org/wiki/Endianness) variable `i`. Since you incremented `i` *before* taking the input, that *might have* overwritten the least sig byte of `i` with `0`, clamping its value to `0` and causing the behaviour you saw. ***IF***. – Weather Vane Jun 07 '16 at 19:13

1 Answers1

1
scanf("%s",&continuar);

This should be:

scanf("%c",&continuar);

As you read into a single character and not a string of character.

With scanf("%s", it will not only write into continuar but the memory around it (how much depends on the number of characters read) and so your i variable must be next to it and is overwritten back to 0.

Edit:

As per @WeatherVane's comment, the solution should actually be:

scanf(" %c",&continuar);

Since you last read a floating point number, the newline (from you pressing enter) is still not read and would be put into the character.

Community
  • 1
  • 1
coyotte508
  • 9,175
  • 6
  • 44
  • 63
  • No, it should be `scanf(" %c",&continuar);` with the space. Otherwise it will read the `newline` left in the input buffer after `scanf("%f",&lista[i].calf3);` – Weather Vane Jun 07 '16 at 18:51