Task using .txt file and phonebook program in C - c

Below is my code for a phonebook program in C. I'm having trouble modifying it. I need to modify it so that after adding entries to the phonebook , the contents will be written to a .txt file. After deleting an entry I need the contents to be written to the same .txt file and have the entire contents printed. Am I supposed to use the fopen () function? I'm a beginner...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Phonebook_Contacts
{
char FirstName[20];
char LastName[20];
char PhoneNumber[20];
} phone;
void AddEntry(phone * );
void DeleteEntry(phone * );
void PrintEntry(phone * );
void SearchForNumber(phone * );
void RandomName(phone * );
void DeleteAll(phone * );
void FreeContacts (phone * );
int counter = 0;
char FileName[256];
FILE *pRead;
FILE *pWrite;
int main (void)
{
phone *phonebook;
phonebook = (phone*) malloc(sizeof(phone)*100);
int iSelection = 0;
if (phonebook == NULL)
{
printf("Out of Memory. The program will now exit");
return 1;
}
else {}
do
{
printf("\n\t\t\tPhonebook Menu");
printf("\n\n\t(1)\tAdd Friend");
printf("\n\t(2)\tDelete Friend");
printf("\n\t(3)\tDisplay Phonebook Entries");
printf("\n\t(4)\tSearch for Phone Number");
printf("\n\t(5)\tFind a Random Friend");
printf("\n\t(6)\tDelete All Entries");
printf("\n\t(7)\tExit Phonebook");
printf("\n\nWhat would you like to do? ");
scanf("%d", &iSelection);
if (iSelection == 1)
{
AddEntry(phonebook);
}
if (iSelection == 2)
{
DeleteEntry(phonebook);
}
if (iSelection == 3)
{
PrintEntry(phonebook);
}
if (iSelection == 4)
{
SearchForNumber(phonebook);
}
if (iSelection == 5)
{
RandomName(phonebook);
}
if (iSelection == 6)
{
DeleteAll(phonebook);
}
if (iSelection == 7)
{
printf("\nYou have chosen to exit the Phonebook.\n");
system("pause");
FreeContacts(phonebook);
return 0;
}
} while (iSelection <= 9);
}
void AddEntry (phone * phonebook)
{
pWrite = fopen("phonebook_contacts.dat", "a");
if ( pWrite == NULL )
{
perror("The following error occurred ");
exit(EXIT_FAILURE);
}
else
{
counter++;
realloc(phonebook, sizeof(phone));
printf("\nFirst Name: ");
scanf("%s", phonebook[counter-1].FirstName);
printf("Last Name: ");
scanf("%s", phonebook[counter-1].LastName);
printf("Phone Number (XXX-XXX-XXXX): ");
scanf("%s", phonebook[counter-1].PhoneNumber);
printf("\n\tFriend successfully added to Phonebook\n");
fprintf(pWrite, "%s\t%s\t%s\n", phonebook[counter-1].FirstName, phonebook[counter-1].LastName, phonebook[counter-1].PhoneNumber);
fclose(pWrite);
}
}
void DeleteEntry (phone * phonebook)
{
int x = 0;
int i = 0;
char deleteFirstName[20]; //
char deleteLastName[20];
printf("\nFirst name: ");
scanf("%s", deleteFirstName);
printf("Last name: ");
scanf("%s", deleteLastName);
for (x = 0; x < counter; x++)
{
if (strcmp(deleteFirstName, phonebook[x].FirstName) == 0)
{
if (strcmp(deleteLastName, phonebook[x].LastName) == 0)
{
for ( i = x; i < counter - 1; i++ )
{
strcpy(phonebook[i].FirstName, phonebook[i+1].FirstName);
strcpy(phonebook[i].LastName, phonebook[i+1].LastName);
strcpy(phonebook[i].PhoneNumber, phonebook[i+1].PhoneNumber);
}
printf("Record deleted from the phonebook.\n\n");
--counter;
return;
}
}
}
printf("That contact was not found, please try again.");
}
void PrintEntry (phone * phonebook)
{
int x = 0;
printf("\nPhonebook Entries:\n\n ");
pRead = fopen("phonebook_contacts.dat", "r");
if ( pRead == NULL)
{
perror("The following error occurred: ");
exit(EXIT_FAILURE);
}
else
{
for( x = 0; x < counter; x++)
{
printf("\n(%d)\n", x+1);
printf("Name: %s %s\n", phonebook[x].FirstName, phonebook[x].LastName);
printf("Number: %s\n", phonebook[x].PhoneNumber);
}
}
fclose(pRead);
}
void SortByFirstName (phone * phonebook)
{
int i = 0;
int x = 0;
int swap;
int TempCounter = counter;
phone Temp;
do
{
swap = 0;
for(i = 1; i < TempCounter; i++)
{
if(strcmp(phonebook[i-1].FirstName, phonebook[i].FirstName) > 0)
{
Temp = phonebook[i];
phonebook[i] = phonebook[i-1];
phonebook[i-1] = Temp;
strcpy(Temp.FirstName, phonebook[i].FirstName);
strcpy(Temp.LastName, phonebook[i].LastName);
strcpy(Temp.PhoneNumber, phonebook[i].PhoneNumber);
swap = 1;
}
}
TempCounter--;
} while (swap);
printf("\nYour friends in Alphabetical Order by First Name:\n\n");
for( x = 0; x < counter; x++ )
{
printf("\n(%d)\n", x+1);
printf("Name: %s %s\n", phonebook[x].FirstName, phonebook[x].LastName);
printf("Number: %s\n", phonebook[x].PhoneNumber);
}
}
void SortByLastName (phone * phonebook)
{
int i = 0;
int x = 0;
int swap;
int TempCounter = counter;
phone Temp;
do
{
swap = 0;
for(i = 1; i < TempCounter; i++)
{
if(strcmp(phonebook[i-1].LastName, phonebook[i].LastName) > 0)
{
Temp = phonebook[i];
phonebook[i] = phonebook[i-1];
phonebook[i-1] = Temp;
strcpy(Temp.FirstName, phonebook[i].FirstName);
strcpy(Temp.LastName, phonebook[i].LastName);
strcpy(Temp.PhoneNumber, phonebook[i].PhoneNumber);
swap = 1;
}
}
TempCounter--;
} while (swap);
printf("\nYour friends in Alphabetical Order by First Name:\n\n");
for( x = 0; x < counter; x++ )
{
printf("\n(%d)\n", x+1);
printf("Name: %s %s\n", phonebook[x].FirstName, phonebook[x].LastName);
printf("Number: %s\n", phonebook[x].PhoneNumber);
}
}
void SearchForNumber (phone * phonebook)
{
int x = 0;
char TempFirstName[20];
char TempLastName[20];
printf("\nPlease type the name of the friend you wish to find a number for.");
printf("\n\nFirst Name: ");
scanf("%s", TempFirstName);
printf("Last Name: ");
scanf("%s", TempLastName);
for (x = 0; x < counter; x++)
{
if (strcmp(TempFirstName, phonebook[x].FirstName) == 0)
{
if (strcmp(TempLastName, phonebook[x].LastName) == 0)
{
printf("\n%s %s's phone number is %s\n", phonebook[x].FirstName, phonebook[x].LastName, phonebook[x].PhoneNumber);
}
}
}
}
void RandomName (phone * phonebook)
{
int iRandom = 0;
srand(time(NULL));
iRandom = rand() % counter;
int x = iRandom;
printf("\nYour random friend is: %s %s\n", phonebook[x].FirstName, phonebook[x].LastName);
printf("Their phone number is: %s\n", phonebook[x].PhoneNumber);
}
void DeleteAll (phone * phonebook)
{
int x = 0;
char nullStr[20] = {'\0'};
for ( x = 0; x < counter; x++ )
{
strcpy(phonebook[x].FirstName, nullStr);
strcpy(phonebook[x].LastName, nullStr);
strcpy(phonebook[x].PhoneNumber, nullStr);
--counter;
}
printf("All Contacts have been deleted.\n");
}
void FreeContacts (phone * phonebook)
{
--counter;
for ( ; counter > 0; --counter)
{
free(phonebook[counter].FirstName);
free(phonebook[counter].LastName);
free(phonebook[counter].PhoneNumber);
free(phonebook);
counter = 0;
return;
}
}

Are you sure you want to be doing "realloc(phonebook, sizeof(phone));" in your AddEntry() function? That's almost certainly not doing what you think it is.

Pretty much all the code you need is already here in this program. I would recommend you start by looking up tutorials or reading the file I/O chapter of books. An additional resource for you is the man pages for the C functions. If you're on a *NIX system you can type man fopen or you can type that into Google to get the same results on a windows system.
Here's the man page for fopen(). As you can see there are two parameters, the name of the file you want to open and the mode.
Clearly there are options to open a file for writing there as well as appending a file that already exists.
You mentioned a requirement to write to a .txt file, in your code you're opening a .dat file phonebook_contacts.dat is this the file you were talking about?
One of the easiest options is to read the entire file into memory then change it there and write it back to the file (over write the existing file), but it's not efficent as you'll have to loop over each existing element and copy them into you phonebook variable. You might want to check with your instructor to see if this is an acceptable solution. Something like:
while( more to read){
read fname line
strcpy(phonebook[i].first_name, fname)
read lname line
strcpy(phonebook[i].last_name, fname)
read num line
strcpy(phonebook[i].number, num)
increment i
}

Related

C program dynamic memory allocation error, string value issue

I have tried multiple methods for a long time but it didn't work, the output automatically updates all previously entered values for the name.
The find method is not required to be checked, but the first display itself provides invalid output:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int phone;
char *name;
} phonecontact;
phonecontact *create(phonecontact *p, int phone, char name[], int i) {
(p+i)->name = (char *)calloc(10, sizeof(char));
(p+i)->name = name;
(p+i)->phone = phone;
printf("\n%s\n", (p+i)->name);
return p;
}
void display(phonecontact *p, int i) {
printf("Name : %s , Phone number : %d\n", p[i].name, p[i].phone);
}
int find(phonecontact *p, char name[], int *num) {
int phone, i = 0;
for (i = 0; i < *num; i++) {
if (strcmp(p[i].name, name) == 1)
display(p, i);
return 1;
}
p = (phonecontact *)realloc(p, ++(*num) * sizeof(phonecontact));
printf("Enter phone number for entered person : ");
scanf("%d", &phone);
p = create(p, phone, name, i + 1);
return 0;
}
int main() {
int num, phone;
char name[30];
printf("Enter number of contacts : ");
scanf("%d", &num);
phonecontact *p;
p = (phonecontact *)calloc(num, sizeof(phonecontact));
for (int i = 0; i < num; i++) {
printf("Enter name : ");
scanf("%s", name);
printf("Enter phone number : ");
scanf("%d", &phone);
p = create(p, phone, name, i);
}
printf("\n%s\n", (p)->name);
printf("\n%s\n", (p + 1)->name);
printf("\n%s\n", (p + 2)->name);
for (int i = 0; i < num; i++) {
display(p, i);
}
printf("Enter name of contact : ");
scanf("%s", &name);
find(p,name, &num);
}
There are many problems in the code:
For each contact to have its own name string, you must allocate a copy of the create() string argument:
phonecontact *create(phonecontact *p, int phone, const char *name, int i) {
p[i].name = strdup(name);
p[i].phone = phone;
printf("\n%s\n", p[i].name);
return p;
}
the function strcmp() returns 0 when the strings compare equal, a negative value if the first argument compares less than the second in lexicographical order and a value greater than zero otherwise.
You should use if (strcmp(p[i].name, name) == 0) and return 1 only if the strings compare equal.
It is confusing for a function named find() to append a new entry in the array.
The array reallocated by find() is not passed back to the caller, and the previous pointer may have become invalid, causing undefined behavior.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int phone;
char *name;
} phonecontact;
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
void init_contact(phonecontact *p, int phone, const char *name) {
p->name = strdup(name);
p->phone = phone;
}
void display_contact(const phonecontact *p) {
printf("Name: %s, Phone number: %d\n", p->name, p->phone);
}
int add_contact(phonecontact **pp, int *pnum, const char *name) {
int phone;
int num = *pnum;
phonecontact *p = *pp;
for (int i = 0; i < num; i++) {
if (strcmp(p[i].name, name) == 1) {
display_contact(&p[i]);
return 1;
}
}
/* reallocate the contact array */
p = (phonecontact *)realloc(p, (num + 1) * sizeof(*p));
if (p == NULL) {
printf("cannot reallocate contact array\n");
return -1;
}
printf("Enter phone number for entered person: ");
while (scanf("%d", &phone) != 1) {
printf("Invalid input. Try again: ");
if (flush_input() == EOF)
return -1;
}
init_contact(&p[num], phone, name);
*pnum = num + 1;
*pp = p;
return 0;
}
int main() {
int num, phone;
char name[30];
printf("Enter number of contacts : ");
if (scanf("%d", &num) != 1 || num < 0) {
fprintf(stderr, "invalid input\n");
return 1;
}
phonecontact *p = calloc(num, sizeof(*p));
if (p == NULL) {
fprintf(stderr, "memory allocation error\n");
return 1;
}
for (int i = 0; i < num; i++) {
printf("Enter name: ");
if (scanf(" %29[^\n]", name) != 1) {
fprintf(stderr, "invalid input\n");
return 1;
}
printf("Enter phone number: ");
if (scanf("%d", &phone) != 1)
fprintf(stderr, "invalid input\n");
return 1;
}
init_contact(&p[i], phone, name);
}
for (int i = 0; i < num; i++) {
display_contact(&p[i]);
}
printf("Enter name of contact: ");
if (scanf(" %29[^\n]", &name) == 1)
add_contact(&p, *num, name);
return 0;
}

swap strings function in c with pointers

When I try to swap between strings in the function Update_student it doesn't make it. Why?
#include <stdio.h>
#include <string.h>
#define SIZE 1
struct student {
int id_number;
char name[50];
char sex[6];
int quiz_score[2];
int total_score;
};
void Add_Student_Records(struct student *pupil) {
printf("ID:");
scanf("%d", &pupil->id_number);
printf("Name: ");
scanf("%s", &pupil->name);
printf("Sex :");
scanf("%s", &pupil->sex);
for (int i = 0; i < 2; i++) {
printf("Quit score %d:", i + 1);
scanf("%d", &pupil->quiz_score[i]);
}
pupil->total_score = pupil->quiz_score[0] + pupil->quiz_score[1];
return;
}
void Add_Students(struct student *students) {
for (int i = 0; i < SIZE; i++) {
printf("Student %d:\n", i + 1);
Add_Student_Records(students);
}
return;
}
void Print_Students(struct student *students) {
for (int i = 0; i < SIZE; i++) {
printf("Student %d details: \n", i + 1);
printf("ID:%d\n", students->id_number);
printf("Name:%s\n", students->name);
printf("Sex:%s\n", students->sex);
for (int i = 0; i < 2; i++) {
printf("Quit score %d:\n", students->quiz_score[i]);
}
printf("Total score: %d\n", students->total_score);
students++;
}
return;
}
void Replace_Strings(char **old_string, char **new_string) {
*old_string = *new_string;
return;
}
void Update_Student(struct student *students) {
int i = 0;
char name[50], new_name[50], cur_name[50];
printf("You can update name, and scores.\n");
printf(" current Name: ");
scanf("%s", name);
printf("new name: ");
scanf("%s", &new_name);
while (i < SIZE) {
strcpy(cur_name, students->name);
if (strcmp(cur_name, name) == 0) {
char *ptr_old_stud_name = students->name;
char *ptr_new_stud_name = new_name;
Replace_Strings(&ptr_old_stud_name, &ptr_new_stud_name);
}
i++;
students++;
}
return;
}
int main() {
struct student students[SIZE];
char ch;
/*1.Add student, 2. Print student*/
printf("1.Add student\n2.Print students\n3.Update student\n");
scanf("%c", &ch);
while (ch != 'E') {
if (ch == '1') {
Add_Students(&students[0]);
}
else if (ch == '2') {
Print_Students(&students[0]);
}
else if (ch =='3') {
Update_Student(&students[0]);
}
printf("Another operation:\t");
scanf("%c", &ch);
}
}
Replace_Strings(&ptr_old_stud_name,&ptr_new_stud_name); passes the addresses of ptr_old_stud_name and ptr_new_stud_name to ReplaceStrings.
ptr_old_stud_name and ptr_new_stud_name are local variables. The first is a pointer that has been set to point to students->name. The second is a pointer that has been set to point to new_name.
Replace_Strings changes the first thing it is passed a pointer to to the second thing it is passed a pointer to. So it changes ptr_old_stud_name to have the value of ptr_new_stud_name.
The result is that the local variable ptr_old_stud_name has a new value. This does not change the thing it points to, students->name.
More specifically, ptr_old_stud_name was pointing to the first character of students->name. students->name is an array, and it cannot be altered by changing pointers to it, and its address cannot be changed. To change its contents, you must copy new values into the bytes within it, which you could do by using strcpy to copy bytes into it from new_name.
Your function Update_student is confusing, you should just iterate through the array of students and compare the student's name with cur_name and replace the name when there is a match.
You should also pass the number of students to handle as an argument.
Here is a modified version:
void Update_Student(struct student *students, int count) {
char cur_name[50], new_name[50];
printf("You can update name, and scores.\n");
printf(" current Name: ");
scanf("%49s", cur_name);
printf("new name: ");
scanf("%49s", new_name);
for (int i = 0; i < count; i++) {
if (strcmp(cur_name, students[i].name) == 0) {
strcpy(students[i].name, new_name);
}
}
}
Call from main as Update_Student(students, SIZE);
Note also that you should ignore whitespace when reading the commands by adding a space before the %c:
scanf(" %c", &ch);
Here is a modified version with for multiple students:
#include <stdio.h>
#include <string.h>
#define SIZE 10
struct student {
int id_number;
char name[50];
char sex[6];
int quiz_score[2];
int total_score;
};
int Add_Student_Records(struct student *pupil) {
printf("ID:");
if (scanf("%d", &pupil->id_number) != 1)
return 0;
printf("Name: ");
if (scanf("%49s", pupil->name) != 1)
return 0;
printf("Sex :");
if (scanf("%1s", pupil->sex) != 1)
return 0;
for (int i = 0; i < 2; i++) {
printf("Quiz score %d:", i + 1);
if (scanf("%d", &pupil->quiz_score[i]) != 1)
return 0;
}
pupil->total_score = pupil->quiz_score[0] + pupil->quiz_score[1];
return 1;
}
int Add_Students(struct student *students, int count) {
int i;
for (int i = 0; i < count; i++) {
printf("Student %d:\n", i + 1);
if (Add_Student_Records(students + i) == 0)
break;
}
return i;
}
void Print_Students(struct student *students, int count) {
for (int i = 0; i < count; i++) {
printf("Student %d details: \n", i + 1);
printf("ID:%d\n", students->id_number);
printf("Name:%s\n", students->name);
printf("Sex:%s\n", students->sex);
for (int i = 0; i < 2; i++) {
printf("Quit score %d:\n", students->quiz_score[i]);
}
printf("Total score: %d\n", students->total_score);
students++;
}
}
void Update_Student(struct student *students, int count) {
char cur_name[50], new_name[50];
printf("You can update name, and scores.\n");
printf(" current Name: ");
if (scanf("%49s", cur_name) != 1)
return;
printf("new name: ");
if (scanf("%49s", new_name) != 1)
return;
for (int i = 0; i < count; i++) {
if (strcmp(cur_name, students[i].name) == 0) {
strcpy(students[i].name, new_name);
}
}
}
int main() {
struct student students[SIZE];
int n = 0;
char ch = 'E';
/* print the menu */
printf("1. Add student\n"
"2. Print students\n"
"3. Update student\n");
scanf(" %c", &ch);
while (ch != 'E') {
if (ch == '1') {
if (n == SIZE) {
printf("student array is full\n");
} else {
/* add more students */
n += Add_Students(&students[n], SIZE - n);
}
} else
if (ch == '2') {
Print_Students(students, n);
} else
if (ch =='3') {
Update_Student(students, n);
}
scanf("%*[^\n]"); // consume the rest of the pending input line
printf("Another operation:\t");
if (scanf(" %c", &ch) != 1)
break;
}
return 0;
}

trying to understand my problems in my code

Input data works for me in the Init function. But once I put in some names and ask for the score of an existing name or a non-existent name, it always returns the grade of the first name
I create two arrays. One of names and one of grade.
Checks whether they meet all the terms of "proper name" as defined by us.
Takes another name and checks if it is in a database. If so, returns the score if it does not return -1
''''
int Data_duplication(char* temp, char** names, int line);
void Init(char*** names, int** grades, int* size);
int Find(char** names, int* grades, int size, char* name);
void FreeAll(char*** names, int** grades, int size);
int main()
{
char** Names = NULL;
int* Grades = NULL;
int size,grade;
char name[SIZE] = { 0 };
Init(&Names, &Grades, &size);
printf("Enter a student name\n");
scanf("%s",name);
grade=Find(Names, Grades, size, name);
printf("%d", grade);
FreeAll(&Names, &Grades, size);
return 0;
}
void Init(char*** names, int** grades, int* size)
{
int i, j, flag;
int strlengh;
char temp[SIZE] = { 0 };
printf("Enter number of students\n");
scanf("%d", size);
*names = (char**)malloc((*size) * sizeof(char*));
if (!(*names))
{
printf("Error");
return;
}
*grades = (int*)malloc((*size) * sizeof(int));
if (!*grades)
{
printf("Error");
return;
}
for (i = 0;i < *size;i++)
{
printf("Enter a name\n");
scanf("%s", temp);
strlengh = strlen(temp);
do
{
flag = 1;
if (strlen(temp) > 20)//if it longer then it should be
flag = 0;
if (temp[0] > 'Z' || temp[0] < 'A') //start with capital letter
flag = 0;
for (j = 1;temp[j] != '\0';j++)//all the letter is a lower case letters except from the first
{
if (temp[j] > 'z' || temp[j] < 'a')
{
flag = 0;
break;
}
}
if (Data_duplication(temp, *names, i))//if its not a name that already entered
{
flag = 0;
}
if (flag)//if the name is ok
{
(*names)[i] = (char*)malloc((strlengh + 1) * sizeof(char));
if (!(*names)[i])
{
printf("Error");
return;
}
strcpy((*names)[i], temp);
}
else//if somthing wrong
{
printf("Bad name,try again.\n");
scanf("%s",temp);
}
} while (!flag);
printf("Enter grade\n");
scanf("%d", (*grades + i));
while ( *(*grades + i) < 0 || *(*grades + i) > 100)//if the grade between 0 to 100
{
printf("Bad grade,try again.\n");
scanf("%d", (*grades + i));
}
}
}
int Data_duplication(char* temp, char** names, int line)//find if there is another name like this that already entered
{
for (int i = 0;i < line;i++)
{
if (!strcmp(temp, names[i]))
{
return 1;
}
}
return 0;
}
int Find(char** names, int* grades, int size, char* name)
{
int i;
for (i=0;i < size;i++)
{
if (strcmp(name,names[i])==0);
{
return (*(grades+i));
}
}
return -1;
}
void FreeAll(char*** names, int** grades, int size)//free al the dynamic memo allocation
{
for (int i = 0;i < size;i++)
{
free(*(*names + i));
}
free(*names);
free(*grades);
}

Write data in files from array of structures using pointers

I am trying to rewrite text in files, changing first line by +1(that holds number of struct saved in igraci.txt) This part is working fine. Then rewrite all text that was there before(This is also working fine) and in the end add 2 new lines in text. Problem is in the last code i wrote here
These are some global variables that I am having problem with and strcture
int RijeciBroj = 0;
int IgraciBroj = 0;
typedef struct Igrac
{
char ime[20];
int brojPoena;
};
This is method for allocating memmory for structures having in mind that one strcture is going to be added
struct Igrac* napraviProstor(int n) {
IgraciBroj = n; //here I try to give global new value
printf("U NAPRAVI PROSTOR : %d", IgraciBroj); // Here i get -9282928
return (struct Igrac*) malloc((n + 1) * sizeof(struct Igrac));
}
This is method that is reading text from file and storing it in allocated memory
void ucitajIgrace(struct Igrac *arr) {
static const char filename[] = "igraci.txt";
FILE *file;
file = fopen(filename, "r");
if (file != NULL)
{
char line[20];
int n;
fscanf(file, "%d", &n);
int i = -1;
int k = 0;
fgets(line, 20, file);
while (fgets(line, 20, file) != NULL) /* read a line */
{
line[strcspn(line, "\n")] = '\0';
i++;
if (i == 0) {
strcpy((arr + k)->ime, line);
}
if (i == 1) {
(arr + k)->brojPoena = atol(line);
k++;
i = -1;
}
}
printf("Igraca: %d", IgraciBroj); //here i get -9892827280
fclose(file);
}
else
{
perror(filename);
}
}
Main method
int main()
{
int o;
Igrac *igr;
FILE *file1;
file1 = fopen("igraci.txt", "r");
if (file1 != NULL)
{
char line[20];
fscanf(file1, "%d", &o); //first line is number of structs
igr = napraviProstor(o);
ucitajIgrace(igr);
}
pocniIgru(rijeci,igr); //ignore rijeci that is another array that is working perfect and has nothing to do with my problem
return 0;
}
This is method where I have problem
void pocniIgru(char** rijeci, struct Igrac *igraci) {
int dobijeni[5] = {}; //array that is saving random numbers so they don't repeat
int brojac1 = 0; //used for index of dobijeni[5]
char srpska[30]; // for user input
char ime[20]; //for users name that we are going to store in igraci.txt
int poeni = 0; //number of points
bool moze; //boolean for loop control
printf("Pocinje igra\n");
printf("\n\n\n\n");
int pitanje; // for random number that we are going to get
for (int i = 0; i < 5; i++) {
moze = true;
LOOP:do {
srand(time(NULL));
pitanje = rand() % RijeciBroj-1; //random number between 0 - global variable here global variable is working fine!
if (pitanje % 2 != 0) {
pitanje++; // I need even number and 0 is accepted
}
for (int k = 0; k < 5; k++) {
if (dobijeni[k] == pitanje) { //checking if we arleay had that number
goto LOOP; // goto LOOP if we had that number so we pick another
}
}
dobijeni[brojac1] = pitanje; //storing that number in loop for later check so it won't repeat
moze = false; // do-while stops
brojac1++;
} while (moze);
printf("Engleska rijec je: %s", rijeci[pitanje]); //get word from array
printf("Unesite rijec na srpskom jeziku: ");
scanf("%30s", srpska); //user input for comparing
strtok(rijeci[pitanje + 1], "\n"); //we need to remove newline
if (strcmp(rijeci[pitanje+1], srpska) == 0) { //cheking if next word is same with user input
poeni += 2;
printf("Tacno! Vas broj peona je %d\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", poeni);
}
else {
poeni -= 1;
if (brojac != 5) {
printf("Greska! Vas broj peona je %d\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", poeni);
}
}
}
printf("Ukupan broj poena je: %d\n", poeni);
printf("Unesite svoje ime: "); //Enter your name
scanf("%s", ime); //get name
if (strcmp(ime, "")) { //check if it's empty
IgraciBroj += 1; //global variable +1 for rewriting in file
strcpy((igraci + IgraciBroj)->ime, ime); //save name in char* struct in last place that is empty
(igraci + IgraciBroj)->brojPoena = poeni; //save points in char* struct in last place that is empty
printf("%s osvojili ste %d poena", (igraci + IgraciBroj)->ime, (igraci + IgraciBroj)->brojPoena); //Here i get normal result and name
FILE *file1;
file1 = fopen("igraci.txt", "w");
if (file1 != NULL)
{
fprintf(file1, "%d\n", IgraciBroj);
for (int broj = 0; broj < IgraciBroj; broj++) {
fprintf(file1, "%s\n", (igraci + broj)->ime); //Problem !! I get some lines before name in file example(----------Name)
fprintf(file1, "%d\n", (igraci + broj)->brojPoena); //Problem !! I get some number like -9899887
}
}
}

Creating a program in C that saves and shows data

I'm new with C, and on the university they are making us create a program that can save data introduced by the user, read the data and check if it’s well introduced. After that it must save that data in each free space, you have 10 empty spaces for saving the data. With all the data saved it must show also the data and compare it with all the data introduced. I made the part of reading the data introduced and cheking if its ok. The problem that I have is that I don’t know how I could make the data base and show that data. Here is the code that I have till now.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char name[30];
int num_sample;
char section;
int cabin;
int day;
int month;
int year;
}Species;
int menu() {
int op = 0;
printf ("\nPrototype Nature Reserve.\n");
printf ("1. Insert a new species.\n");
printf ("2. List the species housed.\n");
printf ("3. Show stadistics.\n");
printf ("4. Exit.\n");
printf ("\nIntroduce an option: ");
scanf ("%d", &op);
return op;
}
void New_species() {
Species e;
int i, j;
char species[100];
char aux[10];
printf("Enter data:\n");
//A fflush is made to not have a problem with the number entered in the menu
fflush(stdin);
gets (species);
//While it is different from - read the text
for (i = 0; species[i] != '-'; i++) {
e.name[i] = species[i];
}
e.name[i] = '\0';
i++;
//We add 1 to the position i because is ending in - and should start reading from the following
for (j = 0; species[i] != '-'; i++,j++) {
aux[j] = species[i];
}
aux[j] = '\0';
e.num_sample = My_atoi(aux);
// Check that the sample is a number and not a character
if (e.num_sample <= 0 || e.num_sample >= 100) {
printf ("--> Error in data format.\n");
}
i++;
//Reads the day introduced
for (j = 0; species[i] != '/'; i++, j++) {
aux[j] = species[i];
}
aux[j] = '\0';
e.day = My_atoi(aux);
//Controls the format of the day
if (e.day <= 0 || e.day > 31) {
printf ("--> Error in data format.\n");
}
i++;
//Reads the month introduced
for (j = 0; species[i] != '/'; i++, j++) {
aux[j] = species[i];
}
aux[j] = '\0';
e.month = My_atoi(aux);
//Controls the format of the month
if (e.month <= 0 || e.month > 12) {
printf ("--> Error in data format.\n");
}
i++;
//Reads the year introduced
for (j = 0; species[i] != '-'; i++, j++) {
aux[j] = species[i];
}
aux[j] = '\0';
e.year = My_atoi(aux);
//Controls the format of the year
if (e.year < 1970 || e.year > 2060) {
printf ("--> Error in data format.\n");
}
i++;
//Reads the section introduced
e.section = species[i];
//Controls that the section is in capital letters
if (e.section < 'A' || e.section > 'Z') {
printf ("--> Error in data format.\n");
}
i+= 2;
//As the cabin is at the end it must reach the \0
for (j = 0; species[i] != '\0'; i++, j++) {
aux[j] = species[i];
}
aux[j] = '\0';
e.cabin = My_atoi(aux);
if (e.cabin < 0 || e.cabin > 20) {
printf ("--> Error in data format.\n");
}
printf ("Species stored successfully (%d/10 free).");
//This printf is just to ensure that the data entered was read correctly
printf ("\n%s", species);
}
int My_atoi(char cad[10]) {
int r = 0;
int i;
for (i = 0; cad[i] != '\0'; i++) {
r = r * 10;
r += cad[i] - '0';
}
return r;
}
void list_species() {
}
void stadistics() {
}
void executeOption(int op) {
switch (op) {
case 1:
New_species();
break;
case 2:
list_species();
break;
case 3:
stadistics();
break;
default:
break;
}
}
int main() {
int op = 0;
do {
op = menu();
executeOption(op);
} while (op != 4);
return 0;
}
I’ve seen that you can use files* so it can create a .txt file for storing but I don’t know how to use it and I don't think that it's allowed in this program.
I'll leave a photo of how it should work
Thanks.
ok u need to save data to a file and load from a file.
here a short code of my and read and write:
#include<stdio.h>
#include<stdlib.h>
typedef struct worker
{
int sal;
char name[25];
}W;
void main()
{
FILE *f;
int i,j=4;
W a[3];
while(j!=3)
{
printf("\nEnter\n[1]write\n[2]read\n[3]exit\n");
scanf("%d",&j);
if(j==1)
{
if (f==NULL)
{
printf("Error!!\n");
exit(0);
}
f=fopen("workers.txt","w");
for(i=0;i<3;i++)
{
printf("\nEnter worker name: ");
scanf("%s",&a[i].name);
printf("\nEnter worker sal: ");
scanf("%d",&a[i].sal);
fprintf(f,"%s %d",a[i].name,a[i].sal);
}
if(j==2)
{
if (f==NULL)
{
printf("Error!!\n");
exit(0);
}
f=fopen("workers.txt","r");
for(i=0;i<3;i++)
{
fscanf(f,"%s %d",a[i].name,&a[i].sal);
printf("\n%s %d",a[i].name,a[i].sal);
}
}
}
fclose(f);}
and I don't think that it's allowed in this program
why wouldn't you be allowed? Yes indeed you can go through two alternatives
To text file
This is the one proposed by dor in his answer where he shows you the way of writing text through fprintf.
To binary file
You can also write to a file using fwrite/fseek like this example I found surfing around you can check it out here -> c-tutorial-binary-file-io
#include<stdio.h>
/* Our structure */
struct rec
{
int x,y,z;
};
int main()
{
int counter;
FILE *ptr_myfile;
struct rec my_record;
ptr_myfile=fopen("test.bin","wb");
if (!ptr_myfile)
{
printf("Unable to open file!");
return 1;
}
for ( counter=1; counter <= 10; counter++)
{
my_record.x= counter;
fwrite(&my_record, sizeof(struct rec), 1, ptr_myfile);
}
fclose(ptr_myfile);
return 0;
}
and retrieving back the data from the binary may go this way as the tutorial shows
#include<stdio.h>
/* Our structure */
struct rec
{
int x,y,z;
};
int main()
{
int counter;
FILE *ptr_myfile;
struct rec my_record;
ptr_myfile=fopen("test.bin","rb");
if (!ptr_myfile)
{
printf("Unable to open file!");
return 1;
}
for ( counter=1; counter <= 10; counter++)
{
fread(&my_record,sizeof(struct rec),1,ptr_myfile);
printf("%d\n",my_record.x);
}
fclose(ptr_myfile);
return 0;
}
If you are looking for a solution in a .txt file I have a proposal,
#include <stdio.h>
int main(){
FILE *in;
FILE *OUT = fopen("read_at.txt", "w");
char name[20];
char capture[80];
int age = 0;
float grade = 0;
puts("introduce your name:");
scanf("%19s", name);
puts("introduce your age:");
scanf("%i", &age);
puts("introduce your Math grade(0-10):");
scanf("%f", &grade);
fprintf(OUT, "Age %i, Grade %f, Name %s\r\n", age, grade, name);
fclose(OUT);
if(!(in = fopen("read_at.txt","r"))){
fprintf(stderr, "The file could not be opened. \n");
return 1;
}
while (fscanf(in, "Age %i, Grade %f, Name %20[^\n]\n", &age, &grade, name)==3){
printf("A %i years old student has achieved a %f mark in last math exam, that student is: %s", age,grade, name);
}
fclose(in);
}
In this code that I have just created you can see how you can just create one file and read and get its data if it has a concrete format. If you are looking for a database you can just put values separated by “;” and new lines (\n). With that if you save it as .csv you would obtain an excel sheet and quite a good database.
If you are interested in this solution, just let me know if you need any additional help.
Regards,

Resources