After reading the material in the text file, if there is a corresponding name through the search, print out the name and money. However, I can only read the first line of the text file. If I want to make it read another line and find the corresponding name what can I do?
my text file has 15 lines.
Jane 50
Bruno 100
Kim 200
Young 150
Will 250
Jane 50
Bruno 100
Kim 200
Young 150
Will 250
Jane 50
Bruno 100
Kim 335
Young 455
Will 555
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct user{
char name [10];
int money;
} userinformation;
int main()
{
userinformation myvar[100];
int x=0;
char find_name[100];
int i = 0;
int idx = 0;
char buffer[1001],*token;
char* ptr;
userinformation* userinfo;
int cents_50=0;
int cents_20=0;
int cents_10=0;
int cents_5=0;
FILE * srcFile = fopen("coins.txt", "r");
if(srcFile == NULL)
{
printf("fail to open file");
return -1;
}
//file read from coins.txt
while (!feof(srcFile))
{
i =0;
fgets(buffer, 1001, srcFile);
token = strtok(buffer, " ");
while (token != NULL)
{
if(i == 0)
{
strcpy(myvar[idx].name, token);;
}
else if (i == 1)
{
myvar[idx].money = atoi(token);
}
i++;
token = strtok(NULL, " ");
}
idx++;
}
for(int i = 0; i <idx; i++)
{
printf("%s %d\n", myvar[i].name, myvar[i].money);
}
fclose(srcFile);
while(x != 2)
{
printf("1.Enter name\n");
printf("2.Exit\n");
scanf("%d%*c", &x);
if(x ==1)
{
printf("Name: ");
scanf("%s%*c", find_name);
for(i=0; i<idx; i++)
{
ptr = strstr(myvar->name, find_name);
}
if(ptr != NULL)
{
printf("Customer: \n");
printf("%s %d\n", myvar->name, myvar->money);
printf("Change: \n");
//calculate 50cents;
if(myvar->money>50)
{
myvar->money/50;
cents_50++;
printf("50 cents : %d \n", cents_50);
}
//calculate 20cents;
if((myvar->money/50)<50 && myvar->money >=20)
{
if((myvar->money%50/20)>=1)
{
(myvar->money%50/20);
cents_20++;
printf("20 cents : %d \n", cents_20);
}
}
//calculate 10cents;
if((myvar->money%50%20/10)<20 && myvar->money >=10)
{
if((myvar->money%50%20/10)>=1)
{
(myvar->money%50%20/10);
cents_10++;
printf("10 cents : %d \n", cents_10);
}
}
if((myvar->money%50%20%10/5)<10 && myvar->money >=5)
{
if((myvar->money%50%20%10/5)>=1)
{
(myvar->money%50%20%10/5);
cents_5++;
printf("5 cents : %d \n", cents_5);
}
}
}
else if(ptr != myvar->name)
{
printf("Not founded\n");
}
}
else if(x ==2)
break;
}
return(0);
}
'''
This seems wrong:
for(i=0; i<idx; i++)
{
ptr = strstr(myvar->name, find_name);
}
myvar is an array but you don't use an array index. In other words - you always use the first element of the array (i.e. myvar[0].name).
Besides that, I would expect that the loop should stop when strstr return a non-NULL value.
Did you intend to do:
for(i=0; i<idx; i++)
{
ptr = strstr(myvar[i].name, find_name);
if (ptr != NULL) break;
}
(btw - do you really want to use strstr? I would expect a string compare using strcmp ).
The same problem, i.e. missing array index, is present in all the code that follows the above code.
BTW: The way you read from the file isn't 100% correct. See Why is “while ( !feof (file) )” always wrong?
Related
I would like to take all of the initial value from struct to do calculate, but it always show total in 0 to me. It supposed to show me a total value of 21.. Anyone that can help me to fix my program I will be very appreciated. Thank you for reviewing my question.. (Below is my code and text file)
wbz.txt:
PID00001:Aircon:2
PID00002:Windows:10
PID00003:Pipe:9
My Code:
#define SIZE 100
struct parts
{
char pid[50], pname[50];
int initialvalue;
}p[SIZE];
int main()
{
FILE* f;
char data[100], pid[50], * s, back;
int buf = 0, choice, i=0, total=0;
memset(p, 0, sizeof(p));
do {
printf("Which warehouse (1.WBZ | 2.WSL | 3.WAR): ");
scanf("%d", &choice);
if (choice == 1)
{
f = fopen("wbz.txt", "r");
while (fgets(data, sizeof data, f))
{
s = strtok(data, ":");
if (s != NULL)
{
strcpy(p[i].pid, s);
}
s = strtok(NULL, ":");
if (s != NULL)
{
strcpy(p[i].pname, s);
}
s = strtok(NULL, ":");
if (s != NULL)
{
p[i].initialvalue = atoi(s);
}
printf("\nParts ID: %s\nParts Name: %s\nParts Quantity: %d\n", p[i].pid, p[i].pname, p[i].initialvalue);
if (p[i].initialvalue < 10)
{
printf("\n---------------------------------------");
printf("\n%s unit is not enough, only %d left\n", p[i].pname, p[i].initialvalue);
printf("---------------------------------------\n");
}
else
{
printf("\n---------------------------------------");
printf("\nThis unit is enough\n");
printf("---------------------------------------\n");
}
}
if (i > 0)
p[i].initialvalue += p[i - 1].initialvalue;
if (++i == SIZE)
{
break;
}
p[i].initialvalue += p[i].initialvalue;
printf("\nTotal: %d", p[i].initialvalue);
fclose(f);
}
printf("\nDo you want to continue (y/n): ");
getchar();
scanf("%c", &back);
} while (back != 'n');
return 0;
}
You update p[i].initialVlue using itself after having incremented i = you add 0 to 0 because the value you add is not yet set :
// update should be before the ++i and using previous index
If (i > 0) {p[i].initialvalue += p[i-1].initialvalue;}
if (++i == SIZE)
{
break;
}
} // end of while loop here
// next line is not good so remove it
//p[i].initialvalue += p[i].initialvalue;
// i is SIZE here do decrease it
// to get the last value
i—
printf("\nTotal: %d", p[i].initialvalue);
}
Also you should initialise p with 0 before using it :
memset(p,0,sizeof(p));
I am making a simple library to store, edit, search books and add new books.
I have the following structure:
struct books {
char bname[150];
char bauthor[100];
unsigned bpages,
price,
numavail;
} info[MAX]; //array of structures
I have this function to calculate the number of books in the txt file and it works fine:
int numofbooks(FILE *ptr) {
char ch;
int num = 0, keep;
ch = fgetc(ptr);
while (ch != EOF) {
if (ch == ':') {
num++;
}
ch = fgetc(ptr);
}
return num / 5;
}
and I am using this function to add new books and store then in a txt file and also to the array info. Here the variable p is always 0 even there are books in the file:
void add() {
int ans = 1;
static int p;
char bname[30], bauthor[30];
unsigned price, bpages, numavail;
FILE *ptr = fopen("books info.txt", "a");
system("cls");
if (ptr == NULL) {
printf("Couldn't open the file....");
exit(1);
}
p = numofbooks(ptr); //calling numofbooks to store the number of books in the file in static variable p
printf("%d", p); //it always prints 0
while (ans == 1) {
printf("\nEnter The name of the book: ");
fflush(stdin);
gets(info[p].bname);
fprintf(ptr, "Book name: %s\n", info[p].bname);
fflush(stdin);
printf("Enter The author of this book: ");
gets(info[p].bauthor);
fprintf(ptr, "Book author: %s\n", info[p].bauthor);
fflush(stdin);
printf("Enter The number of pages of this book: ");
scanf("%u", &info[p].bpages);
fprintf(ptr, "Number of pages: %u\n", info[p].bpages);
fflush(stdin);
printf("What is the price of the book (in EGP)? ");
scanf("%u", &info[p].price);
fprintf(ptr, "Price (in EGP): %u\n", info[p].price);
printf("Number of books available: ");
scanf("%u", &info[p].numavail);
fprintf(ptr, "Number of books available: %u", info[p].numavail);
fprintf(ptr, "\n---------------------------------------------------------\n");
printf("\nBook information saved successfully....\n");
fflush(stdin);
printf("\nEnter (1) to add another book, (0) to exit or (2) for main menu. ");
scanf("%d", &ans);
if (ans == 2) {
fclose(ptr);
system("cls");
main();
}
}
}
here is the function I used to search in the file using the name of the author:
void searchauthor(FILE *ptr) {
char in_name[30];
int flag = 1;
ptr = fopen("books info", "r");
fflush(stdin);
printf("Enter the name of the author: ");
gets(in_name);
int num = numofbooks(ptr); //num to hold number of books
for (int i = 0; i < num; i++) {
if (strcmpi(in_name, info[i].bauthor) == 0) {
printf("%s %u %u %u", info[i].bname, info[i].price, info[i].numavail, info[i].bpages);
flag = 0;
}
}
if (flag == 1) {
printf("Not found.");
}
}
here is the code that reads data from the file:
ptr = fopen("books info.txt", "r");
printf("Total (%d) books are available:-\n\n", numofbooks(ptr));
ptr = freopen("books info.txt", "r", ptr);
ch = fgetc(ptr);
while (ch != EOF) {
printf("%c", ch);
ch = fgetc(ptr);
}
The problem is that this function always prints Not found although the name of the author is already in the txt file. how can I solve this?
A sample of the contents of the file
Here is one way things could be arranged.
This addresses the issue of avoiding fflush(stdin) by using fgets for input and sscanf to parse as needed.
Generally it is a bad idea to call main from a function. Return to main and use a loop to repeat menu choices.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
struct books{
char bname[150];
char bauthor[100];
unsigned bpages;
unsigned price;
unsigned numavail;
} info[MAX];
int readbooks ( void) {
FILE *ptr = fopen("books info.txt", "r");
if ( ! ptr) {
perror ( "books info.txt");
return 0;
}
int book = 0;
int field = -1;
int each = 0;
int parse = 0;
int ch = 0;
info[0].bname[0] = 0;
info[0].bauthor[0] = 0;
info[0].bpages = 0;
info[0].price = 0;
info[0].numavail = 0;
while ( EOF != ( ch = fgetc ( ptr))) {
printf("%c", ch);
if ( '\n' == ch) {
parse = 0;//end of line. no parsing
}
if ( parse) {
if ( ! each && ( ' ' == ch || '\t' == ch)) {
continue;//skip leading spaces
}
if ( 0 == field) {
if ( each + 1 < 150) {
info[book].bname[each] = ch;
++each;
info[book].bname[each] = 0;
}
printf ( "name %s ", info[book].bname);
}
if ( 1 == field) {
if ( each + 1 < 100) {
info[book].bauthor[each] = ch;
++each;
info[book].bauthor[each] = 0;
}
printf ( "author %s ", info[book].bauthor);
}
if ( 2 == field) {
info[book].bpages *= 10;
info[book].bpages += ch - '0';
}
if ( 3 == field) {
info[book].price *= 10;
info[book].price += ch - '0';
}
if ( 4 == field) {
info[book].numavail *= 10;
info[book].numavail += ch - '0';
}
}
if ( ':' == ch) {
++field;
if ( 5 == field) {
field = 0;
if ( book + 1 < MAX) {
++book;
info[book].bname[0] = 0;
info[book].bauthor[0] = 0;
info[book].bpages = 0;
info[book].price = 0;
info[book].numavail = 0;
}
}
each = 0;
parse = 1;//resume parsing
}
}
fclose ( ptr);
if (4 == field) {
++book;
}
return book;
}
int add ( void) {
int ans = 1;
char line[100] = "";
int p;
p = readbooks();
printf("%d", p);
FILE *ptr = fopen("books info.txt", "a");
if ( ! ptr) {
perror ( "books info.txt");
return 0;
}
while(ans == 1){
printf("\nEnter The name of the book: ");
fgets(info[p].bname, 150, stdin);
info[p].bname[strcspn ( info[p].bname, "\n")] = 0;
fprintf(ptr, "Book name: %s\n", info[p].bname);
printf("Enter The author of this book: ");
fgets(info[p].bauthor, 100, stdin);
info[p].bauthor[strcspn ( info[p].bauthor, "\n")] = 0;
fprintf(ptr, "Book author: %s\n", info[p].bauthor);
printf("Enter The number of pages of this book: ");
fgets ( line, 100, stdin);
sscanf(line, "%u", &info[p].bpages);
fprintf(ptr, "Number of pages: %u\n", info[p].bpages);
printf("What is the price of the book (in EGP)? ");
fgets ( line, 100, stdin);
sscanf( line, "%u", &info[p].price);
fprintf(ptr, "Price (in EGP): %u\n", info[p].price);
printf("Number of books available: ");
fgets ( line, 100, stdin);
sscanf( line, "%u", &info[p].numavail);
fprintf(ptr, "Number of books available: %u", info[p].numavail);
fprintf(ptr, "\n---------------------------------------------------------\n");
printf("\nBook information saved successfully....\n");
++p;
printf("\nEnter (1) to add another book\nor (2) for main menu. ");
fgets ( line, 100, stdin);
sscanf( line, "%d", &ans);
if (ans == 2) {
fclose(ptr);
}
}
return p;
}
int main ( void) {
int totalbooks = 0;
totalbooks = add ( );
for ( int each = 0; each < totalbooks; ++each) {
printf ( "name %s\n", info[each].bname);
printf ( "author %s\n", info[each].bauthor);
printf ( "pages %u\n", info[each].bpages);
printf ( "price %u\n", info[each].price);
printf ( "number %u\n", info[each].numavail);
}
return 0;
}
I am doing a program that reads user input files (coordinates) and it creates a minesweeper mini-game, with bombs placed at given coordinates.
My problem is with the read option, the input should be: read filename.
I am trying to separate the string in two, but I'm not doing great.
ps. I'm a beginner so I probably made stupid mistakes, and the code is a mess right now because it's not finished.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define map_SIZE 25
void mapa(void);
void printUsermap(void);
void readf(void);
void bombmaker (void);
int x, y, i, j;
int numbers;
char mines;
char map[map_SIZE][map_SIZE];
char final_map[map_SIZE][map_SIZE];
char umap[map_SIZE][map_SIZE];
void mapa(void){
int column, row;
for(column = 0; column < map_SIZE; column++)
for(row = 0; row < map_SIZE; row++)
umap[column][row] = '_';
}
void printUsermap(){
int column, row;
system("cls");
for(column = 0; column < map_SIZE ; column++)
{
for(row = 0; row < map_SIZE; row++)
{
printf("%c", umap[column][row]);
}
printf("\n");
}
}
void bombmaker (){
int i=0, j=0;
if( map[i][j] != '*')
{
map[i][j] = '*';
final_map[i][j] = map[i][j];
mines++;
}
}
void readf(){
char string[50] = "practice try.ini ";
// Extract the first token
char * token = strtok(string, " ");
// loop through the string to extract all other tokens
while( token != NULL ) {
printf( " %s\n", token ); //printing each token
token = strtok(NULL, " ");
}
//reading second string
/*char buff[128];
int i = 0;
scanf("%s",buff);
char *p = strtok (buff, " ");
char *div_var[2];
while (p)
{
div_var[i++] = p;
p = strtok (NULL, " ");
}
for (i = 0; i < 2; i++)
{
printf("data[%i] = %s\n", i+1, div_var[i]);
}
char ch, file_name[25];
printf("> ");
gets(file_name);
FILE *fp;
fp = fopen(div_var[1], "r"); // read mode
if (fp == NULL)
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are:\n", file_name);
while((ch = fgetc(fp)) != EOF)
printf("%c", ch); */
}
int main()
{
char option[128];
// MENU
printf("+-----------------------------------------------------\n");
printf(" read <filename> - read input file\n show - show the mine map\n trigger <x> <y> - trigger mine at <x> <y>\n plant <x> <y> - place armed mine at <x> <y>\n export <filename> - save file with current map\n quit - exit program\n sos - show menu\n ");
printf("+-----------------------------------------------------\n");
do{
printf(">");
scanf ("%s", option);
//Opcao read
//if (strcmp(option, "plant")!=0 || strcmp(option,"tigger")!=0 || strcmp(option, "show")!=0 || strcmp(option, "export")!=0 || strcmp(option, "quit")!=0){
if (strcmp(option, "read")==0){
readf();
}
// Option show
if (strcmp(option, "show")==0)
{
mapa();
printUsermap();
}
// Option trigger
else if (strcmp(option, "trigger")==0)
{
scanf("%d %d", &x, &y);
if (x >= 25 || y >= 25){
fprintf(stdout, "Invalid coordinate\n");
}
else if (map[i][j] == '.'){
map[i][j] = '*';
final_map[i][j] = map[i][j];
mines++;
}
else{
fprintf(stdout, "No mine at specified coordinate\n");
//fprintf(stdout,"Hello. My name is Inigo Montoya. You killed my father. Prepare to die\n");
}
}
// Option plant
else if (strcmp(option, "plant")==0)
{
scanf("%d %d", &x, &y);
if (x >= 25 || y >= 25){
fprintf(stdout, "Invalid coordinate\n");
}
else if (map[i][j] == '_'){
map[i][j] = '.';
final_map[i][j] = map[i][j];
mines++;
}
else if (map[i][j] == '*'){
map[i][j] = '.';
final_map[i][j] = map[i][j];
mines++;
}
else{
//printf ("You're gonna need a bigger boat\n");
}
}
// Opcao export
else if (strcmp(option, "export")==0)
{
FILE * fp;
fp = fopen("file1.text","w");
fprintf(fp, "teste");
fclose(fp);
}
// Opcao SOS
else if (strcmp(option, "sos")==0)
{
printf("+-----------------------------------------------------\n");
printf(" read <filename> - read input file\n show - show the mine map\n trigger <x> <y> - trigger mine at <x> <y>\n plant <x> <y> - place armed mine at <x> <y>\n export <filename> - save file with current map\n quit - exit program\n sos - show menu\n ");
printf("+-----------------------------------------------------\n");
}
}
while (strcmp(option,"quit")!=0);
return 0;
}
Stop using scanf. Read in the input with fgets. Then use strtok (or better strtok_r) to first split of the action. If the action is "read", you can then split of the filename in readf.
in main:
char line[256];
fgets(line, sizeof(line), stdin);
char *action = strtok(line, " \t\n");
in readf you can then get a the filename parameter with
char *filename = strtok(NULL, " \t\n");
Error handling was ommited for brevity.
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,
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
}