This question already has answers here:
How should character arrays be used as strings?
(4 answers)
Closed 3 months ago.
I have a problem with the a struct´s fields.The code compile but doesn´t work as is should, This is how i define my struct.(Srry for the bad english, its my first time in stackoverflow :)
struct registro {
char Pais[3];
char Nombre[20];
char Apellido[20];
char Clase[1];
char Nivel[2];
char Genero[1];
int Edad;
};
i can write on struct without problem. The words in bold are the ones that i typed
=======Agregue los datos del nuevo estudiante=======
Ingrese Pais : **ARG**
Ingrese Nombre del Estudiante : **Gonzalo**
Ingrese Apellido : **Suarez**
Ingrese Clase Social : **A**
Ingrese Nivel de Ingles : **C1**
Ingrese Edad : **20**
Ingrese Genero : **M**
______________________________
ALUMNO AGREGADO DE FORMA EXITOSA! :)
Desea Agregar otro estudiante: S/N
The problem is when i want to se file this happen:
=======Archivos de Estudiantes=======
ARCHIVO :
___________
Pais : ARGGonzalo
Nombre y Apellido : Gonzalo Suarez
Clase : AC1M
edad : 20
Nivel de ingles : C1M
Genero : M
________________________________
i discovered that for some reason the code saves the field Pais,Clase and Nivel wrong, i checked and its not a problem in the printf, i dont know why or how to fix it, I think that theres some library o im using wrong the scanf
heres the code:
#include"stdio.h"
#include"conio.h"
#include"stdlib.h"
void agregar();
void ver_archivo();
void buscar();
void eliminar();
struct registro {
char Pais[3];
char Nombre[20];
char Apellido[20];
char Clase[1];
char Nivel[2];
char Genero[1];
int Edad;
};
void agregar(){
char respuesta2;
FILE *fp;
int n,i;
struct registro reg;
do{
system("cls");
printf("\t\t\t\t=======Agregue los datos del nuevo estudiante=======\n\n\n");
fp=fopen("Datos.dat","w");
printf("\n\t\t\tIngrese Pais : ");
scanf("%s",®.Pais);
printf("\n\t\t\tIngrese Nombre del Estudiante : ");
scanf("%s",®.Nombre);
printf("\n\t\t\tIngrese Apellido : ");
scanf("%s",®.Apellido);
printf("\n\t\t\tIngrese Clase Social : ");
scanf("%s",®.Clase);
printf("\n\t\t\tIngrese Nivel de Ingles : ");
scanf("%s",®.Nivel);
printf("\n\t\t\tIngrese Edad : ");
scanf("%d",®.Edad);
printf("\n\t\t\tIngrese Genero : ");
scanf("%s",®.Genero);
printf("\n\t\t\t______________________________\n");
if(fp==NULL){
fprintf(stderr,"ERROR: NO SE PUDO ABRIR EL ARCHIVO");
}else{
printf("\t\t\tALUMNO AGREGADO DE FORMA EXITOSA! :)\n");
}
fwrite(®, sizeof(struct registro), 1, fp);
fclose(fp);
printf("\t\t\tDesea Agregar otro estudiante: S/N");
scanf("%s",&respuesta2);
}while(respuesta2=='S');
}
my profesor suggest me to change
fp=fopen("Datos.dat","w");
to
fp=fopen("Datos.dat","wb");
but didnt work
you are putting strings like ARG into a field that is char[3]. Strings in c are zero terminated so you need char[4]. 2 rules for char string in c
always allocate one extra character
make sure that there is a \0 character at the end of the string
Related
The exercise about creating a linked list for patient, then arrange it by their name. I'm trying to swap their name; it seems that what I did doesn't work.
I've tried to take the the previous pointer "prec" and compare the name of next pointer "ptr" then I tried to swap their name in function named "echangedeChaine"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct patient{
int cin;
char nom[8];
char prenom[8];
int annee;
struct patient *suivant;
};
struct patient *tete=NULL;
void creationdePatient(){
struct patient* ptr;
char rep;
ptr = malloc(sizeof(struct patient));
tete =ptr;
printf("Saisir Numero de Cin de Nouveau Patient: ");
scanf("%d",&tete->cin);
printf("Saisir Nom de Patient: ");
scanf("%8s",&tete->nom);
printf("Saisir prenom de Patient: ");
scanf("%8s",&tete->prenom);
tete->suivant = NULL;
printf("\nVoulez vous Saisir un autre Patient ?: (O,N): \n");
scanf(" %c",&rep);
while(toupper(rep)=='O'){
ptr = malloc(sizeof(struct patient));
printf("Saisir Numero de Cin de Nouveau Patient: ");
scanf("%d",&ptr->cin);
printf("Saisir Nom de Patient: ");
scanf("%8s",&ptr->nom);
printf("Saisir prenom de Patient: ");
scanf("%8s",&ptr->prenom);
ptr->suivant = tete;
tete=ptr;
printf("\nVoulez vous Saisir un autre Patient ?: (O,N): \n");
scanf(" %c",&rep);
}
}
void echangedeChaine(char x[8] , char y[8]){
char temp[8];
strcpy(temp,y);
strcpy(y,x);
strcpy(x,temp);
}
void printtList(){
struct patient *temp = tete;
while(temp!=NULL){
printf("Cin: %d | Nom:%s | Prenom: %s\n", temp->cin, temp->nom, temp->prenom);
temp=temp->suivant;
}
}
void trier(){
struct patient *ptr = tete;
struct patient*prec;
int echange=0;
do{
while(ptr!=NULL){
prec=ptr;
ptr=ptr->suivant;
if(strcmp(prec->nom,ptr->nom)<0){
echangedeChaine(prec->nom,ptr->nom);
echange=1;
}
}
}while(echange==1);
}
int main()
{
creationdePatient();
printtList();
trier();
printtList();
}
It seems it doesn't work after I tried to execute it.
The are several issues with your code, including (but not necessarily limited to):
Your code in trier() will dereference a NULL pointer at the last element - since its suivant is NULL, and you're doing:
ptr = ptr->suivant;
if(strcmp(prec->nom,ptr->nom) < 0) { ... }
I think you're trying to sort in the wrong order: When strcmp(prec->nom,ptr->nom) is negative, that means the first patient's name is lexicographically earlier than the following patient name - in which case they should not be exchanged.
PS - for those not fluent in French, here's a little glossary for OP's program...
tete = head
suivant = next
nom = last/family name
prenom = first/given name
echange = change (or replace)
chaine = list (or cain)
The Exercise is about filling Products names with their Stock capacity in file named fichierProduit and filling the movement (Import and Export) of this products in file named fichierMouvment. After filling these 2 files I create another file fichierdeResultat so I can write in it the new Stock Capacity. After doing some math the function related to this is ResultatdeMouvement, when displaying the Result it only displays the first product.
I tried to copy the name into the record "Resultat" (R) and then write it into the fichierdeResultat while displaying them in the function AfficheDeProduitApresMouvement it seems displaying only the first product name in file fichierProduit.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
struct Produit{
char NomP[10] ;
int StockP;
};
struct Mouvement{
char MouveP[10];
int MouveAp;
int MouveV;
};
struct Resultat{
char NomPr[10];
int StockR;
};
//INSERTING NEW PRODUCTS LIST
void SaisirProduits(FILE* ficheierProduit){
struct Produit P;
ficheierProduit = fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","wb");
char rep;
do {
fseek(ficheierProduit, 0, SEEK_END);
printf("Saisir Nom de Produit: ");
scanf("%9s",&P.NomP);
printf("Saisir Capacite de Stock de Produit: ");
scanf("%i",&P.StockP);
fwrite (&P, sizeof(struct Produit), 1,ficheierProduit);
if(fwrite!=0){
printf("\n\Produit Ajoute avec succees !\n\n");
}
printf("Voulez Vouz Saisir un autre Produit (O,N): ");
scanf(" %c",&rep);
}while(toupper(rep)!='N');
fclose(ficheierProduit);
}
//INSERTING NEW MOVEMENT LIST
void SaisirMouvement(FILE* fichierMouvment){
struct Mouvement M;
fichierMouvment = fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","wb");
char rep;
do {
fseek(fichierMouvment, 0, SEEK_END);
printf("Saisir Nom de Produit a Ajouter un mouvement: ");
scanf("%9s",&M.MouveP);
printf("Saisir Capacite d'approvisionnement: ");
scanf("%i",&M.MouveAp);
printf("Saisir Nombre Vendu de ce Produit: ");
scanf("%i",&M.MouveV);
fwrite (&M, sizeof(struct Mouvement), 1,fichierMouvment);
if(fwrite!=0){
printf("\n\Mouvement Ajoute avec succees !\n\n");
}
printf("Voulez Vouz Saisir un autre Mouvement (O,N): ");
scanf(" %c",&rep);
}while(toupper(rep)!='N');
fclose(fichierMouvment);
}
//Function to verify if the Products Exist or not
int VerifierProduitExistouNon(char NomdeProduit[10],FILE* ficheierProduit){
struct Produit P; ficheierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","r+");
int found=0;
while(!feof(ficheierProduit)){
fread(&P,sizeof(P),1,ficheierProduit);
if(strcmp(P.NomP,NomdeProduit)==0){
found=1;
return found;
}else if(feof(ficheierProduit) && found==0)
return found;
}
fclose(ficheierProduit);
}
//Add New Products to the File
void AjouterNouveauProduit(FILE* fichierProduit){
struct Produit P;
fichierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","ab+");
printf("Saisir Nom de Nouveau Produit: ");
scanf("%9s",&P.NomP);
if(VerifierProduitExistouNon(P.NomP,fichierProduit)!=0)
printf("\n\nProduit deja Exist Merci de Verifier !\n\n");
else{
printf("\nSaisir Capcite de Stock de Produit: ");
scanf("%i",&P.StockP);
fwrite (&P, sizeof(struct Produit), 1,fichierProduit);
printf("\nSaisir de nouveau Produit avec Success ! \n");
}
fclose(fichierProduit);
}
//INSERTING NEW MOUVEMENT
void AjouterNouveauMouvement(FILE* fichierMouvment,FILE* fichierProduit){
struct Mouvement M;
fichierMouvment = fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","ab+");
printf("Saisir Nom de Produit a Verifier S'il exist: ");
scanf("%9s",&M.MouveP);
if(VerifierProduitExistouNon(M.MouveP,fichierProduit)!=0){
printf("\n\nProduit Exist Ajout de Nouveau Mouvement.....\n\n");
printf("\nSaisir Capcite d'approvisionnement de Ce Produit: ");
scanf("%i",&M.MouveAp);
printf("\nSaisir Capcite de Vente de Ce Produit: ");
scanf("%i",&M.MouveV);
fwrite (&M, sizeof(struct Mouvement), 1,fichierMouvment);
if(fwrite!=0){
printf("\nSaisir de nouveau Produit avec Success ! \n");
}
}else{
printf("\n\nCe Produit N existe pas dans le Stock Merci de Verifier ! \n\n");
}
fclose(fichierMouvment);
}
//TRYING TO FILE THE RESULT FILE
void ResultatdeMouvement(FILE* ficheierProduit,FILE* fichierMouvment,FILE* fichierResultat){
struct Produit P;
struct Mouvement M;
struct Resultat R; ficheierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","r+");
fichierMouvment=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","r+");
fichierResultat=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FResultat.dat","wb");
while(!feof(ficheierProduit)){
fread(&P,sizeof(P),1,ficheierProduit);
while(!feof(fichierMouvment)){
fread(&M,sizeof(M),1,fichierMouvment);
if(strcmp(P.NomP,M.MouveP)==0){
strcpy(R.NomPr,P.NomP);
R.StockR=P.StockP+(M.MouveAp-M.MouveV);
}
}
fwrite(&R,sizeof(R),1,fichierResultat);
}
fclose(ficheierProduit);
fclose(fichierMouvment);
fclose(fichierResultat);
}
void AfficheDeMouvement(FILE* fichierdeMouvement){
struct Mouvement M;
fichierdeMouvement=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FMouvment.dat","r+");
while(fread(&M,sizeof(M),1,fichierdeMouvement)){
printf("\n\nNom de Produit: %s | approvisionnement= %i | Vente= %i\n\n ",M.MouveP,M.MouveAp,M.MouveV);
}
fclose(fichierdeMouvement);
}
void AfficheDeProduitavantMouvement(FILE* fichierProduit){
struct Produit P;
fichierProduit=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FProduit.dat","r+");
while(fread(&P,sizeof(P),1,fichierProduit)){
printf("\n\nNom de Produit: %s | Stock Valable = %i \n\n",P.NomP,P.StockP);
}
fclose(fichierProduit);
}
void AfficheDeProduitApresMouvement(FILE* fichierResultat){
struct Resultat R;
fichierResultat=fopen("C:/Users/Ayoub/Desktop/EX5/EX5/FResultat.dat","r+");
while(fread(&R,sizeof(R),1,fichierResultat)){
printf("\n\nNom de Produit: %s | Stock Valable Apres Mouvement: %i \n",R.NomPr,R.StockR);
}
fclose(fichierResultat);
}
//Main
int main()
{ FILE* Produit;//file of the products
FILE* MouvementdeProduit;//file of the mouvment
FILE* ResultatdeMouvedeProduit;//file of the result
AfficheDeProduitavantMouvement(Produit);
AfficheDeMouvement(MouvementdeProduit); ResultatdeMouvement(Produit,MouvementdeProduit,ResultatdeMouvedeProduit);
AfficheDeProduitApresMouvement(ResultatdeMouvedeProduit);
}
There are many problems with your code, some of which I addressed in the comments. I will/did not identify all problems. I will just point you to the problem you are asking about.
The problem is that you skip a lot of records in the input file, so before processing the next product you must rewind the input file:
while(fread(&P,sizeof(P),1,ficheierProduit))
{
// You now have a product.
// Now collect its stock.
R.StockR= 0;
*R.NomPr= '\0';
while(fread(&M,sizeof(M),1,fichierMouvment))
{
if(strcmp(P.NomP,M.MouveP)==0){
strcpy(R.NomPr,P.NomP);
R.StockR=P.StockP+(M.MouveAp-M.MouveV);
}
}
if (*R.NomPr!='\0') fwrite(&R,sizeof(R),1,fichierResultat);
// You have now possibly skipped lots of products.
// So you must rewind the file.
fseek(fichierMouvment,0, SEEK_SET);
}
My question refers to the while(!feof(arch)) that repeats the last registry two times. Thanks if you take some of your time to answer. I'm in first year learning basics.
The information is on an archive, so the first input shouldn't be 's' because it isn't the first time to input. Then the program list the infomation but the last registry repeats two times.
#include <stdio.h>
typedef struct{
int legajo;
char nombre[30];
int ingreso;
int pparcial;
int sparcial;
} reg_alumno;
reg_alumno funcionleer(void);
typedef FILE * archivo; //Se define el tipo de dato "archivo".
archivo arch; //Se declara una variable de archivo.
int main(void){
reg_alumno alumno,alu;
int ca,i,j=0;
char respuesta;
printf("Desea ingresar datos por primera vez?");
scanf("%c",&respuesta);
printf("Ingrese cantidad alumnos");
scanf("%d",&ca); //Pide cantidad alumnos
if(respuesta=='s'){
arch = fopen("alumnos.dat","w"); //Crear archivo para escribir, crea si no existe)
for(i=0;i<ca;i++){
alumno = funcionleer(); //Lee alumno
fseek(arch,sizeof(reg_alumno)*i,SEEK_SET); //Busca la última posición del archivo
fwrite(&alumno,sizeof(reg_alumno),1,arch); //Escribe en la última posición
}
}
else{
arch = fopen("alumnos.dat","r+");
while(!feof(arch)){
fseek(arch,sizeof(reg_alumno)*j,SEEK_SET); //Pasa de registro en registro(alumno en alumno).
fread(&alu,sizeof(reg_alumno),1,arch); //Trae a la memoria principal un alumno
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
}
fclose(arch); //Cierra el archivo
}
reg_alumno funcionleer(void){ //Función leer
reg_alumno alumno;
printf("Ingrese el numero de legajo:\n");
scanf("%d",&alumno.legajo);
printf("Ingrese el nombre:\n");
scanf("%s",alumno.nombre);
return(alumno);
}
Good to check result of IO operations #WhozCraig.
The code's problem is that its prints even if fread() fails.
// No check of return value.
fread(&alu,sizeof(reg_alumno),1,arch);
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
Code uses feof() incorrectly. Many SO posts on that.
Since OP implies code is required to use feof() by teacher: following are 2 good ways to use feof()
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
if (fread(&alu,sizeof(reg_alumno),1,arch) == 0) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
// If loop quit because of EOF
if (feof(arch)) printf("Success");
else if (!ferror(arch)) printf("IO Error");
Or
for (;;) {
if (fseek(arch,sizeof(reg_alumno)*j,SEEK_SET)) break;
fread(&alu,sizeof(reg_alumno),1,arch);
if (!feof(arch)) break;
if (!ferror(arch)) break;
printf("Legajo N %d: %s\n",alu.legajo,alu.nombre);
j++;
}
I got a problem at this line c->next=var;
and my function is :
{
struct film
{
int id;
char nom[50];
char typeFilm[50];
int duree;
int dateSortie;
struct film *next;
};
#include<stdio.h>
#include<string.h>
#include "structure_film.h"
#include<stdlib.h>
void ajouter_film(struct film **h,struct film **c)
{
struct film *var;
int s, genre;
do
{
var=(struct film*) malloc(sizeof(struct film));
printf("quel est le nom du film que vous voulez ajouter ? \n");
scanf("%s",var->nom);
printf("\nquel est le type de ce film \n 1-action \n 2-aventure \n 3-romantique \n 4-comedie \n");
scanf("%d",&genre);
switch(genre)
{
case 1 :
strcpy((var->typeFilm),"action");
break;
case 2 :
strcpy((var->typeFilm),"aventure");
break;
case 3 :
strcpy((var->typeFilm),"romantique");
break;
default :
strcpy((var->typeFilm),"comedie");
}
printf("\nquel est sa duree ? \n");
scanf("%d",&var->duree);
printf("\nveuillez entrez le numero de reference de ce film : \n");
scanf("%d",&var->id);
printf("\nquel est l'annee de sortie? \n");
scanf("%d",&var->dateSortie);
if (*h==NULL)
{
*h=var;
*c=var;
}
else
{
printf("i'm in else \n");
*c->next=var;
*c=var;
var->next=NULL;
}
printf("si vous voulez ajoutez un autre film veuillez tapez 1 si non tapez 0 \n");
scanf("%d",&s);
}
while (s!=0);
}
}
The problem is the priority of the operands here:
*c->next=var;
This is evaluated as: "take the field next of the struct pointed by c, and then, deference it.". As c is not a pointer to struct film, the next field doesn't exist.
And you want: "deference the pointer c, and take the field next of the pointer that results from it." because *c is a pointer to struct film, and therefore, field next exists for it.
So, it's: (*c)->next=var; to alter the precedence order in the evaluation.
This:
*c->next=var;
Probably needs to be this:
(*c)->next=var;
At least then it might compile--who knows if it's the behavior you want!
The reason is that c is a pointer to a pointer, so you need to dereference it twice to get the next field of the struct film.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am doing a project and when I try to use a file to help me keep recording the number of the register of a user.
After I had the part of creating a file, my program start crashing everytime I call a function that I changed (Ler_Pessoa()). It doesnt report any error or warning and I've not been able to understand why it's behaving like that.
I have two files, one is working correctly and I need the secound one to start in 0 everytime I delete the "Data.txt" file.
If you could take a look at my code, I would appreciate.
My header file:
#define ARQ "Dados.txt" /*ARQUIVO COM OS DADOS*/
#define ARQ_REG "Registo.txt" /*Arquivo que vai contabilizando o numero do registo */
FILE *fp;
FILE *reg;
typedef struct
{
char Nome[100];
int Sala;
int Hora_inicio;
int Minuto_inicio;
int Hora_fim;
int Minuto_fim;
long int numero_registo;
char Status; /* '*' Indica que o registo está apagado */
} PESSOA;
void Numero_Registo();
void Listar_Reservas();
void Apagar_Pessoa();
void Alterar_Pessoa();
void Inserir_Pessoa();
void Pesquisar_Nome(char *s);
void Iniciar();
void Ler_Pessoa(PESSOA *p);
void Mostrar_Pessoa(PESSOA p);
void Adicionar_Pessoa(PESSOA p);
void Mensagem(char *msg);
In Numero_Registo.c:
#include "header.h"
void Numero_Registo() /*
* Verifica se o Arquivo REG já existe. Se não existir, o numero de registo começa a 0.
* Se já existir, abre-o em Modo de Leitura e Escrita (r+b)
*/
{
int i = 0;
reg = fopen(ARQ_REG, "r+b"); /* Tenta Abrir*/
if (reg==NULL)
{
reg=fopen(ARQ_REG, "w+b");
fprintf("%d",i) ;/*Cria o Arquivo*/
}
fclose(reg);
}
In Ler_Pessoa.c:
#include "header.h"
void Ler_Pessoa(PESSOA *p) /*Esta função permite ler os dados inseridos por um utilizador de modo a fazer a reserva*/
{
int num_reg;
reg = fopen (ARQ_REG,"r");
fscanf("%d", &num_reg);
num_reg++;
fclose(reg);
reg = fopen(ARQ_REG,"w");
fprintf ("%d", num_reg);
fclose(reg);
printf("Introduza o seu Nome (Primeiro e Ultimo) : "); gets(p->Nome);
printf("Introduza o numero da sala que quer reservar: "); scanf("%d", &p->Sala);
printf("Introduza a partir de que horas quer reservar a sala (HH:MM): "); scanf("%2d:%2d",&p->Hora_inicio , &p->Minuto_inicio);
printf("Introduza ate que horas quer reservar a sala (HH:MM): "); scanf("%2d:%2d", &p->Hora_fim , &p->Minuto_fim);
p -> Status = ' ';
p -> numero_registo = num_reg;
fflush(stdin);
system("cls");
}
In your posted source code, the fscanf() and the fprintf() are called without the file pointer . Changing it to
fscanf( reg, "%d", &num_reg );
and
fprintf( reg, "%d", num_reg );
could be all.