Reputation: 167
ISSUE: I'm trying to fill my beerData
struct
with data found in beer.dat
, except I don't understand how structs work well enough to implement without crashing my code. I believe I need an array of structs.
The beer.dat file contents:
7 // total number of beers
Coors //beer name
1234567 // beer id
72 // beer quantity
7.40 //beer price
Miller
7777777
44
9.70
Bud
7654321
345
9.90
Wachusett
7799435
4
14.70
Corona
9999999
112
9.99
Zima
0000000
1
0.01
Mikes
0890398
12
10.99
CODE:
/*
User interface, alloc, malloc 13 points
Correct structure and array built 7 points
Recursive sort
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct beerData {
char *beer[7]; // number of brands
char *beer_name; //names
int beer_id[7]; //ID number given to beer
int beer_quantity; //stock
float beer_price; // pricing
} beer_data;
void printStr(char *line) {
char *look = "";
printf("What would you like to search for? \n");
scanf("%s", look);
//printf("Line: %s\n", line);
exit(0);
}
void search() {
//look through beer.dat for a specific beer by ID number.
char str[32];
FILE *fp = fopen("beer.dat", "r");
if (fp == NULL) {
printf("Error: can't open file to read\n");
} else {
while (!feof(fp)) {
fscanf(fp, "%s ", str);
//printf("%s\n",str);
printStr(str);
}
}
fclose(fp);
}
int main() {
int user_choice;
printf("Enter 1 to search for a beer, 2 to view the entire catalogue,"
" and 3 to place an order, press 4 to exit.\n");
while (user_choice != 4) {
scanf("%d", &user_choice);
switch (user_choice) {
case 1:
printf("Searching for a beer\n");
user_choice = 0;
search();
break;
case 2:
printf("Viewing Inventory\n");
//viewInv();
break;
case 3:
printf("Placing an order...\n");
//placeOrder();
break;
case 4:
printf("Goodbye!\n");
exit(0);
default:
printf("Incorrect entry, try again.\n");
continue;
}
}
}
I'm trying create a function that searches through the file, and finds a specific beer based on an ID given, that ID is inside a set that should be its struct... so once the ID is input, the program searches for the beer, and prints out the name, ID, quantity, and price.
For full clarity, I'll post the assignment questions in case I'm not conveying my needs properly. The assignment is to:
Upvotes: 3
Views: 557
Reputation: 31609
First you need to declare a meaningful structure. The structure contains relevant information for each item. Example:
typedef struct beer_data
{
char name[20]; //names
int id; //ID number given to beer
int quantity; //stock
float price; // pricing
} beer_data;
Next, you need an array of this structure. Use malloc
to allocate enough memory for total
number of items. Example:
beer_data *beers = malloc(total * sizeof(beer_data));
Now you have beers[0], beers[1], beers[2]...
, read each item in the file and put that in the structure.
To read the file, you can use fscanf
or fgets
.
The first line in your file is
7 // total number of beers
You can read the number 7
using fscanf
:
int maximum = 0;
fscanf(fp, "%d", &maximum);
This should work fine, but there are characters after that which you are not interested in. Use fgets
to read to the end of the line and discard those characters.
Start a loop and read each line, add to the structure.
With this method, if you are adding a new item, then you have to increase the memory size. See add_item
which uses realloc
. This might be too advanced. Alternatively, you can save the new item to the file, call free(beers)
, and read the file again.
typedef struct beer_data
{
char name[20]; //names
int id; //ID number given to beer
int quantity; //stock
float price; // pricing
} beer_data;
void search_by_name(beer_data *beers, int total)
{
char buf[20];
printf("Enter name to search: ");
scanf("%19s", buf);
//note, we put %19s because beers[count].name is only 20 bytes long
for(int i = 0; i < total; i++)
{
if(strcmp(beers[i].name, buf) == 0)
{
printf("Found: %s, %d, %d, %.2f\n",
beers[i].name, beers[i].id, beers[i].quantity, beers[i].price);
return;
}
}
printf("%s not found\n", buf);
}
void print_list(beer_data *beers, int total)
{
for(int i = 0; i < total; i++)
{
printf("%s %d %d %.2f\n",
beers[i].name, beers[i].id, beers[i].quantity, beers[i].price);
}
}
void add_item(beer_data *beers, int *total)
{
//note, total has to be passed as pointer
//because we are changing it
//allocate more memory:
beers = realloc(beers, sizeof(beer_data) * (*total + 1));
printf("enter name: ");
scanf("%19s", beers[*total].name);
printf("enter id:");
scanf("%d", &beers[*total].id);
printf("enter quantity:");
scanf("%d", &beers[*total].quantity);
printf("enter price:");
scanf("%f", &beers[*total].price);
//increase the total
*total += 1;
}
int main()
{
FILE *fp = fopen("beer.dat", "r");
if(!fp)
{
printf("Error: can't open file to read\n");
return 0;
}
char buf[500];
int maximum = 0;
fscanf(fp, "%d", &maximum);
//read the rest of the line and discard it
fgets(buf, sizeof(buf), fp);
//allocate memory
beer_data *beers = malloc(maximum * sizeof(beer_data));
int total = 0;
while(1)
{
fgets(buf, sizeof(buf), fp);
sscanf(buf, "%19s", beers[total].name);
if(fscanf(fp, "%d", &beers[total].id) != 1) break;
fgets(buf, sizeof(buf), fp);
if(fscanf(fp, "%d", &beers[total].quantity) != 1) break;
fgets(buf, sizeof(buf), fp);
if(fscanf(fp, "%f", &beers[total].price) != 1) break;
fgets(buf, sizeof(buf), fp);
total++;
if(total == maximum)
break;
}
fclose(fp);
int stop = 0;
while (!stop)
{
printf("\
Enter 0 to exit\n\
Enter 1 print list\n\
Enter 2 for search\n\
Enter 3 add new item\n");
int choice;
scanf("%d", &choice);
switch(choice)
{
case 0:
stop = 1;
break;
case 1:
print_list(beers, total);
break;
case 2:
search_by_name(beers, total);
break;
case 3:
add_item(beers, &total);
break;
}
printf("\n");
}
//cleanup:
free(beers);
return 0;
}
Upvotes: 2