When i try to execute this little program on the while my terminal crash and i don't know why! Somebody can help me? =) The problem is in the while. My colpiler (code:blocks) doesn't say anything O_o just one warning, but no errors.
#include<stdio.h>
#include<stdlib.h>
#define mxl 30
typedef struct inc{
int ora;
char desc[mxl];
} incluso;
typedef struct dati {
char data[mxl];
int n_a;
incluso *a;
} agenda;
int main(){
FILE *f;
agenda *p;
int i,orai,oraf;
char c, datar[mxl],nomefile[mxl],datapp[mxl];
printf("Inserisci il nome del file: ");
scanf("%s",&nomefile);
f=fopen(nomefile,"r");
if(f==NULL){
printf("Impossibile aprire il file!");
exit(1);
}
else{
printf("Inserisci data, ora inizio ed ora fine nel formato gg/mm hh hh: ");
scanf("%s %d %d",datar, orai,oraf);
while((c=getc(f))!=EOF){
if(fscanf(f,"%s",&datapp)==datar){
fscanf(f,"%s",&p->data);
fscanf(f,"%d",&p->n_a);
p->a=(incluso*)malloc(p->n_a*sizeof(incluso));
for(i=0;i<p->n_a;i++){
fscanf(f,"%d",&p->a[i].ora);
fscanf(f,"%s",&p->a[i].desc);
}
}
}
for(i<0;i<p->n_a;i++){
if(p->a[i].ora>orai && p->a[i].ora<oraf )
printf("%s %d %s", p->data, p->a[i].ora, p->a[i].desc);
}
free(p->a);
fclose(f);
}
}
In addition to what BLUEPIXY already mentioned:
scanf("%s",&nomefile);
should be
scanf("%s",nomefile);
because nomefile is an array and is reduced to a pointer already.
if(fscanf(f,"%s",&datapp)==datar){
Same here. It should be:
if(fscanf(f,"%s",datapp)==datar){
Also what do you want to compare here? The left side is an int and the right side a char*. If you want to compare the strings you have to do it in an extra line and with strcmp: (You also need to #include <string.h> for this)
fscanf(f,"%s",datapp);
if(strcmp(datapp, datar) == 0){
The same problem again:
fscanf(f,"%s",&p->a[i].desc);
should be
fscanf(f,"%s",p->a[i].desc);
Here you probably have a typo:
for(i<0;i<p->n_a;i++){
should be
for(i=0;i<p->n_a;i++){
With all warnings activated (-Wall -Wextra) gcc warned me for each of these.
Also (but there is no warning for this) you are repeatedly allocating for p->a. This should be done only once before the loop. Don't forget to free p either.
Problems as follows my noticed...
change
scanf("%s %d %d",datar, orai,oraf);
to
scanf("%s %d %d",datar, &orai, &oraf);
and
fscanf(f,"%s",&p->data);
to
p = malloc(sizeof(*p));
...
fscanf(f,"%s", p->data);
ADD
if(fscanf(f,"%s",&datapp)==datar){
Probably
if(fscanf(f, "%s", datapp)==1){
Related
I have a strange issue with my code :
I have a function generating a dynamic array of struct and only takes an int size as parameter.
It's work well until i try to add just a scanf("d";&size); to choose the size of my array, can't understand why i get a seg fault.
Note : There is no issue with compilation if i remove the line containing scanf
pokemon_t * createPkmDatabase( int taille){
printf("taille %d",taille);
pokemon_t *tableau=malloc(sizeof(pokemon_t)*taille);
...
...
}
int main(){
/*"taille" means size in french */
int taille=5;
printf("Saisir taille : ");
scanf("%d",&taille); /* <-- BREAKS EVERYTHING */
printf("valeur de taille : %d\n ",taille);
pokemon_t *database=createPkmDatabase(taille);
}
I don't get why changing the value of "taille" with a simple scanf change anything the value.
It doesn't even seems to enter in the function bc it doesn't even print the value of the size
There are no errors in the code shown.
Some remarks:
Use the correct type for sizes (size_t)
Always check the result of scanf and malloc
typedef struct {
int x,y,z;
}pokemon_t;
pokemon_t * createPkmDatabase(size_t taille){
printf("taille %d",taille);
pokemon_t *tableau=malloc(sizeof(*tableau)*taille);
return tableau;
}
int main(){
/*"taille" means size in french */
size_t taille;
printf("Saisir taille : ");
if(scanf("%zu",&taille) == 1)
{
printf("valeur de taille : %zu\n ",taille);
pokemon_t *database=createPkmDatabase(taille);
if(database)
{
printf("\nAllocation OK\n");
}
else
{
printf("\nAllocation FAILED\n");
}
free(database);
}
}
https://godbolt.org/z/ExjYe5G94
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct etudiant{
char nom[10];
float moy;
};
void AjoutEtudiant(struct etudiant E,FILE *ficheierEtudiant) {
ficheierEtudiant = fopen("C:/Users/Ayoub/Desktop/TDTP/Ex1/Etudiant.dat","w");
char rep;
do{
printf("Saisir nom etudiant a Ajouter: ");
scanf("%s",&E.nom);
printf("Saisir son Moyen: ");
scanf("%f",&E.moy);
fwrite (&E, sizeof(struct etudiant), 1,ficheierEtudiant);
if(fwrite!=0){
printf("\n\nEtudaint Ajouter avec succees !\n\n");
}
printf("\nvoulez vouz Ajouter un autre etudiant? (O,N): ");
scanf("%s",&rep);
} while(toupper(rep)!='N');
fclose(ficheierEtudiant);
}
void EcrireListeEtudiant(struct etudiant E, FILE* fichierEtudiant) {
fichierEtudiant=fopen("C:/Users/Ayoub/Desktop/TDTP/Ex1/Etudiant.dat","rb");
while(fread(&E,sizeof(struct etudiant),1,fichierEtudiant))
printf("Nom Etudiant: %s",E.nom,"| Moyen= %f \n",E.moy);
fclose(fichierEtudiant);
}
int main()
{
FILE *fichierEtudiant;
struct etudiant E;
AjoutEtudiant(E,fichierEtudiant);
EcrireListeEtudiant(E,fichierEtudiant);
}
I add names and their marks (float) in the file but when I try to display them it only shows the name and ignore the float parts in the file! I have tried many ways but ended up messing it up. Can someone help me to understand the issue?
In order to get the name and the moyen, change
printf("Nom Etudiant: %s",E.nom,"| Moyen= %f \n",E.moy);
to
printf("Nom Etudiant: %s| Moyen= %f \n", E.nom, E.moy);
This is necessary, because printf always takes a single format string and then all the arguments. If the first string only describes a single argument, the others will be ignored.
In your code, the second argument is the second half of the format string and the third argument is the moyen you are missing in the output. Both are ignored.
With the single, longer format string as proposed, two arguments are described, so both are found and used and both end up in the output.
I'm starting to learn in C and now I'm in the chapters of structs so I'm making a simple program with switch who ask for input from the user if the user press "1" the program ask for data of a new client, and after that you can print it from another function called in a switch case "2", the problem is the printed data is totally wrong I suspect the returned data is wrong or so.
P.D: Exist any way to print only the data introduced before instead 20 times the same data?
Here's the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct datos{
char nombre[20];
char apellido[20];
char direccion[20];
int edad[3];
long telefono[10];
}agenda;
agenda mostrar_datos();
agenda insercion_datos();
int main(void)
{
char con[3];
int menu;
puts("\n=== Bienvenido a la agenda en C ===\n");
while (!strstr(con,"si"))
{
puts("\n=== Que quieres hacer? ===\n");
fflush(stdin);
puts("\nIntroducir datos [1]\n");
puts("\nVer los datos[2]\n");
puts("\nSalir[3]\n");
scanf(" %d", &menu);
switch(menu)
{
case 1:
insercion_datos();
break;
case 2:
mostrar_datos();
break;
}
}
}
agenda insercion_datos()
{
agenda nuevo_dato;
puts("Bienvenido, vamos a introducir datos.");
puts("Dime su nombre.");
fflush(stdin);
gets(nuevo_dato.nombre);
puts("Dime su apellido.");
fflush(stdin);
gets(nuevo_dato.apellido);
puts("Dime su direccion.");
fflush(stdin);
gets(nuevo_dato.direccion);
puts("Dime su edad.");
fflush(stdin);
scanf(" %d", &nuevo_dato.edad);
puts("Dime su telefono.");
fflush(stdin);
scanf(" %d", &nuevo_dato.telefono);
}
agenda mostrar_datos()
{
int i = 0;
agenda mostrar_dato;
for (i=0;i<10;i++)
{
printf("Nombre: %s\n Apellido: %s\n Direccion: %s\n Edad: %d\n Telefono: %d\n", mostrar_dato.nombre,mostrar_dato.apellido,
mostrar_dato.direccion,mostrar_dato.edad, mostrar_dato.telefono);
}
}
I don't think this will work.
Couple of points to note here:
There is a white space in the scanf statement where you try to read the menu variable in the main()
In your function: insercion_datos() does not do anything besides creating a local variable and filling it with some data.
In your function: mostrar_datos(), the local variable is not initialized, therefore you receive no output.
Try to make a global array of `agenda' and then fill the array of structure everytime you read an input through insercion_datos(). Keep track of the number of inserts you have performed
the when you are printing using the mostrar_datos(), you can use that count and print.
I hope this resolves your doubt as to why there are no returns.
#include <stdio.h>
#include <stdlib.h>
struct not{
int id,hw,mdt,fnl;
char name[20];
char lname[20];
}rec;
int main(){
FILE *fp1,*fp2;
char a1[3]="A",a2[3]="B",a3[3]="C",a4[3]="D",a5[3]="F";
float numgrade;
char letgrade[3];
I got inf.txt file with 10 student's ID,NAME,LAST NAME,HOMEWORK GRADE,MIDTERM AND FINAL GRADE.
fp1=fopen("inf.txt","r");
fp2=fopen("outf.txt","w");
while( !feof(fp1)){
fscanf(fp1,"%d %s %s %d %d %d\n",&rec.id,rec.name,rec.lname,&rec.hw,&rec.mdt,&rec.fnl);
numgrade = (0.15)*rec.hw + (0.35)*rec.mdt + (0.5)*rec.fnl;
I got incompatible types in assignment error at if-else if part
if(numgrade>=0 && numgrade <=40) letgrade=strcat(a5,a5);
else if(numgrade>=41 && numgrade<=45) letgrade=strcat(a4,a4);
else if(numgrade>=46 && numgrade<=52) letgrade=strcat(a4,a3);
else if(numgrade>=53 && numgrade<=60) letgrade=strcat(a3,a3);
else if(numgrade>=61 && numgrade<=69) letgrade=strcat(a3,a2);
else if(numgrade>=70 && numgrade<=79) letgrade=strcat(a2,a2);
else if(numgrade>=80 && numgrade<=89) letgrade=strcat(a2,a1);
else if(numgrade>=90) letgrade=strcat(a1,a1);
fprintf(fp2,"%d %-12s %-12s %3d %3s",rec.id,rec.name,rec.lname,numgrade,letgrade);
}
fclose(fp1);
fclose(fp2);
system("pause");
return 0;
}
I searched incompatible types in assignment error in SOF but couldnt find something useful for my code.
You declared
char letgrade[3];
as an array. In C, arrays cannot be assigned with = operator. Pointers can be assigned, but you would need to manage memory pointed to by the pointers.
If you would like to concatenate two strings into letgrade, use the following code:
strcpy(letgrade, a5); // Copy the first part
strcat(letgrade, a5); // Append the second part
Note that in order for the above code to work properly, the length of a5 must not exceed 1. Otherwise, strcat would write past the end of letgrade.
I've got a question regarding programming and files.
while(current!=NULL)
{
if(current->Id_Doctor!='\0')
{
current=current->next;
id_doc=(current->Id_Doctor);
}
if(current->Id_Doctor=='\0')
{
id_doc=id_doc+1;
printf("%d", id_doc);
break;
}
}
fwrite(&id_doc, sizeof(char), 1, Archivo);
I dont know why but it aint writing the value of id_doc on the binary file called 'Archivo'...what could be the problem?
I added a printf of id_doc and the value was printed..I really dont know
Ok, heres the full code(more-less):
struct Medico
{
int Id_Doctor;
int Estado;
char Nombre[60];
char Clave_Acceso[20];
char Especialidad[40];
struct Medico *next;
};
void Dar_Alta_Med (int estado);
void MenuPrincipal(char enta);
int main(void)
{
char enta;
MenuPrincipal(enta);
}
void Dar_Alta_Med(int estado)
{
struct Medico * head = NULL;
struct Medico * prev, *current;
char nombre_doc[60], especialida[40], password[20];
int id_doc=0, estado_doc=1;
FILE *Archivo;
const char *md1="\n<md>\n";
const char *id_doc1="<id_doctor> ";
Archivo=fopen("md.dat", "ab+");
fwrite(md1, 1, strlen(md1), Archivo);
fwrite(id_doc1, 1, strlen(id_doc1), Archivo);
current = (struct Medico *) malloc (sizeof(struct Medico));
current->Id_Doctor=id_doc;
while(current!=NULL)
{
if(current->Id_Doctor!='\0')
{
current=current->next;
id_doc=(current->Id_Doctor);
}
else
{
id_doc=id_doc+1;
printf("%d", id_doc);
break;
}
}
fwrite(&id_doc, sizeof(id_doc), 1, Archivo);
printf("Ingresa el nombre del Doctor a dar de alta: ");
fclose(Archivo);
}
Im dying here, please help :/
Try adding fflush(Archivo); to force a write of all buffered data.
Also, this statement: if(current->Id_Doctor=='\0') really ought to be an else since there is no other thing it can be but '\0'
Three things:
Make sure your fopen is successful.
Archivo=fopen("md.dat", "ab+");
if (Archivo == NULL)
{
perror("Failed to open file Archivo");
...
}
Make sure you are checking the success of your fwrite's.
if (fwrite(&id_doc, sizeof(id_doc), 1, Archivo) < 1)
{
perror("Failed to write to file Archivo");
...
}
Make sure you have a fclose to close the file properly.
if (fclose(Archivo) != 0)
{
perror("Failed to close file Archivo");
...
}
Now that you've post a full sample of your code I guess I should ask if error checking is just left out for brevity? If not, you should think about adding it.
If you're expecting the value of id_doc to be in display format in the output file you'll have to convert the int to a string (using snprintf or similar) and write the string to the output file instead.
fwrite(&id_doc, sizeof(char), 1, Archivo);
If you defined id_doc as anything other than a char it will write \0 to the file.
Much cleaner would be:
fwrite(&id_doc, sizeof(id_doc), 1, Archivo);
If your first current is an Id_Doctor you have an endless loop.
If there is no current after your last current that is not an Id_Doctor, you get an illegal pointer derefenciation.
For your Problem:
try the flush() family.
You're passing a pointer to a FOUR-BYTE INT, but only writing ONE BYTE (the wrong byte)!
Solution: declare id_doc as "char", not "int".
You have previously written the strings "\n<md>\n" and"<id_doctor> " to the file Archivo, which seems to indicate that it is not a binary file at all, but rather an XML-style file.
In this case, what you almost certainly want is:
fprintf(Archivo, "%d", id_doc);