Scan (read) from BIN file - arrays

I need to solve a problem. I need to create two functions which scan user's input information and put in into structure array and then put all array to BIN file (with function fwrite()) and other function - read from BIN file with function fread(). You can see my code below. Problem is that I can write to file, but when I read I get filler array element and other element which are empty. How to get only filled struct array element?
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
typedef struct
{
char Lesson[50];
char TeachersName[50];
char TeachersLastName[50];
int Credits;
int NumberOfStudents;
} School;
void ToFile (char *fileName);
void FromFile (char *FileName);
int main()
{
char *fileName[]={"student.bin"};
ToFile (*fileName);
FromFile (*fileName);
return 0;
}
void ToFile (char *fileName)
{
int n, chars;
FILE *fp;
fp = fopen(fileName, "wb");
School Info[20];
if(fp == NULL)
{
printf("Error opening file\n");
exit(1);
}
printf("Testing fwrite() function: \n\n");
printf("Enter the number of records you want to enter: ");
scanf("%d", &n);
for(int i = 0;i<n;i++)
{
printf("\nEnter details of employee %d \n", i + 1);
fflush(stdin);
printf("Lesson: ");
gets(Info[i].Lesson);
printf("Teachers name: ");
gets(Info[i].TeachersName);
printf("Teachers last name: ");
gets(Info[i].TeachersLastName);
printf("Credits: ");
scanf("%d", &Info[i].Credits);
printf("Number of studens: ");
scanf("%d", &Info[i].NumberOfStudents);
chars = fwrite(&Info[i], sizeof(Info), 1, fp);
printf("Number of items written to the file: %d\n", chars);
}
fclose(fp);
}
void FromFile (char *FileName)
{
School Info[20]= { { "", "","",0,0 } };;
FILE * fpp;
fpp = fopen(FileName, "rb");
fread(&Info, sizeof(Info), 1, fpp);
/*
for(int j=0; j<20; ++j) {
printf("\nLesson: %s", Info[j].Lesson);
printf("\nTeachers name: %s", Info[j].TeachersName);
printf("\nTeachers last name: %s", Info[j].TeachersLastName);
printf("\nCredits: %d", Info[j].Credits);
printf("\nNumber of students: %d", Info[j].NumberOfStudents);
printf("\n");
}*/
int j=0;
while (fread(&Info, sizeof(Info), 1, fpp))
{
printf("\nLesson: %s", Info[j].Lesson);
printf("\nTeachers name: %s", Info[j].TeachersName);
printf("\nTeachers last name: %s", Info[j].TeachersLastName);
printf("\nCredits: %d", Info[j].Credits);
printf("\nNumber of students: %d", Info[j].NumberOfStudents);
printf("\n");
j++;
}
fclose(fpp);
}

Related

Why is the while loop not executing to compare strings

First, the while loop is not comparing titles in the file and the num_books does not add on top of the file. Second, instead of reading the num_books already in the file, it reads twice every time executed. can someone help?
typedef struct book {
char *title;
char *author;
char *subject;
};
struct library {
struct book collection;
int num_books;
struct library *next;
};
add(FILE *file, FILE *fileout, struct library *thislib, struct book *thisbook) {
char choice = "1";
int size;
char line1[50];
file = fopen("temp1.txt", "a+");
fileout = fopen("temp2.txt", "a+");
printf("\t Add a book to your library!\n");
printf("\t\t Title: ");
scanf("%s", &thisbook->title);
printf("\t\t Author: ");
scanf("%s", &thisbook->author);
printf("\t\t Subject: ");
scanf("%s", &thisbook->subject);
fseek(file, 0, SEEK_SET);
thislib->num_books++;
fprintf(file, "%d", thislib->num_books);
size = ftell(file);
while (thislib->num_books > 1) {
for (int i = 1; i < size; i++) {
fseek(file, i, SEEK_CUR);
fscanf(file, "%s", line1);
printf("%s", line1);
if (strcmp(thisbook->title, line1) != 0) {
printf("Please re-enter title as similar ones are not allowed.\n");
printf("\t\t Title: ");
scanf("%s", &thisbook->title);
strcpy(line1, "");
}
}
}
fseek(file, 1, SEEK_SET);
fprintf(file, "%c %s %s %s\n", choice, &thisbook->title, &thisbook->author, &thisbook->subject);
fprintf(fileout, "The book %s, author %s, subject %s has been added to the library.\n", &thisbook->title, &thisbook->author, &thisbook->subject);
fclose(file);
fclose(fileout);
}

trouble reading data from binary file into struct array

I have a binary file with some data I inputted using an array of struct.
However, when I try to read back my values and display them, only the first one prints followed by garbage values.
Where did I go wrong?
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct eagleEmployees{
char userName[16];
char psswd[16];
};
int main()
{
int i;
struct eagleEmployees data[3];
FILE* fptr;
fptr = fopen("eEmployees.bin", "wb");
for(i=0; i<3; i++){
printf("\nEnter client name %d: ", i+1);
scanf(" %s", data[i].userName);
printf("\nEnter client password %d: ", i+1);
scanf(" %s", data[i].psswd);
}
i++;
fwrite(data, sizeof(struct eagleEmployees), 3, fptr);
fclose(fptr);
// I close the file above and reopen for reading below.
FILE *f;
f = fopen("eEmployees.bin", "rb");
for(i=0; i<3; i++){
fread(data,1,sizeof(struct eagleEmployees), f);
printf("\n %s \t %s",data[i].userName, data[i].psswd);
}
fclose(f);
return 0;
}

C language - printing some sentences to file

I want to read strings and write them as full lines into a file, but I can't read more words into a buffer as a complete string.
Current problematic code:
printf("\nEnter how many sentences do you want to read: ");
scanf("%d", &n);
tab = (char**)malloc(n * sizeof(char*));
for (int i = 0; i < n; i++) {
printf("\nEnter sentence: ");
scanf("%s", val);
tab[i] = _strdup(val);
}
for (i = 0; i < n; i++)
fprintf(f, "%s ", tab[i]);
free(tab);
Previously I tried this: (problem is this only assigns one string)
printf("\nEnter how many sentences do you want to read: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
printf("\nEnter sentence: ");
scanf("%s", val);
fprintf(f, "\%s ", val);
}
Almost there, now i have sentences but i got one empty line as first line of file.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string>
#define SIZE 30
void creare(char t[30]);
void main(void)
{
FILE* f2;
char name[30];
printf("\nEnter name of file to work with: ");
scanf("%s", name);
creare(name);
f2 = fopen(name, "r");
if (f2 == NULL)
{
printf("\nOpen error!!");
exit(0);
}
fclose(f2);
printf("\n");
_getch();
}
void creare(char t[30])
{
FILE* f;
int n,i;
char val[30];
f = fopen(t, "w");
if (f == NULL)
{
printf("\nOpen error!!");
exit(0);
}
printf("\nEnter how many sentences do you want to read: ");
scanf("%d", &n);
for (i = 0; i <= n; i++)
{
fgets(val, sizeof(val), stdin);
fprintf(f, "% s", val);
}
fclose(f);
}
I have used fgets(val, sizeof val, stdin) to read the string, because to read string with spaces.
The reason why that blank line comes in file is due to the fact that you are reading "\n" that is inputted after scanf("%d", &n);The keystroke "\n" will be read into val for the first time so it simply prints that "\n" to the file.
In order to read that "\n" use a character to read that "\n". Below is the complete program.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define SIZE 30
void creare(char t[30]);
int main(void)
{
FILE* f2;
char name[30];
printf("\nEnter name of file to work with: ");
scanf("%s", name);
creare(name);
f2 = fopen(name, "r");
if (f2 == NULL)
{
printf("\nOpen error!!");
exit(0);
}
fclose(f2);
printf("\n");
}
void creare(char t[30])
{
FILE* f;
int n,i;
char val[30],g;
f = fopen(t, "w");
if (f == NULL)
{
printf("\nOpen error!!");
exit(0);
}
printf("\nEnter how many sentences do you want to read: ");
scanf("%d", &n);
scanf("%c",&g);
for (i = 0; i <n; i++)
{
fgets(val, sizeof(val), stdin);
fprintf(f, "%s", val);
}
fclose(f);
}

C doesn't load info from file (fread, fwrite)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG 50 //just a random value
typedef struct Song
{
char *name;
char *nameSong;
char *timeSong;
int date;
} Song;
void saveToFile(Song *x, int *songCount) //Saves info to the binary file
{
FILE *f = fopen("array.txt", "w");
if (f == NULL)
{
printf("Error\n");
}
fwrite(songCount, sizeof(int), 1, f);
fwrite(x, sizeof(struct Song), (*songCount), f);
fclose(f);
}
void readSong(Song *x, int *songCount) //Reads info fromt he file and writes it
{
FILE *fr = fopen("array.txt", "r");
if (fr == NULL)
{
printf("Error\n");
}
printf("Songs:\n");
fread(songCount, sizeof(int), 1, fr);
fread(x, sizeof(struct Song), (*songCount), fr);
for(int i=0; i < (*songCount); i++)
{
printf("%d. %s %s %s %d\n", (i+1), x[i].name, x[i].nameSong, x[i].timeSong, x[i].date);
}
fclose(fr);
}
void insertSong(Song *x, int Count) //Inserts new song into the array.
{
printf("\nInsert name of the band:\n");
x[Count].name=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].name);
printf("Insert name of the song:\n");
x[Count].nameSong=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].nameSong);
printf("Insert length of the song:\n");
x[Count].timeSong=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].timeSong);
printf("Insert then song was created:\n");
scanf("%d", &(x[Count].date));
printf("\n");
}
main()
{
int songCount, menuOption;
Song *x=malloc(SLENG*sizeof(char)+SLENG*sizeof(char)+SLENG*sizeof(char)+sizeof(int));
printf("1. insert song\n 2. load from file\n ");
scanf("%d", &menuOption);
switch(menuOption)
{
case(1) :
printf("Insert how many songs do you want to input?\n");
scanf("%d", &songCount);
for(int i=0; i<songCount; i++)
{
insertSong(x, i);
}
saveToFile(x, &songCount);
break;
case(2) :
readSong(x, &songCount);
break;
}
}
I have an assingment to write a programm which would input some data into file and could read that data from that file, the problem is probably with fwrite or fread, couse it seems to crash everytime I try to load the and write the data from file. Any ideas why is it not working properly? And can I even do it like this as it is dynamic struct array. Thanks in advance.
In order to save the structure to a file, it must only contain scalar values, not pointers into memory objects. Modify your structure to use arrays instead of pointers:
typedef struct Song {
char name[SLENG];
char nameSong[SLENG];
char timeSong[SLENG];
int date;
} Song;
And modify the code accordingly, but note that:
saving and reading the structures to and from a file requires opening it in binary mode "wb" and "rb".
it is very misleading to name a binary file array.txt.
you do not need to pass the address of the count when writing to the file, but you need to pass the address of the array pointer when reading as you do not know yet how much memory to allocate.
Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG 50 // this value is used in the file format
typedef struct Song {
char name[SLENG];
char nameSong[SLENG];
char timeSong[SLENG];
int date;
} Song;
int saveToFile(Song *x, int songCount) { //Saves info to the binary file
FILE *f = fopen("array.bin", "wb");
if (f == NULL) {
printf("Error\n");
return -1;
}
fwrite(songCount, sizeof(int), 1, f);
int written = fwrite(x, sizeof(struct Song), songCount, f);
fclose(f);
return written;
}
int readSong(Song **x, int *songCount) { //Reads info from the file and writes it
int count = 0;
FILE *fr = fopen("array.bin", "rb");
if (fr == NULL) {
printf("Error\n");
return -1;
}
printf("Songs:\n");
fread(&count, sizeof(int), 1, fr);
*x = calloc(count, sizeof(Song));
if (*x == NULL) {
printf("Cannot allocate %d bytes of memory\n", count);
fclose(fr);
return -1;
}
int found = fread(*x, sizeof(struct Song), count, fr);
for (int i = 0; i < found; i++) {
printf("%d. %s %s %s %d\n", i + 1,
(*x)[i].name, (*x)[i].nameSong, (*x)[i].timeSong, (*x)[i].date);
}
fclose(fr);
return *songCount = found;
}
void insertSong(Song *x, int Count) { //Inserts new song into the array.
printf("\nInsert name of the band:\n");
scanf("%49s", x[Count].name);
printf("Insert name of the song:\n");
scanf("%49s", x[Count].nameSong);
printf("Insert length of the song:\n");
scanf("%49s", x[Count].timeSong);
printf("Insert then song was created:\n");
scanf("%d", &(x[Count].date));
printf("\n");
}
int main(void) {
int songCount, menuOption;
Song *x = NULL;
printf("1. insert song\n 2. load from file\n ");
scanf("%d", &menuOption);
switch (menuOption) {
case 1:
printf("Insert how many songs do you want to input?\n");
if (scanf("%d", &songCount) == 1) {
x = calloc(songCount, sizeof(Song));
for (int i = 0; i < songCount; i++) {
insertSong(x, i);
}
saveToFile(x, songCount);
}
break;
case 2:
readSong(&x, &songCount);
break;
}
free(x);
x = NULL;
return 0;
}

Console app menu not working in C

guys! So I have an assignment to create a structure that includes variables based on what information I need to store and to bring out a menu that calls different functions and does different things. The problems is that for some reason my createFile function is not working at all and I've been looking for errors for 2 days and I simply cannot spot where this is coming from.
Ignore the changeStud funcion as I'm still working on it. I simply want to create my file when I enter the name for it and then chose the nnumber of the function. (in my case > enter filename> enter 1> it just loops the menu function and it should create a file)
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student {
char ime[50];
char fn[10];
int ocfiz, ocmat, ocpro;
};
char filename[20];
FILE *fd;
Student ps;
void createFile() {
fd = fopen(filename, "wb");
fclose(fd);
printf("File created!\n");
}
void readStud(Student *s) {
printf("Enter data for new student");
getchar();
printf("Enter student name:");
gets_s(s->ime);
printf("\nEnter FN:");
scanf_s("%s", s->fn);
printf("\nEnter marks for Maths, Programming, Physics");
scanf_s("%d %d %d", &s->ocmat, &s->ocpro, &s->ocfiz);
getchar();
}
void addStud() {
fd = fopen(filename, "a+b");
char c;
do {
readStud(&ps);
fwrite(&ps, sizeof(ps), 1, fd);
printf("More Students? (y/n) : ");
c = getchar(); getchar();
} while (c == 'y');
fclose(fd);
}
void writeAllStud() {
fd = fopen(filename, "rb");
printf("students in file\n");
fread(&ps, sizeof(ps), 1, fd);
while (!feof(fd)) {
printf("%s fn: %s ocmat: %d ocpro: %d ocfiz: %d", ps.ime, ps.fn, ps.ocmat, ps.ocpro, ps.ocfiz);
fread(&ps, sizeof(ps), 1, fd);
}
fclose(fd);
}/*
void changeStud() {
char fn2[50];
printf("enter FN:");
gets_s(fn2);
fd = fopen(filename, "r+b");
fread(&ps, sizeof(ps), 1, fd);
while (!feof(fd)) {
if (strcmp(ps.fn, fn2)==0) {
fseek(fd, -(long) sizeof(ps), SEEK_CUR);
fwrite(&ps, sizeof(ps, 1, fd));
break;
}
}
}*/
void Avg() {
}
void exportData() {
FILE *txt;
txt = fopen("students.txt", "wt");
fd = fopen(filename, "rb");
fread(&ps, sizeof(ps), 1, fd);
while (!feof(fd)) {
fprintf(txt, "%s %s marks fiz%d mat%d prog%d\n", ps.fn, ps.ime, ps.ocfiz, ps.ocmat, ps.ocpro);
fread(&ps, sizeof(ps), 1, fd);
}
fclose(fd);
fclose(txt);
printf("students have been written to a text file.\n");
}
void main() {
printf("Enter file name:");
gets_s(filename);
int c;
do {
printf("\nMenu:\n");
printf("0 Exit\n");
printf("1 Create file\n");
printf("2 Add new student data\n");
printf("3 Change data from FN\n");
printf("4 AVG marks for maths, programming, physics\n");
printf("5 export all AVG marks to .txt file\n");
scanf("%d", &c);
switch (c) {
case 1: createFile; break;
case 2: addStud; break;
//case 3: changeStud; break;
case 4: Avg; break;
case 5: exportData; break;
}
} while (c != 0);
}
i think you should use your struct variable like this:
struct Student {
char ime[50];
char fn[10];
int ocfiz, ocmat, ocpro;
}ps;
or use
struct Student ps;
instead of just student ps,or you can decleare it in main function..And passing a struct in a functin is
void readStud( struct Student *s)() {
//your code...
}

Resources