Wrong output with C program - c

I'm trying to get this code work:
#include <stdio.h>
#include <conio.h>
#define N 2
typedef struct identite {
char numClient[20];
char nom[20];
char prenom[20];
} Identite;
typedef struct facture {
int numFacture;
Identite personne;
float prix;
int anlimite;
} Facture;
Facture tabFactures[10];
// initialisation ???
Facture saisirFacture() {
Facture uneFacture;
printf("saisissez le numero de la facture: ");
scanf("%d", &uneFacture.numFacture);
printf("saisissez le numero du client: ");
scanf("%s", &uneFacture.personne.numClient);
printf("saisissez le nom du client: ");
scanf("%s", &uneFacture.personne.nom);
printf("saisissez le prenom du client: ");
scanf("%s", &uneFacture.personne.prenom);
printf("saisissez le prix: ");
scanf("%f", &uneFacture.prix);
printf("saisissez anlimite: ");
scanf("%d", &uneFacture.anlimite);
printf("Vous avez renseigné tous les champs, Merci.\n");
return uneFacture;
}
void saisirTabFacture() {
int i;
i = 0;
Facture fi;
while (i < N) {
tabFactures[i] = fi;
saisirFacture(fi);
i++;
}
getch();
}
void afficheFacture(Facture uneFacture) {
printf("le numero de la facture est:%d\n", uneFacture.numFacture);
printf("le numero du client est:%s\n", uneFacture.personne.numClient);
printf("le nom du client est:%s\n", uneFacture.personne.nom);
printf("le prenom du client est:%s\n", uneFacture.personne.prenom);
printf("le prix est:%f\n", uneFacture.prix);
printf("annee limite est:%d\n", uneFacture.anlimite);
getch();
}
void afficheTabFacture() {
Facture fi;
int i;
for (i = 0;i < N - 1;i++) {
tabFactures[i] = fi
afficheFacture(tabFactures);
}
}
int main() {
Facture tabFactures[N];
Facture uneFacture;
printf("la saisie des factures : \n");
saisirTabFacture();
printf("les factures qui vous avez saisi sont:");
afficheTabFacture(tabFactures);
return 0;
}
Everything works fine except the output of the function afficherTabFacture(tabFactures), instead of giving the strings I have entered it gives special characters, or it gives O or empty values. Here is an image:
Could you please help me to solve it?

There are multiple problems in your code:
saisirFacture returns a Facture by value, but you do not store this return value, instead you pass a Facture as an argument in saisirTabFacture.
There is local array tabFactures in main and a global variable by the same name: main and saisirTabFacture are not referring to the same array.
afficheTabFacture should be passed a Facture object, not an array of Facture objects.
Here is a modified version that will prompt for 2 bills and then print them:
#include <stdio.h>
#include <conio.h>
#define N 2
typedef struct identite {
char numClient[20];
char nom[20];
char prenom[20];
} Identite;
typedef struct facture {
int numFacture;
Identite personne;
float prix;
int anlimite;
} Facture;
Facture saisirFacture(void) {
Facture uneFacture;
printf("saisissez le numero de la facture: ");
scanf("%d", &uneFacture.numFacture);
printf("saisissez le numero du client: ");
scanf("%19s", uneFacture.personne.numClient);
printf("saisissez le nom du client: ");
scanf("%19s", uneFacture.personne.nom);
printf("saisissez le prenom du client: ");
scanf("%19s", uneFacture.personne.prenom);
printf("saisissez le prix: ");
scanf("%f", &uneFacture.prix);
printf("saisissez anlimite: ");
scanf("%d", &uneFacture.anlimite);
printf("Vous avez renseigné tous les champs, Merci.\n");
return uneFacture;
}
void saisirTabFacture(Facture tabFactures[]) {
for (int i = 0; i < N; i++) {
tabFactures[i] = saisirFacture();
}
getch();
}
void afficheFacture(Facture uneFacture) {
printf("le numero de la facture est:%d\n", uneFacture.numFacture);
printf("le numero du client est:%s\n", uneFacture.personne.numClient);
printf("le nom du client est:%s\n", uneFacture.personne.nom);
printf("le prenom du client est:%s\n", uneFacture.personne.prenom);
printf("le prix est:%f\n", uneFacture.prix);
printf("annee limite est:%d\n", uneFacture.anlimite);
getch();
}
void afficheTabFacture(Facture tabFactures[]) {
for (int i = 0; i < N; i++) {
afficheFacture(tabFactures[i]);
}
}
int main(void) {
Facture tabFactures[N];
Facture uneFacture;
printf("la saisie des factures : \n");
saisirTabFacture(tabFactures);
printf("les factures qui vous avez saisi sont:");
afficheTabFacture(tabFactures);
return 0;
}

Related

Error "a label can only be part of a statement" when compiling file line 17 in the main() function [duplicate]

This question already has answers here:
Why can we not declare a variable after a switch case colon without using curly braces?
(3 answers)
Closed last month.
I have a problem compiling the code in the main file at line 17.
The error is
"a label can only be part of a statement and a declaration is not a statement".
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#define TAILLE_MAX_NOM 50
// Définition du type Compte
typedef struct {
int RIB;
float solde;
char etat[TAILLE_MAX_NOM];
float plafond_credit;
int nb_operations;
float operations[100];
} Compte;
Compte T_Compte[100];
int menu();
void CreerCompte(Compte *C);
int ChercherCompte(Compte T_Compte[],int NC,int RIB );
void AjouterCompte (Compte T_Compte[], int *NC, Compte C);
float Ajouter_Retirer (Compte T_Compte[], int NC, float M,int RIB);
void ListeComptes(Compte T_Compte[], int NC);
void StatCompte (Compte T_Compte[], int NC, int *PNBA,int *PNBR ,int RIB);
void Prime (Compte T_Compte[], int NC);
#endif // HEADER_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
int menu() {
int choix;
printf("\n\n -> Menu <- \n\n");
printf(" 1 - Ajouter un Nouveau Compte \n");
printf(" 2 - Afficher les comptes de la banque \n");
printf(" 3 - Ajouter une operation a un compte\n");
printf(" 4 - Attribuer une prime aux meilleurs comptes bancaires \n");
printf(" 0 - Quitte\n");
printf("\n --------------------------------------\n");
do {
printf(" -> Tapez votre choix : ");
scanf("%d",&choix);
printf("\n\n");
} while (choix>4 || choix<0);
return choix;
}
void CreerCompte(Compte *C) {
printf("RIB du compte : ");
scanf("%d", &C->RIB);
printf("Solde initial du compte (supérieur ou égal à 50) : ");
scanf("%f", &C->solde);
while (C->solde < 50) {
printf("Le solde initial doit être supérieur ou égal à 50 !\n");
printf("Solde initial du compte (supérieur ou égal à 50) : ");
scanf("%f", &C->solde);
}
strcpy(C->etat, "debiteur");
printf("Plafond de crédit du compte (strictement négatif supérieur à -500) : ");
scanf("%f", &C->plafond_credit);
while (C->plafond_credit >= 0 || C->plafond_credit <= -500) {
printf("Le plafond de crédit doit être un montant strictement négatif supérieur à -500 !\n");
printf("Plafond de crédit du compte (strictement négatif supérieur à -500) : ");
scanf("%f", &C->plafond_credit);
}
C->nb_operations = 0;
}
int ChercherCompte(Compte T_Compte[], int NC, int RIB) {
for (int i = 0; i < NC; i++) {
if (T_Compte[i].RIB == RIB) {
return i;
}
}
return -1;
}
void AjouterCompte(Compte T_Compte[], int *NC, Compte C) {
if (ChercherCompte(T_Compte, *NC, C.RIB) != -1) {
printf("Un compte avec ce RIB existe déjà !\n");
return;
}
T_Compte[*NC] = C;
(*NC)++;
}
float Ajouter_Retirer(Compte T_Compte[], int NC, float M, int RIB) {
// Vérifie que la somme à ajouter ou retirer est non nulle
if (M == 0) {
printf("La somme à ajouter ou retirer ne peut pas être nulle !\n");
return -1;
}
// Cherche le compte dans le tableau
int pos = ChercherCompte(T_Compte, NC, RIB);
// Vérifie que le compte existe
if (pos == -1) {
printf("Le compte avec le RIB spécifié n'existe pas !\n");
return -1;
}
Compte C = T_Compte[pos];
// Vérifie que l'opération de retrait peut être effectuée
if (M < 0 && (C.solde + M < -C.plafond_credit)) {
printf("Opération de retrait impossible !\n");
return -1;
}
// Effectue l'opération
C.solde += M;
C.nb_operations++;
T_Compte[pos] = C;
return C.solde;
}
void ListeComptes(Compte T_Compte[], int NC) {
printf("Liste des comptes de la banque :\n");
for (int i = 0; i < NC; i++) {
Compte C = T_Compte[i];
printf("RIB : %d, Solde : %.2f, Etat : %s, Plafond de crédit : %.2f, Nombre d'opérations : %d\n",
C.RIB, C.solde, C.etat, C.plafond_credit, C.nb_operations);
}
}void StatCompte(Compte T_Compte[], int NC, int *PNBA, int *PNBR, int RIB) {
// Initialise les compteurs à 0
*PNBA = 0;
*PNBR = 0;
// Cherche le compte dans le tableau
int pos = ChercherCompte(T_Compte, NC, RIB);
if (pos == -1) {
printf("Le compte avec ce RIB n'existe pas !\n");
return;
}
// Parcours les opérations du compte
Compte C = T_Compte[pos];
for (int i = 0; i < C.nb_operations; i++) {
if (C.operations[i] > 0) {
(*PNBA)++;
} else if (C.operations[i] < 0) {
(*PNBR)++;
}
}
}
void Prime(Compte T_Compte[], int NC) {
printf("Attribution de la prime aux meilleurs comptes de la banque :\n");
for (int i = 0; i < NC; i++) {
Compte C = T_Compte[i];
// Vérifie que le compte est débiteur
if (strcmp(C.etat, "debiteur") == 0) {
int nb_ajout = 0;
int nb_retrait = 0;
// Parcours les opérations du compte pour compter le nombre d'opérations d'ajout et de retrait
for (int j = 0; j < C.nb_operations; j++) {
if (C.operations[j] > 0) {
nb_ajout++;
} else if (C.operations[j] < 0) {
nb_retrait++;
}
}
// Vérifie que le nombre d'opérations d'ajout est supérieur aux nombres d'opérations de retrait
if (nb_ajout > nb_retrait) {
float prime = (C.solde / C.nb_operations) * 0.5;
printf("RIB : %d - Prime : %.2f\n", C.RIB, prime);
}
}
}
}
//source file/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "header.h"
int main() {
// Initialize the array of accounts
int NC = 0;
// Display the menu and get the user's choice
int choix = menu();
while (choix != 0) {
switch (choix) {
case 1:
Compte C;
getchar();
CreerCompte(&C);
AjouterCompte(T_Compte, &NC, C);
break;
case 2:
// Display the accounts
ListeComptes(T_Compte, NC);
break;
case 3:
// Add or remove money from an account
printf("RIB du compte : ");
int RIB;
scanf("%d", &RIB);
printf("Somme à ajouter ou retirer : ");
float M;
scanf("%f", &M);
float solde = Ajouter_Retirer(T_Compte, NC, M, RIB);
if (solde != -1) {
printf("Nouveau solde : %.2f\n", solde);
}
break;
case 4:
// Attribute a prize to the best accounts
Prime(T_Compte, NC);
break;
}
// Display the menu and get the user's choice again
choix = menu();
}
printf("Au revoir !\n");
return 0;
}
Here is the main function that uses 4 switches to perform the following functions:
Add a new account
Display the accounts of the bank
Add an operation to an account
Attribute a prize to the best accounts
Is this line 17?
Compte C;
If so, you need to scope the variable C. Change the case 1: handler to this:
case 1:
{
Compte C;
getchar();
CreerCompte(&C);
AjouterCompte(T_Compte, &NC, C);
break;
}

Problem with duplicate data in fgets with structs [duplicate]

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 5 months ago.
I have a program that seems to have a problem displaying the data received from a .txt file with fgets
Basically the program is something similar to a CRUD or ABM (in Spanish).
The problem is that when I show the structs from the file, it shows me a duplicate of the last struct.
The code is the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
// ==== Estructura Empleado ====
typedef struct
{
int legajo; // Numero de 6 digitos
char nombreApellido[30];
float sueldo; // Aleatorio entre 80k-200k
} Empleado;
// Carga un empleado por teclado; Devuelve un struct Empleado
Empleado cargarEmpleadoPorTeclado();
// Carga un vector de Empleado
void cargarEmpleadosPorTeclado(Empleado empleados[], int cantidadEmpleados);
// Recibe un vector de chars y devuelve un struct Empleado
Empleado parsearEmpleado(char datosSinParsear[50], int largoDatos);
// Carga los empleados desde el archivo al vector empleados[]
void cargarEmpleadosEnVector(Empleado empleados[], int cantidadEmpleados);
// Guarda los empleados en el archivo 'empleados.txt'
void guardarEmpleados(Empleado empleados[], int cantidadEmpleados);
// Muestra los empleados cargados en el vector empleados[]
void mostrarEmpleadosDesdeArchivo(int cantidadEmpleados, int eliminados);
// Busca un empleado por legajo en el archivo 'empleados.txt' y lo 'elimina'
void eliminarEmpleadoPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int * eliminados);
void eliminarEmpleadoVectorPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int *eliminados);
void menu(Empleado empleados[], int cantidadEmpleados);
/* ==== Funcion main ==== */
int main()
{
int cantidadEmpleados = 100;
Empleado empleados[cantidadEmpleados];
menu(empleados, cantidadEmpleados);
return 0;
}
/* ==== Implementaciones ==== */
Empleado cargarEmpleadoPorTeclado()
{
Empleado empleado;
printf("\nIngrese el Nombre y Apellido del empleado: ");
fflush(stdin);
gets(empleado.nombreApellido);
printf("\nIngrese el numero de Legajo del empleado: ");
fflush(stdin);
scanf("%d", &empleado.legajo);
empleado.sueldo = 80000 + rand() % (200000-80000);
return empleado;
}
void cargarEmpleadosPorTeclado(Empleado empleados[], int cantidadEmpleados)
{
for (int i = 0; i < cantidadEmpleados; i++)
{
empleados[i] = cargarEmpleadoPorTeclado();
}
guardarEmpleados(empleados, cantidadEmpleados);
}
Empleado parsearEmpleado(char datosSinParsear[], int largoDatos)
{
Empleado empleado;
int delimitador1 = -1;
int delimitador2 = -1;
char auxiliarLegajo[10] = " ";
char auxiliarNombreApellido[30] = " ";
char auxiliarSueldo[10] = " ";
for(int i = 0; i < largoDatos; i++)
{
// Recorro el string hasta encontrar la primera ocurrencia
// Notese que i = largoDatos es para forzar la salida del for y no sobreescribir el valor de delimitador1
// con la segunda ocurrencia
if(datosSinParsear[i] == ';')
{
delimitador1 = i;
i = largoDatos;
}
}
// Recorro el string a partir de la posicion siguiente de la primera ocurrencia
for (int i = delimitador1 + 1; i < largoDatos; i++)
{
if (datosSinParsear[i] == ';')
{
delimitador2 = i;
}
}
if ((delimitador1 != -1) && (delimitador2 != -1))
{
// Desde 0 hasta delimitador1 tenemos el legajo
for (int i = 0; i < delimitador1; i++)
{
auxiliarLegajo[i] = datosSinParsear[i];
}
// Desde delimitador1+1 hasta delimitador2 tenemos el nombre y apellido
for (int i = delimitador1 + 1; i < delimitador2; i++)
{
auxiliarNombreApellido[i - delimitador1 - 1] = datosSinParsear[i];
}
// Desde delimitador2+1 hasta largoDatos tenemos el sueldo en float
for (int i = delimitador2 + 1; i < strlen(datosSinParsear); i++)
{
auxiliarSueldo[i - delimitador2 - 1] = datosSinParsear[i];
}
empleado.legajo = atoi(auxiliarLegajo);
strcpy(empleado.nombreApellido, auxiliarNombreApellido);
empleado.sueldo = atof(auxiliarSueldo);
return empleado;
}
}
void cargarEmpleadosEnVector(Empleado empleados[], int cantidadEmpleados)
{
// Intentamos abrir el archivo y verificamos si no es un puntero nulo
FILE * archivoEmpleados = fopen("empleados.txt", "r");
if(archivoEmpleados != NULL)
{
int i = 0;
while (!feof(archivoEmpleados) && (i < cantidadEmpleados))
{
char datosSinParsear[50] = "";
Empleado empleadoActual;
// Leemos los datos y lo parseamos
fgets(datosSinParsear, 50, archivoEmpleados);
empleadoActual = parsearEmpleado(datosSinParsear, 50);
// Lo asignamos a la posicion actual del vector 'empleados[]'
empleados[i] = empleadoActual;
i++;
}
fclose(archivoEmpleados);
}
// Si el archivo no existe o no lo encuentra
else
{
printf("\nImposible leer los empleados\nEl archivo \"empleados.txt\" no existe o no se encuentra en la ruta actual");
exit(-1);
}
}
void guardarEmpleados(Empleado empleados[], int cantidadEmpleados)
{
// Intentamos abrir el archivo y verificamos si no es un puntero nulo
FILE * archivoEmpleados = fopen("empleados.txt", "w");
if(archivoEmpleados != NULL)
{
for (int i = 0; i < cantidadEmpleados; i++)
{
// Grabamos los datos linea por linea con el formato 'legajo;nombreapellido;sueldo'
fprintf(archivoEmpleados, "%d;%s;%.2f\n", empleados[i].legajo, empleados[i].nombreApellido, empleados[i].sueldo);
}
printf("\nEmpleados guardados exitosamente en \"empleados.txt\"");
fclose(archivoEmpleados);
}
// Si el archivo no existe o no lo encuentra
else
{
printf("\nImposible guardar los empleados\nEl archivo \"empleados.txt\" no existe o no se encuentra en la ruta actual");
exit(-1);
}
}
void mostrarEmpleadosDesdeArchivo(int cantidadEmpleados, int eliminados)
{
FILE * archivoEmpleados = fopen("empleados.txt", "r");
int i = 0;
while(!feof(archivoEmpleados) && i < (cantidadEmpleados-eliminados))
{
char datosSinParsear[50] = "";
fgets(datosSinParsear, 50, archivoEmpleados);
Empleado empleadoActual;
empleadoActual = parsearEmpleado(datosSinParsear, 50);
printf("\nEmpleado");
printf("\n\t* Numero de legajo: %d", empleadoActual.legajo);
printf("\n\t* Nombre y Apellido: %s", empleadoActual.nombreApellido);
printf("\n\t* Sueldo (en pesos): %.2f", empleadoActual.sueldo);
i++;
}
fclose(archivoEmpleados);
}
/*
Esta funcion no elimina en si la linea que pertenezca al empleado
Sino mas bien, la omitiria cuando la lea, escribiendo un archivo nuevo con el mismo nombre
De esa forma, estariamos haciendo lo mismo
*/
void eliminarEmpleadoPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int *eliminados)
{
// Intentamos abrir el archivo y verificamos si no es un puntero nulo
FILE * archivoEmpleados = fopen("empleados.txt", "r");
// Creamos un nuevo archivo para escribir los datos
FILE * nuevoArchivoEmpleados = fopen("empleados2.txt", "w");
if(archivoEmpleados != NULL)
{
int i = 0;
while (!feof(archivoEmpleados) && i < cantidadEmpleados)
{
char datosSinParsear[50] = "";
Empleado empleadoActual;
// Recibimos los datos y los parseamos
fgets(datosSinParsear, 50, archivoEmpleados);
empleadoActual = parsearEmpleado(datosSinParsear, 50);
/*
Cuando no coincida el legajo, escribe
Si es que llega a coincidir (justamente ese debemos eliminar), no lo escribimos,
simplemente, hacemos una iteración y continuamos el bucle
*/
if (empleadoActual.legajo != legajo)
{
fprintf(nuevoArchivoEmpleados, "%d;%s;%.2f\n", empleadoActual.legajo, empleadoActual.nombreApellido, empleadoActual.sueldo);
i++;
}
else
{
i++;
continue;
};
}
fclose(archivoEmpleados);
fclose(nuevoArchivoEmpleados);
remove("empleados.txt");
rename("empleados2.txt", "empleados.txt");
eliminarEmpleadoVectorPorLegajo(empleados, legajo, cantidadEmpleados, &eliminados);
*eliminados = *eliminados + 1;
printf("\nEmpleado con legajo numero %d eliminado exitosamente", legajo);
}
// Si el archivo no existe o no lo encuentra
else
{
printf("\nImposible eliminar al empleado\nEl archivo \"empleados.txt\" no existe o no se encuentra en la ruta actual");
exit(-1);
}
}
void eliminarEmpleadoVectorPorLegajo(Empleado empleados[], int legajo, int cantidadEmpleados, int *eliminados)
{
int posicionDelElemento = -1;
for (int i = 0; i < cantidadEmpleados; i++)
{
if(empleados[i].legajo == legajo)
{
posicionDelElemento = i;
i = cantidadEmpleados;
}
}
for(int i = posicionDelElemento - 1; i<cantidadEmpleados-1; i++)
{
empleados[i] = empleados[i + 1];
}
cantidadEmpleados--;
}
void menu(Empleado empleados[], int cantidadEmpleados)
{
int sigue = 1;
int eliminados = 0;
int cantidadEmpleadosVar = 0;
printf("\nMenu Empleados\n");
printf("\nOpciones:\n");
printf("\n\t1. Listar los empleados");
printf("\n\t2. Agregar un empleado");
printf("\n\t3. Eliminar un empleado");
printf("\n\t4. Salir");
do
{
int opcion;
int legajo;
printf("\nIngrese opcion > ");
scanf("%d", &opcion);
switch (opcion)
{
case 1:
printf("\nMostrando empleados cargados");
mostrarEmpleadosDesdeArchivo(cantidadEmpleados, eliminados);
break;
case 2:
printf("\nAgregar un empleado:");
printf("\nCuantos empleados desea cargar? > ");
scanf("%d", &cantidadEmpleadosVar);
cargarEmpleadosPorTeclado(empleados, cantidadEmpleadosVar);
break;
case 3:
printf("\nEliminando un empleado:");
printf("\nIngrese el numero de legajo del empleado a eliminar > ");
scanf("%d", &legajo);
eliminarEmpleadoPorLegajo(empleados, legajo, cantidadEmpleados, &eliminados);
break;
case 4:
sigue = 0;
break;
default:
printf("\nLa opcion \"%d\" no es valida, ingrese otra vez\n\n", opcion);
continue;
break;
}
} while (sigue);
}
And the empleados.txt file is the following:
555666;Leandro;80041.00
232433;Juan;80945.00
234443;Antonio;90485.00
119304;Manuel;102943.00
The output is:
Code output linked on imgur
Does anyone know what this error could be?
There are many issues in your code, here are some important ones:
you must not use gets(): read Why is the gets function so dangerous that it should not be used?
you should test the return value of fgets() to determine if a line was read or if end of file has been reached.
using feof() for this purpose as you do is incorrect. You should read Why is “while( !feof(file) )” always wrong?
you should always test for fopen() success before calling any stream function with the FILE pointer.
Also use more spaces for indentation, 4 is recommended for readability.

Reading integer from file through function in c returns wrong value

I'm trying to read a bunch of information about a player from a binary file in c through the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// structure joueur
typedef struct Joueur {
char nom[20];
int num_lieu;
int liste_objet[10];
}Joueur;
// question a
void sauvegarder_jeu(char* nom_partie, Joueur* joueur) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "wb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// écriture du nom du joueur
fwrite(joueur->nom, sizeof(joueur->nom), 1, flot);
// écriture du numero du lieu
fwrite(&(joueur->num_lieu), sizeof(joueur->num_lieu), 1, flot);
// écriture de la liste des objets
fwrite(joueur->liste_objet, sizeof(joueur->liste_objet), 1, flot);
// fermeture du fichier
fclose(flot);
}
// question b
void charger_jeu(char* nom_partie, char* nom, int* num_lieu, int* liste_objet) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "rb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// joueur temp pour sizeof
Joueur *temp = (Joueur*)malloc(sizeof(Joueur));
// lecture du nom du joueur
fread(nom, sizeof(temp->nom), 1, flot);
// écriture du numero du lieu
fread(&num_lieu, sizeof(temp->num_lieu), 1, flot);
// écriture de la liste des objets
fread(liste_objet, sizeof(temp->liste_objet), 1, flot);
// suppression du joueur temporaire
free(temp);
// fermeture du fichier
fclose(flot);
}
int main() {
// variables
char *nom_partie = "save.sve";
int i;
int* num_lieu_lecture;
int* liste_objet_lecture;
char* nom_lecture;
// creation d'un joueur qui possede tous les objets
Joueur *j1 = (Joueur*)malloc(sizeof(Joueur));
strcpy(j1->nom, "Omar");
j1->num_lieu = 12;
for (i = 0; i < 10; i++) {
j1->liste_objet[i] = 1;
}
// sauvegarde de la partie
sauvegarder_jeu(nom_partie, j1);
printf("Sauvegarde terminee!\n");
// lecture de la partie
charger_jeu(nom_partie, nom_lecture, num_lieu_lecture, liste_objet_lecture);
printf("Chargement terminee!\n");
// affichage des donnees de la partie
printf("%s\n", nom_lecture);
printf("%d\n", *num_lieu_lecture);
for (i = 0; i < 10; i++) {
printf("liste_objet[%d] = %d\n", i, liste_objet_lecture[i]);
}
// liberation de la memoire
free(j1);
return 0;
}
The function "sauvegarder_jeu()" writes the player's data into a binary file, and the "charger_jeu()" is supposed to read that data and store into variables that I would print out.
The output, where all the values are correct expect for the "num_lieu_lecture" value:
Omar
32759
liste_objet[0] = 1
liste_objet[1] = 1
liste_objet[2] = 1
liste_objet[3] = 1
liste_objet[4] = 1
liste_objet[5] = 1
liste_objet[6] = 1
liste_objet[7] = 1
liste_objet[8] = 1
liste_objet[9] = 1
I don't know where the problem stems from.
The variables you're passing to charger_jeu() do not need to be pointers. num_liste_objet should be int, and liste_objet_lecture and nom_lecture should be arrays.
Then you should pass the address of num_liste_objet to charger_jeu(), so it will update the variable. In charger_jeu() you don't need to use & before num_lieu because it's already a pointer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// structure joueur
typedef struct Joueur {
char nom[20];
int num_lieu;
int liste_objet[10];
}Joueur;
// question a
void sauvegarder_jeu(char* nom_partie, Joueur* joueur) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "wb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// écriture du nom du joueur
fwrite(joueur->nom, sizeof(joueur->nom), 1, flot);
// écriture du numero du lieu
fwrite(&(joueur->num_lieu), sizeof(joueur->num_lieu), 1, flot);
// écriture de la liste des objets
fwrite(joueur->liste_objet, sizeof(joueur->liste_objet), 1, flot);
// fermeture du fichier
fclose(flot);
}
// question b
void charger_jeu(char* nom_partie, char* nom, int* num_lieu, int* liste_objet) {
// ouverture du fichier
FILE *flot;
flot = fopen(nom_partie, "rb");
if (flot == NULL) {
printf("Erreur dans l'ouverture du fichier!\n");
return;
}
// joueur temp pour sizeof
Joueur *temp = (Joueur*)malloc(sizeof(Joueur));
// lecture du nom du joueur
fread(nom, sizeof(temp->nom), 1, flot);
// écriture du numero du lieu
fread(num_lieu, sizeof(temp->num_lieu), 1, flot);
// écriture de la liste des objets
fread(liste_objet, sizeof(temp->liste_objet), 1, flot);
// suppression du joueur temporaire
free(temp);
// fermeture du fichier
fclose(flot);
}
int main() {
// variables
char *nom_partie = "save.sve";
int i;
int num_lieu_lecture;
int liste_objet_lecture[10];
char nom_lecture[20];
// creation d'un joueur qui possede tous les objets
Joueur *j1 = (Joueur*)malloc(sizeof(Joueur));
strcpy(j1->nom, "Omar");
j1->num_lieu = 12;
for (i = 0; i < 10; i++) {
j1->liste_objet[i] = 1;
}
// sauvegarde de la partie
sauvegarder_jeu(nom_partie, j1);
printf("Sauvegarde terminee!\n");
// lecture de la partie
charger_jeu(nom_partie, nom_lecture, &num_lieu_lecture, liste_objet_lecture);
printf("Chargement terminee!\n");
// affichage des donnees de la partie
printf("%s\n", nom_lecture);
printf("%d\n", *num_lieu_lecture);
for (i = 0; i < 10; i++) {
printf("liste_objet[%d] = %d\n", i, liste_objet_lecture[i]);
}
// liberation de la memoire
free(j1);
return 0;
}

I have some problems with linked lists

I have some problems with my code. I want to load a file (i can do it in "cargar" function), i have my menu, my "show list" function (mostrar_lista) and my "add function" (anadir_elemento) but i have problems with guardar (my save function).
When I use my save function (guardar) i can't save anything, my file "records.txt" just collapses and i have a file with 700.000 Kbytes.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct unDisco{
char titulo[100];
char artista[100];
short fecha;
char formato[50];
float precio;
struct unDisco *siguiente;
};
struct unDisco *primero, *ultimo;
void cargar(){
FILE *discoteca;
discoteca = fopen("records.txt","r");
if (discoteca==NULL){
return ;
}else{
char ayuda, titulo[100], artista[100], formato[50];
int cont=0, k, fecha, n;
float precio;
while((ayuda=fgetc(discoteca))!=EOF){
if (ayuda=='\n'){
cont++;
}
}
rewind(discoteca);
char linea[cont][1024];
for (k=0;k<cont;k++){
fgets(linea[k],1023,discoteca);
struct unDisco *disco=(struct unDisco *)malloc(sizeof(struct unDisco));
sscanf(linea[k]," %s %s %i %s %f", titulo,artista,&fecha,formato,&precio);
strcpy(disco->titulo, titulo);
strcpy(disco->artista, artista);
strcpy(disco->formato, formato);
disco->fecha=fecha;
disco->precio=precio;
if (primero==NULL) {
primero = disco;
ultimo = disco;
}
else {
ultimo->siguiente = disco;
ultimo = disco;
}
}
}
fclose(discoteca);
return ;
}
void mostrar_menu() {
printf("\n\nMenú:\n=====\n\n");
printf("1.- Añadir elementos\n");
printf("2.- Borrar elementos\n");
printf("3.- Mostrar lista\n");
printf("4.- Salir\n\n");
printf("Escoge una opción: ");fflush(stdout);
}
void anadir_elemento() {
struct unDisco *disco;
int data;
float prezo;
char titulo[100],artista[100],formato[50];
//reservamos memoria para el nuevo elemento
disco = (struct unDisco *) malloc (sizeof(struct unDisco));
printf("\nTitulo: "); fflush(stdout);
fscanf(stdin," %s",titulo);
printf("Artista: "); fflush(stdout);
fscanf(stdin," %s",artista);
printf("Fecha: "); fflush(stdout);
fscanf(stdin," %i",&data);
printf("Formato: "); fflush(stdout);
fscanf(stdin," %s",formato);
printf("Precio: "); fflush(stdout);
fscanf(stdin," %f",&prezo);
strcpy(disco->titulo, titulo);
strcpy(disco->artista, artista);
strcpy(disco->formato, formato);
disco->fecha=data;
disco->precio=prezo;
// el campo siguiente va a ser NULL por ser el último elemento de la lista
disco->siguiente = NULL;
// ahora metemos el nuevo elemento en la lista. lo situamos al final de la lista
//comprobamos si la lista está vacía. si primero==NULL es que no hay ningún elemento en la lista. también vale ultimo==NULL
if (primero==NULL) {
printf( "Primer elemento\n");
primero = disco;
ultimo = disco;
}
else {
// el que hasta ahora era el último tiene que apuntar al nuevo
ultimo->siguiente = disco;
// hacemos que el nuevo sea ahora el último
ultimo = disco;
}
}
void mostrar_lista() {
struct unDisco *auxiliar; // lo usamos para recorrer la lista
int i;
i=0;
auxiliar = primero;
printf("\nMostrando la lista completa:\n");
while (auxiliar!=NULL) {
printf( "Titulo: %s, Artista: %s, Fecha: %i, Formato: %s, Precio: %.2f",
auxiliar->titulo,auxiliar->artista,auxiliar->fecha,auxiliar->formato,auxiliar->precio);
auxiliar = auxiliar->siguiente;
i++;
}
if (i==0) printf( "\nLa lista está vacía!!\n" );
}
void guardar(){
FILE *discoteca;
struct unDisco *disco;
discoteca=fopen("records.txt","w");
while(disco->siguiente!=NULL){
fprintf(discoteca,"%s %s %i %s %.2f\n",
disco->titulo, disco->artista, disco->fecha, disco->formato, disco->precio);
}
fclose(discoteca);
}
int main(){
char opcion;
cargar();
primero = (struct unDisco *) NULL;
ultimo = (struct unDisco *) NULL;
do {
mostrar_menu();
fscanf(stdin," %c",&opcion);
switch ( opcion ) {
case '1': anadir_elemento();
break;
case '2': printf("No disponible todavía!\n");
break;
case '3': mostrar_lista(primero);
break;
case '4':
guardar();
exit( 1 );
break;
default: printf( "Opción no válida\n" );
break;
}
} while (opcion!='4');
return 0;
}
it seems logical that guardar receives the unDisco in parameter, something like
void guardar(struct unDisco *disco){
FILE *discoteca = fopen("records.txt","w");
while(disco != NULL) { /* <<< test changed */
fprintf(discoteca,"%s %s %i %s %.2f\n",
disco->titulo, disco->artista,
disco->fecha, disco->formato,
disco->precio);
disco = disco->siguiente; /* <<< added */
}
fclose(discoteca);
}

Why does this C function not return an integer value?

When I try to execute my program, I get an error. I can't read the last value in "ch":
int choi(char *Tvide[48])//permet de choisir la place selon les choix de l utilisateur
{
char fum, classe, pos;
printf("\n S.V.P choisissez votre Classe (A:1 ere classe )/(B: 2 eme classe): ");
classe = getche();
printf("\n Est ce que vous etes fumeur (O:fumeur)/(N:non fumeur):");
fum = getche();
printf("\n S.V.P vous preferez s''assoir pres de la fenetre ou du couloir(C:couloir )/(F:fenetre):");
pos=getche();
int Tfum[24] = {3,4,7,8,11,12,15,16,19,20,23,24,27,28,31,32,35,36,39,40,43,44,47,48};
int Tnfum[24] = {1,2,5,6,9,10,13,14,17,18,21,22,25,26,29,30,33,34,37,38,41,42,45,46};
int Tfen[24] = {1,4,5,8,9,12,13,16,17,20,21,24,25,28,29,32,33,36,37,40,41,44,45,48};
int Tcol[24] = {2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31,34,35,38,39,42,43,46,47};
int k;
char Tdispo[48];
for(k=1; k<=48; k++) { Tdispo[k]='o'; } // on met içi le tableau des places vides
if (classe=='A')
{
for(k=9;k<=48;k++) { Tdispo[k]='n'; }
}
if (classe=='B')
{
for(k=1;k<=9;k++) { Tdispo[k]='n'; }
}
if (fum=='O')
{
for(k=1;k<=24;k++) { Tdispo[Tnfum[k]]='n'; }
}
if (fum=='N')
{
for(k=1;k<=24;k++) { Tdispo[Tfum[k]]='n'; }
}
if (pos=='C')
{
for(k=1;k<=24;k++) { Tdispo[Tfen[k]]='n'; }
}
if (pos=='F')
{
for(k=1; k<=24; k++) { Tdispo[Tcol[k]]='n'; }
}
int s;
printf("Les places disponibles sont:");
for(s=1; s<=48; s++)
{
if(Tdispo[s] == 'o') { printf("%d",s,"~"); }
}
int ch;
printf("\n S.V.P introduire votre choix :");
scanf("%d",ch);
Tvide[ch]=='n';
int ch1 = ch;
return ch1;
}
What could be causing this behavior?
You should have
scanf("%d",&ch);
not
scanf("%d",ch);
Because the result of scanf gets stored in the variable named ch.
Your main problem is that C uses 0-based arrays. A array of size 24 iss accessed 0 to 23) but you access them from 1 to 24, thus the last access is outside the array.

Resources