it shows output more than 4 times - c

I was trying to make a program in C that basically asks the user some information about the people they live with. The code is in Spanish, but I will show you the problem.
/*Miembros de la familia*/
#include<stdio.h>
#include<stdbool.h>
#define TRUE 1
#define FALSE 0
int main(){
int personas,i,varones=0,hembras=0,opcion;
bool mayoredad=false;
printf("Indique cuantas personas viven en su casa:\n");
scanf("%i", &personas);
struct nombre{
char primer[30];
char segundo[30];
char apellido[30];
}minombre;
struct fecha{
int dia;
int mes;
int anio;
}nacimiento, actual;
printf("\nIngrese la fecha actual:\n");
scanf("%i %i %i", &actual.dia, &actual.mes, &actual.anio);
struct familia{
struct nombre minombre;
char cedula[10];
struct fecha nacimiento;
char genero;
int edad;
}familia[personas];
for(i=0;i<personas;i++){
printf("\nIndique su primer nombre, segundo nombre y apellido:\n");
scanf("%s %s %s", &familia[i].minombre.primer, &familia[i].minombre.segundo, &familia[i].minombre.apellido);
printf("\nPor favor escriba su numero de cedula:\n");
scanf("%s", &familia[i].cedula);
do{
printf("\nIngrese la fecha de su nacimiento: (DD)(MM)(AAAA):\n");
scanf("%i %i %i", &familia[i].nacimiento.dia, &familia[i].nacimiento.mes, &familia[i].nacimiento.anio);
if(familia[i].nacimiento.anio>actual.anio){
printf("Dato invalido, por favor intente nuevamente.");
}
}while(nacimiento.anio>actual.anio);
familia[i].edad=actual.anio-familia[i].nacimiento.anio;
if(familia[i].nacimiento.mes>=actual.mes && familia[i].nacimiento.dia>actual.dia){
familia[i].edad--;
}
if(familia[i].edad>=18){
mayoredad=true;
}
do{
printf("Indique su genero: (f) o (m):");
scanf(" %c", &familia[i].genero);
if(familia[i].genero=='f'){
hembras++;
}else if(familia[i].genero=='m'){
varones++;
}
}while(familia[i].genero!='f' && familia[i].genero!='m');
}
do{
printf("Registro concluido. Desea ver las estadisticas? 1(si) 2(no)");
scanf("%i", &opcion);
if(opcion!=1 && opcion!=2){
printf("DATO INVALIDO, INTENTE NUEVAMENTE");
}else if(opcion==1){
for(i=0;i<personas;i++){
printf("Nombre: %s %s %s\n", familia[i].minombre.primer, familia[i].minombre.segundo, familia[i].minombre.apellido);
printf("Cedula:%s\n", familia[i].cedula);
printf("Edad:%i\n", familia[i].edad);
printf("Mayor de edad:\n");
switch(mayoredad){
case true:printf("Si");break;
case false:printf("No");
}
}
printf("Cantidad de personas en el hogar: %i\n", personas);
printf("Varones: %i Hembras: %i\n", varones, hembras);
}
}while(opcion>=2 && opcion<0);
printf("Presione una tecla para salir.");
getchar();
return 0;
}
In the last do-while loop that requests the person's gender (familia[i].genero)
It is supposed to ask just once, but in the last iteration of the for loop, it displays the same question four times:enter image description here
How can I fix this?

The format specifier %i will treat input whose suffix is 0 (and not 0x nor 0X) as octal number.
Therefore, 09 in your input is invalid as octal number and it will leave 9 in the stream.
This 9 is read to familia[i].nacimiento.anio by the next specifier.
Then, following scanf(" %c", &familia[i].genero); will read 2003 from the input and this will lead to the 4 extra asking.
To fix this, use %d specifier to read integers. %d spcifier will treat input as decimal number regardless of the suffix.

Related

How to use correctly tridimensional arrays to save and print strings?

I have to save three different strings in n number of 2D arrays, for that reason I created a 3D array named datosCliente[size][4][size]. After that I have to print their content. But when I'm printing the strings in the first and second string the first character disappear, and the third string isn't printed.
The first string is the name of a country.
The second is the date of departure.
The last is the date of return.
This is the code:
#include <stdio.h>
#include <stdlib.h>
const int size = 100;
void ingresoDatos(char [size][4][size], int*);
void imprimirDatos(char [size][4][size], int*);
int main(void) {
char datosCliente[size][4][size];
int cant;
FILE *document;
document = fopen("data.txt", "a");
if(document == NULL) {
printf("Error al abrir el archivo.\n");
}else {
ingresoDatos(datosCliente, &cant);
imprimirDatos(datosCliente, &cant);
}
fclose(document);
return 0;
}
void ingresoDatos(char datos[size][4][size], int *cant) {
int tam = 0;
system("clear");
printf("Ingreso de datos\n");
do {
printf("Ingrese el número de clientes: ");
scanf("%d", &tam);
}while(tam >= 100 || tam <= 0);
*cant = tam;
for(int i = 1; i <= tam; i++) {
system("clear");
printf("Ingrese el destino: ");
fgets(&datos[i][0][0], 20, stdin);
getchar();
printf("Ingrese la fecha de salida: ");
fgets(&datos[i][1][0], 30, stdin);
getchar();
printf("Ingrese la fecha regreso: ");
fgets(&datos[i][2][0], 30, stdin);
getchar();
}
}
void imprimirDatos(char datos[size][4][size], int *cant) {
system("clear");
for(int i = 1; i <= *cant; i++) {
printf("Cliente %d:\n", i+1);
printf("Destino: %s", &datos[i][0][100]);
printf("Fecha de salida: %s", &datos[i][1][100]);
printf("Fecha de regreso: %s", &datos[i][2][100]);
printf("\n");
}
}
I enter this data:
tam: 1
Destino (to): China
Fecha de salida (depart in): 23 de septiembre de 2022
Fecha de regreso (return in): 24 de noviembre de 2022
And this is the output:
Cliente 1:
Destino: hina
Fecha de salida: 3 de septiembre de 2022
Fecha de regreso:
I had forgotten mention but I'm using Replit to do the code.
scanf("%d", &tam); doesn't consume a newline character even if it is entered. (c - fgets doesn't work after scanf - Stack Overflow) In my opinion, you shouldn't mix scanf() and fgets(). You can use fgets() to read a line and sscanf() to parse the line.
fgets() consumes a newline character (if it is entered). Calling getchar(); after that will drop the first character of the next line.
Considering these points, the function ingresoDatos should be:
void ingresoDatos(char datos[size][4][size], int *cant) {
int tam = 0;
system("clear");
printf("Ingreso de datos\n");
do {
char buffer[100];
printf("Ingrese el número de clientes: ");
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &tam);
}while(tam >= 100 || tam <= 0);
*cant = tam;
for(int i = 1; i <= tam; i++) {
system("clear");
printf("Ingrese el destino: ");
fgets(&datos[i][0][0], 20, stdin);
printf("Ingrese la fecha de salida: ");
fgets(&datos[i][1][0], 30, stdin);
printf("Ingrese la fecha regreso: ");
fgets(&datos[i][2][0], 30, stdin);
}
}

Problem in C - scanf() skipping input (It is not a problem with the buffer)

Basically, I have to make a currency prices conversion with a menu (Im in first year) but the second scanf that executes when you select the 0) is totally skipped; after that the program prints the menu again around 5 times and then it lets you select an option again. This is the only part that is not working, the rest is fine.
You may think that the problem is that the buffer has a newline stored from the previous scanf, but that is not the case as I am making sure to clean it. Also, don't mind the strings, they are just in spanish.
Thanks for your time!
'''
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
char e = ' ';
float le = 1.1, de = 0.9, din = 1, c1, c2;
while (e != 's') {
puts("\n ================================================================");
puts(" CONVERSION DE DIVISAS");
puts(" ================================================================");
puts("0) Introducir valores de cotizacion de monedas");
puts("a) Convertir euros a dolares y libras");
puts("b) Convertir dolares a euros y libras");
puts("c) Convertir libras a euros y dolares");
puts("s) Salir");
printf("\nIntroduzca su eleccion: ");
scanf(" %c", &e);
e = tolower(e);
fflush(stdin);
switch (e) {
case '0':
printf("\nIntroduzca cuantas libras son un euro: ");
scanf(" %9.4f ", &le);
fflush(stdin);
printf("Introduzca cuantos dolares son un euro: ");
scanf(" %9.4f ", &de);
fflush(stdin);
break;
default:
printf("\nOpcion incorrecta");
break;
}
}
return 0;
}
'''

Why is the output of my results 0.0000?

Hey people this is my first question on this page. I have been learning C in university and I have to complete an activity where I insert name, surname and 4 grades, of 3 different students. After that I must calculate average grade, maximum and minimum grade, and print those results on screen.
The program compiles correctly without errors, but when the results are printed, the program says that average grade, maximum and minimum grade are all equal to 0.000000.
I really don't know what the problem is and I would apreciate if anyone could check it out and help me in any way.
(Sorry if you don't understand the variable names, I'm from Argentina and they are in Spanish)
#include <stdio.h>
#define N 50
struct alumno
{
char nombre [N];
char apellido [N];
float nota1;
float nota2;
float nota3;
float nota4;
} alumno1, alumno2, alumno3;
struct notas
{
float prom;
float nmax;
float nmin;
} notas1, notas2, notas3;
float promedio (struct alumno a, struct notas b)
{
b.prom = (a.nota1 + a.nota2 + a.nota3 + a.nota4)/4;
return b.prom;
};
float notamaxima (struct alumno a, struct notas b)
{
if ((a.nota1>a.nota2) && (a.nota1>a.nota3) && (a.nota4>a.nota4))
{
b.nmax=a.nota1;
}
else if ((a.nota2>a.nota1) && (a.nota2>a.nota3) &&
(a.nota2>a.nota4))
{
b.nmax=a.nota2;
}
else if ((a.nota3>a.nota1) && (a.nota3>a.nota2) &&
(a.nota3>a.nota4))
{
b.nmax=a.nota3;
}
else if ((a.nota4>a.nota1) && (a.nota4>a.nota2) &&
(a.nota4>a.nota3))
{
b.nmax=a.nota4;
}
return 0;
};
float notaminima (struct alumno a, struct notas b)
{
if ((a.nota1<a.nota2) && (a.nota1<a.nota3) && (a.nota1<a.nota4))
{
b.nmin=a.nota1;
}
else if ((a.nota2<a.nota1) && (a.nota2<a.nota3) &&
(a.nota2<a.nota4))
{
b.nmin=a.nota2;
}
else if ((a.nota3<a.nota1) && (a.nota3<a.nota2) &&
(a.nota3<a.nota4))
{
b.nmin=a.nota3;
}
else if ((a.nota4<a.nota1) && (a.nota4<a.nota2) &&
(a.nota4<a.nota3))
{
b.nmin=a.nota4;
}
return 0;
};
int main ()
{
struct alumno;
struct notas;
printf ("Ingrese nombre del alumno:\n");
fgets (alumno1.nombre, N, stdin);
printf ("Ingrese apellido del alumno:\n");
fgets (alumno1.apellido, N, stdin);
printf ("Ingrese la primera nota del alumno:\n");
scanf ("%f", &alumno1.nota1);
printf ("Ingrese la segunda nota del alumno:\n");
scanf ("%f", &alumno1.nota2);
printf ("Ingrese la tercera nota del alumno:\n");
scanf ("%f", &alumno1.nota3);
printf ("Ingrese la cuarta nota del alumno:\n");
scanf ("%f", &alumno1.nota4);
promedio (alumno1, notas1);
notamaxima (alumno1, notas1);
notaminima (alumno1, notas1);
printf ("El promedio del primer alumno es %f\n", notas1.prom);
printf ("La nota maxima del primer alumno es %f\n", notas1.nmax);
printf ("La nota minima del primer alumno es %f\n", notas1.nmin);
printf ("Ingrese nombre del alumno:\n");
fgets (alumno1.nombre, N, stdin);
printf ("Ingrese apellido del alumno:\n");
fgets (alumno1.apellido, N, stdin);
printf ("Ingrese la primera nota del alumno:\n");
scanf ("%f", &alumno2.nota1);
printf ("Ingrese la segunda nota del alumno:\n");
scanf ("%f", &alumno2.nota2);
printf ("Ingrese la tercera nota del alumno:\n");
scanf ("%f", &alumno2.nota3);
printf ("Ingrese la cuarta nota del alumno:\n");
scanf ("%f", &alumno2.nota4);
promedio (alumno2, notas2);
notamaxima (alumno2, notas2);
notaminima (alumno2, notas2);
printf ("El promedio del segundo alumno es %f\n", notas2.prom);
printf ("La nota maxima del segundo alumno es %f\n", notas2.nmax);
printf ("La nota minima del segundo alumno es %f\n", notas2.nmin);
printf ("Ingrese nombre del alumno:\n");
fgets (alumno1.nombre, N, stdin);
printf ("Ingrese apellido del alumno:\n");
fgets (alumno1.apellido, N, stdin);
printf ("Ingrese la primera nota del alumno:\n");
scanf ("%f", &alumno3.nota1);
printf ("Ingrese la segunda nota del alumno:\n");
scanf ("%f", &alumno3.nota2);
printf ("Ingrese la tercera nota del alumno:\n");
scanf ("%f", &alumno3.nota3);
printf ("Ingrese la cuarta nota del alumno:\n");
scanf ("%f", &alumno3.nota4);
promedio (alumno3, notas3);
notamaxima (alumno3, notas3);
notaminima (alumno3, notas3);
printf ("El promedio del tercer alumno es %f\n", notas3.prom);
printf ("La nota maxima del tercer alumno es %f\n", notas3.nmax);
printf ("La nota minima del tercer alumno es %f\n", notas3.nmin);
return 0;
}
I think the function here you used doesn't make any changes
float promedio (struct alumno a, struct notas b)
All parameters you send to the function need to be the address type
like this
void promedio (struct alumno *a, struct notas *b)
.
.
.
promedio (&alumno3, &notas3);
The question about call by value & call by reference
Another question is you always return 0 in every each function
Why not use 'void' or return the calculation results , and the result must need to be accepted by a parameter
float notamaxima (struct alumno a, struct notas b)
{
if ((a.nota1>a.nota2) && (a.nota1>a.nota3) && (a.nota4>a.nota4))
{
return a.nota1;
}...
}
b.nmax = notamaxima (alumno1, notas1);
It's impossible your professors didn't know that.
sry for my eng

Unable to start the int correctly and keep the number back from the function

First at all sorry for my english, i will try my best.
Well, here's the problem, I am making a C program just for learning, the program is basically a students manager, I wanted to add a final function in which the user would be prompted by an id to by remove and after inserting that id the student would be eliminate from the database, the problem is... when the data is inserted in the first case there's added a subroutine that automatically adds the id as and int in the struct,problem is it shows a random int number like "43405" or so I thought to start the integer to 1, the problem is when the function is re-called again id will back to be 1 and that just simply don't work.
P.D:I read some of you guys told me about to make the code more readable, can you give me a nice "tutorial" or so to make that?
Function:
int insertar_notas(struct alumnos notas[20], int n,int id_alumno){
char resp[3];
system("cls");
puts("\n \a Insercion del alumno\n");
while (!strstr(resp,"no")){
fflush(stdin);
printf("\nEl ID de este alumno sera: %d\n", id_alumno);
notas[n].id=id_alumno;
id_alumno++;
puts("\nDime el nombre del Alumno\n");
scanf("%10s", notas[n].alumno );
system("cls");
fflush(stdin);
puts("\nDime el apellido del Alumno\n");
scanf("%10s", notas[n].apellido );
system("cls");
puts("\nDime la Primera nota trimestral del Alumno[1.23]\n");
scanf("%f", &notas[n].nota1 );
system("cls");
puts("\nDime la Segunda nota trimestral del Alumno[1.23]\n");
scanf("%f", &notas[n].nota2 );
system("cls");
puts("\nDime la Tercera nota trimestral del Alumno[1.23]\n");
scanf("%f", &notas[n].nota3 );
n++;
system("cls");
puts("\nQuieres volver a insertar otro?[si|no]\n");
scanf("%3s", resp);
strlwr(resp);
}
return n;
return id_alumno;
}
Main for more info:
int main (void){
int menu = 0, n = 0, id_alumno;
struct alumnos notas[20];
puts("\n<><><>Bienvenido al recuento de notas de la escuela<><><>\n");
puts("\nQue deseas hacer?\n");
while (menu != 5){
puts("\n1)Insertas las notas de un alumno\n2)Ver todas las notas\n3)Ver las notas de un alumno\n4)Modificar notas\n5)Salir\n");
scanf("%d", &menu);
switch(menu){
case 1:
n=insertar_notas(notas,n,id_alumno);
break;
C uses pass by value, so to make id_alumno modifiable you need to pass it as a pointer:
int insertar_notas(struct alumnos notas[20], int n,int *id_alumno) { // id_alumno is now a pointer to int inside this function
char resp[3];
system("cls");
puts("\n \a Insercion del alumno\n");
while (!strstr(resp,"no")){
fflush(stdin);
printf("\nEl ID de este alumno sera: %d\n", *id_alumno); // Use * to access the value
notas[n].id=id_alumno;
(*id_alumno)++; // Use * to access the value. ++ has higher precedence than *, so need parenthesis around *id_alumno
...
And in the call from main:
n=insertar_notas(notas, n, &id_alumno); // address-of id_alumno
Also, you need to initialize id_alumno in main:
int menu = 0, n = 0, id_alumno = 1;

My program starts the loop before scan is done

I have a little problem, my program works well until it arrives to the final step, a scanf which asks for continuation of the loop. The problem is that this scan isn't working, but the following system("cls") works. Looks like javascript when async.
Here is the code.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char elegir_dificultad;
int dificil = 1;
printf("Desea que se le indique si el numero es menor o mayor? \n s/n \n");
scanf("%c",&elegir_dificultad);
if(elegir_dificultad == 's'){
dificil = 0;
}
while(1){
int aleatorio, cont, introducido;
cont = 1;
aleatorio = rand()%101;
printf("%d",aleatorio);
int fallo = 1;
while(fallo){
printf("Introduce el numero, intento numero %d \n", cont);
scanf("%d",&introducido);
if(introducido == aleatorio){
fallo = 0;
}
if(cont == 10){
break;
}
if(!dificil){
if(introducido < aleatorio){
printf("El numero introducido es menor que el aleatorio \n");
}
if(introducido > aleatorio){
printf("El numero introducido es mayor que el aleatorio \n");
}
}
if(fallo){
cont++;
}
}
char continuar;
if(fallo){
printf("Has perdido... el numero era %d \n Quieres repetirlo? s/n \n",aleatorio);
scanf("%c",&continuar);
if(continuar=='n'){
break;
}
system("cls");
}else{
printf("°Has ganado! el numero era %d \n Quieres repetirlo? s/n \n",aleatorio);
scanf("%c",&continuar);
if(continuar=='n'){
break;
}
system("cls");
}
}
system("PAUSE");
return 0;
}
This problem is because of \n character left behind by the previous scanf. Place a space before each %c specifier in scanf to eat up \n. .
scanf(" %c", &introducido);
...
scanf(" %c",&continuar);

Resources