Reading struct from binary file (C) - c

I need your help with reading struct from binary file,
the "Grocery read_from_file ()..." function Can't get this to work!
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>
#include <conio.h>
struct grocerylist
{
int iD;
char grocery[30];
float amount;
char unit[10];
};
Grocery set_size_of(Grocery* list, int index);
Grocery input(int index);
void print_grocerylist(Grocery* list, int* index);
void write_to_file(FILE* file_pointer, Grocery* list, int index);
Grocery read_from_file(FILE* file_pointer, Grocery* list, int* index);
void change_item(Grocery* list, int index);
void remove_item(Grocery* list, int* index);
int main()
{
Grocery* list = (Grocery*)malloc(sizeof(Grocery)*1); //Grocery-array allocated memory for 1 struct
int index = 0, choice = 0;
FILE* file_pointer = NULL;
printf("Hey there user!\n");
while(choice != 7){
system("cls");
printf("Menu\n");
printf("1 - Add an item to the list.\n2 - Print the contents of your current list.\n3 - Print the contents to file.\n4 - Read from file.\n5 - Change an item on the list.\n6 - Remove item from the list.\n7 - close the program.\nChoose: ");
scanf("%d", &choice);
printf("\n");
switch(choice){
case 1:
list[index] = input(index);
index++;
*list = set_size_of(list, index); //Reallocating memory for the array of grocery-structs.
fflush(stdin);
break; //Add item
case 2:
print_grocerylist(list, &index); //Print list
fflush(stdin);
break;
case 3:
write_to_file(file_pointer, list, index); //print to file
fflush(stdin);
break;
case 4:
*list = read_from_file(file_pointer, list, &index); //read from file
fflush(stdin);
break;
case 5:
change_item(list, index); //change item
fflush(stdin);
break;
case 6:
remove_item(list, &index); //remove item
index--;
fflush(stdin);
break;
case 7:
free(list);
exit(EXIT_SUCCESS); //End program
break;
default:
printf("Wrong input, please try again!");
fflush(stdin);
getch();
break;
}
}
return 0;
}
Grocery set_size_of(Grocery* list, int index){ //reallocates memory.
list = realloc(list, (index+1)*sizeof(Grocery));
return *list;
}
Grocery input(index){
Grocery tmp;
int x = 0;
tmp.iD = index +1;
fflush(stdin);
printf("Grocery: ");
gets(tmp.grocery);
while(x == 0){
fflush(stdin);
printf("Amount: ");
x = scanf("%f", &tmp.amount);
if(x == 0){
puts("Error, please try again!");
}
}
fflush(stdin);
x = 0;
while(x == 0){
printf("Unit: ");
gets(tmp.unit);
if(isalpha(*tmp.unit)){
x = 1;
}else{
x = 0;
puts("Error: please try again!\n");
}
}
printf("\n");
return tmp;
}
void print_grocerylist(Grocery* list, int* index){
int i;
system("cls");
printf("The grocery list contains:\n");
printf("Item Amount Unit");
for(i=0;i<*index;i++)
{
printf("\n%d: %-10s %5.1f %6s", list[i].iD, list[i].grocery, list[i].amount, list[i].unit);
}
printf("\n");
getch();
printf("Press any key to continue.\n");
}
void write_to_file(FILE* file_pointer, Grocery* list, int index){ //works just fine afaik.. Prints the index at the start, fills it up with all the rest.
char filename[30];
memset(filename, '\0', sizeof(filename));
printf("What is the name of the file you wish to write to?: ");
scanf("%s", filename);
strcat(filename, ".txt");
file_pointer = fopen(filename, "wb");
if(file_pointer == NULL){
printf("Error!");
return;
}else{
fflush(stdin);
printf("File opened successfully!\n");
fwrite(&index, sizeof(int), 1, file_pointer);
fwrite(list, sizeof(Grocery), index, file_pointer);
printf("File written.");
getch();
}
fclose(file_pointer);
return;
}
Grocery read_from_file(FILE* file_pointer, Grocery* list, int* index){ //Can't get this to work...
char filename[30];
memset(filename, '\0', sizeof(filename));
printf("What is the name of the file you wish to read from?: ");
scanf("%s", filename);
strcat(filename, ".txt");
file_pointer = fopen(filename, "rb");
if(file_pointer == NULL){
printf("Error!");
return *list;
}else{
fflush(stdin);
free(list);
printf("File opened successfully!\n");
fread(index, sizeof(int), 1, file_pointer);
printf("Index %d read.\n", *index);
list = (Grocery*)calloc(*index, sizeof(Grocery));
fread(list, sizeof(Grocery), (*index), file_pointer);
printf("File read.");
getch();
fflush(stdin);
}
fclose(file_pointer);
return *list;
}
void change_item(Grocery* list, int index){ //Basically it's a more complex version of "Grocery input()" were we look to the ID/index and alter the information.
int x = 0, id, item, choice;
print_grocerylist(list, &index);
printf("Which item would you like to change?\nID number: ");
scanf("%d", &id);
printf("\nWhat do you want to change?\n1 - Grocery.\n2 - Amount.\n3 - Unit.\nChoose: ");
scanf("%d", &choice);
switch(choice){
case 1:
fflush(stdin);
printf("Grocery: ");
for(item = 0; item <= index; item++){
if(list[item].iD == id){
gets(list[item].grocery);
}
}
break;
case 2:
while(x == 0){
fflush(stdin);
printf("Amount: ");
for(item = 0; item <= index; item++){
if(list[item].iD == id){
x = scanf("%f", &list[item].amount);
}
}
if(x == 0){
puts("Error, please try again!");
}
}
break;
case 3:
fflush(stdin);
x = 0;
printf("Unit: ");
for(item = 0; item <= index; item++){
if(list[item].iD == id){
gets(list[item].unit);
if(isalpha(*list[item-1].unit)){
x = 1;
}else{
x = 0;
puts("Error: please try again!\n");
}
}
}
break;
default:
printf("\nError! Please try again.\n");
break;
}
return;
}
void remove_item(Grocery* list, int* index){ //Takes the last struct and copies it to the slot which will be "removed" and then reallocates the memory for the array -1, keeping the old ID, to make things simple.
int item;
printf("Which item would you like to remove?\nID number: ");
scanf("%d", &item);
strcpy(list[item].grocery, list[*index].grocery);
list[item].amount = list[*index].amount;
strcpy(list[item].unit, list[*index].unit);
list = realloc(list, (*index-1)*sizeof(Grocery));
return ;
}

For the most part, the "Grocery read_from_file()" function works, but it returns only the first item instead of the list it correctly read.
To return and assign (a pointer to) the whole list, change the call
*list = read_from_file(file_pointer, list, &index);
to
list = read_from_file(file_pointer, list, &index);
and the definition
Grocery read_from_file(FILE* file_pointer, Grocery* list, int* index){
…
return *list;
…
return *list;
}
to
Grocery *read_from_file(FILE *file_pointer, Grocery *list, int *index)
{
…
return list;
…
return list;
}
To not leak the memory of the old list when it reads one from a file, insert free(list) before list = (Grocery*)calloc(*index, sizeof(Grocery)); or change that to
list = realloc(list, *index * sizeof(Grocery));

Related

Program not displaying anything after compiling in c

I made a C program to keep track of the distanced traveled by buses and hours worked by employees, both have ID as the primary key, these save on 2 different files. The code compiles but does not show anything, care to help? I used different sources for help with this code but I don't think that's the problem since a similar code runs well
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 100
int provbid;
int proveid;
int login();
void menu2();
void menu3();
void bus_mgm();
void emp_mgm();
typedef struct bus_data
{
int busid;
float distrav;
}bus;
typedef struct emp_data
{
int empid;
float hrswrkd;
}emp;
void addb(int*,bus[]);
void adde(int*,emp[]);
void viewb(int*,bus[]);
void viewe(int*,emp[]);
void updateb(int*,bus[]);
void updatee(int*,emp[]);
void deleteb(int*,bus[]);
void deletee(int*,emp[]);
int searchb(int,bus[]);
int searche(int,emp[]);
void readfileb(int*,bus[]);
void readfile(int*,emp[]);
void writefileb(int,bus[]);
void writefilee(int,emp[]);
int main(){
int el = 0;
emp eplist[SIZE];
readfile(&el, eplist);
int option1;
int p = 0;
p = login();
if (p==1){
printf("\nWelcome to 'Company Manager' user\n");
}
system("pause");
system("cls");
printf("Please slect an option:\n");
printf("1 for bus managment menu\n");
printf("2 For employee managment menu\n");
scanf("%d", &option1);
while (option1 != 3){
switch(option1){
case 1:
menu2();
break;
case 2:
menu3();
break;
default:
{
if (option1 != 3){
printf("/n Option is not supported.");
}
}
}
system("pause");
}
return 0;
}
int login(){
int pwd = 12345678;
int count = 0;
int pw;
while (count != 5){
printf("Please enetr password. \n");
scanf("%d",&pw);
if (pw == pwd){
printf("Password accepted");
return 1;
}
else{
printf("\n Wrong Password, try again.\n");
}
count++;
printf("You have done %d chances out of 5\n", count);
}
return 0;
}
void menu2(){
int choice;
int bl = 0;
bus bslist[SIZE];
readfileb(&bl, bslist);
printf("Welcome to the bus menu.\n");
printf("Please select an option:\n1: Add bus information\n2: View bus information\n 3: Update bus information\n 4: Delete bus information\n 5: Return to login menu\n ");
scanf("&d",choice);
switch (choice){
case 1:
addb(&bl, bslist);
case 2:
viewb(&bl, bslist);
case 3:
updateb(&bl, bslist);
case 4:
deleteb(&bl, bslist);
case 5:
main();
default:
printf("you have not selected a proper option");
}
}
void menu3(){
int choice;
int el = 0;
emp eplist [SIZE];
readfile(&el, eplist);
printf("Welcome to the Employee menu menu.\n");
printf("Please select an option:\n1: Add Employee information\n2: View Employee information\n 3: Update Employee information\n 4: Delete Employee information\n 5: Return to login menu ");
scanf("&d", choice);
switch (choice){
case 1:
adde(&el, eplist);
case 2:
viewe(&el, eplist);
case 3:
updatee(&el, eplist);
case 4:
deletee(&el, eplist);
case 5:
main();
default:
printf("you have not selected a proper option");
}
}
void addb(int *loc ,bus list[]){
printf("Add bus information");
int n = searchb( *loc, list);
if (n != -1){
printf("This ID is already being used.");
}
else
{
list[*loc].busid = provbid;
fflush(stdin);
printf("Please enter the total distance traveled, the number you have given will be accepted as km: ");
scanf("%f", &list[*loc].distrav);
*loc = *loc + 1;
}
}
void adde(int*loc ,emp list[]){
printf("Add Employee information");
int n = searche( *loc, list);
if (n != -1){
printf("This ID is already being used.");
}
else
{
list[*loc].empid = proveid;
fflush(stdin);
printf("Please enter the total hours worked: ");
scanf("%f", &list[*loc].hrswrkd);
*loc = *loc + 1;
}
}
void viewb(int *loc ,bus list[]){
int meh;
printf("Showing information of all buses.\n");
for(meh = 0; meh < *loc; meh++)
{
printf("Bus ID is: %d\n", list[meh].busid);
printf("Distance traveled is: %.1f\n", list[meh].distrav);
}
}
void viewe(int *loc,emp list[]){
int meh;
printf("Showing information of all Employess.\n");
for(meh = 0; meh < *loc; meh++)
{
printf("Employee ID is: %d\n", list[meh].empid);
printf("Hours worked are: %.1f\n", list[meh].hrswrkd);
}
}
void updateb(int *loc,bus list[]){
int tempbid;
printf("Update bus information");
tempbid = searchb(*loc, list);
if( tempbid== -1)
{
printf("This ID does not exist.\n");
}
else
{
printf("Enter new distanced traveled: ");
scanf("%f", &list[tempbid].distrav);
printf("Distance traveled has been updated. \a");
}
}
void updatee(int *loc ,emp list[]){
int tempeid;
printf("Update employee information");
tempeid = searche(*loc, list);
if( tempeid== -1)
{
printf("This ID does not exist.\n");
}
else
{
printf("Enter new hours worked: ");
scanf("%f", &list[tempeid].hrswrkd);
printf("Hours worked has been updated. \a");
}
}
void deleteb(int *loc, bus list[]){
int tempbid, meh;
printf("Delete bus info");
tempbid = searchb(*loc, list);
if(tempbid == -1)
{
printf("This ID does not exist.\n");
}
else
{
for(meh = tempbid; meh < *loc; meh++)
{
list[meh].busid = list[meh + 1].busid;
list[meh].distrav = list[meh + 1].distrav;
}
*loc = *loc - 1;
printf("Bus ID %d has been deleted.\n", tempbid);
}
}
void deletee(int *loc,emp list[]){
int tempeid, meh;
printf("Delete employee info");
tempeid = searche(*loc, list);
if(tempeid == -1)
{
printf("This ID does not exist.\n");
}
else
{
for(meh = tempeid; meh < *loc; meh++)
{
list[meh].empid = list[meh + 1].empid;
list[meh].hrswrkd = list[meh + 1].hrswrkd;
}
*loc = *loc - 1;
printf("Employee ID %d has been deleted.\n", tempeid);
}
}
int searchb(int loc, bus list[]){
int meh;
printf("Enter bus ID: ");
scanf("&d", provbid);
for(meh=0; meh<loc; meh++){
if(list[meh].busid == provbid)
return meh;
}
return -1;
}
int searche(int loc ,emp list[]){
int meh;
printf("Enter employee ID: ");
scanf("&d", proveid);
for(meh=0; meh<loc; meh++){
if(list[meh].empid == proveid)
return meh;
}
return -1;
}
void readfileb(int *loc, bus list[]){
FILE *bd;
bd = fopen("Bus Data.txt", "r");
if(bd != NULL)
{
while(!feof(bd))
{
fscanf(bd, "%d %f ", &list[*loc].busid, &list[*loc].distrav);
*loc = *loc + 1;
}
}
fclose(bd);
}
void readfile(int *loc, emp list[]){
FILE *ed;
ed = fopen("Employee Data.txt", "r");
if(loc != NULL)
{
while(!feof(ed))
{
fscanf(ed, "%d %f ", &list[*loc].empid, &list[*loc].hrswrkd);
*loc = *loc + 1;
}
}
fclose(ed);
}
Thank you for all your help, the first problem was with scanf which I did not see so thank you for pointing it out and the other is the first 3 lines of main, the int el = 0; emp eplist[SIZE];and readfile(&el, eplist); were not supposed to be in this function.

Process finished with exit code instead of returning back to main function

I am creating an grocery store system as an assignment in C for a class I put off until my senior year. It uses a linked list to keep track of products in the store. I have gotten it mostly working, but for some reason each time I select a menu option, it will run until it tries to access a NULL memory location (Process finished with exit code -1073741819 (0xC0000005)) and exit with some random memory location that it tried to access instead of returning back to the main function.
I have tested out several different while loop conditionals, all of which lead to the process being terminated as it seems like NULL is accessed even if the conditional isn't met.
The program has two classes, both of which are below. I am trying to focus on the "showList" function for now, as I feel like if I'm able to figure one out, then I can correct the rest of them.
showList() is called by option 4 on the menu.
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
void displayMenu()
{
puts("Welcome to the LinkedList grocery store.");
puts("Please let me know what you want to do by typing in one of the
numbers.");
puts("============================================================");
puts("1: Add product to store 2: Purchase product from store");
puts("3: Check price of a product 4: Show products in store");
puts("5: Remove a product from store 6: Find product");
puts("7: Inventory 8: Done for today");
}
int main(int argc, char *argv[])
{
product * head = NULL, *p;
char temp[N];
float sales = 0.0, quantity;
int choice, done = 0;
//system("cls");
head = load(head, "inventory.txt");
while (!done) {
displayMenu();
puts("What do you want to do?");
fflush(stdin);
scanf("%d", &choice);
fflush(stdin);
switch (choice)
{
case 1:
head = addProduct(head);
break;
case 2:
fflush(stdin);
printf("Please enter the name of a product: ");
fflush(stdin);
scanf("%s", temp);
fflush(stdin);
printf("Please enter the quantity: ");
fflush(stdin);
scanf("%f", &quantity);
fflush(stdin);
sales += purchase(head, temp, quantity);
break;
case 3:
fflush(stdin);
printf("Please enter the name of a product: ");
fflush(stdin);
scanf("%s", temp);
fflush(stdin);
checkPrice(head, temp);
break;
case 4:
showList(head);
break;
case 5:
fflush(stdin);
printf("Please enter the name of a product: ");
fflush(stdin);
scanf("%s", temp);
fflush(stdin);
rmItem(head, temp);
break;
case 6:
fflush(stdin);
printf("Please enter the name of a product: ");
fflush(stdin);
scanf("%s", temp);
fflush(stdin);
findProduct(head, temp);
break;
case 7:
puts("****INVENTORY****");
fflush(stdin);
printf("Total sales: %f\n", sales);
fflush(stdin);
display(head);
break;
case 8:
doneToday(head, "inventory.txt");
done = 1;
break;
default:
puts("Wrong code. Please try again.");
break;
}
}
return 0;
}
List.c:
#include "list.h"
// load in data from a file appending to the list l, return it
product * load(product *l, char fn[])
{
char name[N], quantity_unit[N], price_unit[N];
float quantity_value, price_value;
int rt;
product * head = l;
FILE * fin = fopen(fn, "r");
if(fin == NULL) {
printf("InLoad: File open failed (%s)\n", fn);
return NULL;
}
while (1) {
rt = fscanf(fin, "%s %f %s %f %s\n", name, &quantity_value,quantity_unit,
&price_value, price_unit );
if (rt < 5)
break;
if (head == NULL)
head = buildNode(name, quantity_value, quantity_unit, price_value,
price_unit);
else
append(head, buildNode(name, quantity_value, quantity_unit,
price_value, price_unit));
}
fclose(fin);
return head;
}
void doneToday(product* l, char fn[])
{
FILE * fout = fopen(fn, "w");
if(fout == NULL) {
printf("InSave: File open failed (%s)\n", fn);
return;
}
product* current = l;
while(current != NULL){
fprintf(fout, "%s %f %s %f %s\n", current->name, current-
>quantity_value,current->quantity_unit, current->price_value, current-
>price_unit);
current = current->next;
}
fclose(fout);
}
// build a product Node
product * buildNode(char name[], float quantity_value, char quantity_unit[],
float price_value, char price_unit[])
{
product * p = (product *) malloc(sizeof(product));
if(p == NULL) {
puts("InBuildNode: Memory Allocation Failed!");
return NULL;
}
strcpy(p->name, name);
p->quantity_value = quantity_value;
strcpy(p->quantity_unit, quantity_unit);
p-> price_value = price_value;
strcpy(p->price_unit, price_unit);
return p;
}
//shows the current product list
void showList(product *l)
{
product* cursor = l;
puts("************ Product List ******************");
printf("Name\tQuantity\tUnit\tPrice\t\tUnit\n\n");
while(cursor != NULL){
printf("%s\t%f\t%s\t%f\t%s\n", cursor->name, cursor->quantity_value,
cursor->quantity_unit, cursor->price_value, cursor->price_unit);
cursor = cursor->next;
}
}
//adds a product to the list if it's not already
product * addProduct(product* l)
{
product* cursor = l;
product* result = l;
char name[N];
float quantity_value;
char quantity_unit[N];
float price_value;
char price_unit[N];
puts("Please enter the name of a product: ");
scanf("%s", name);
puts("Please enter the quantity value of a product: ");
scanf("%f", &quantity_value);
puts("Please enter the quantity unit of a product: ");
scanf("%s", quantity_unit);
puts("Please enter the price value of a product: ");
scanf("%f", &price_value);
puts("Please enter the price unit of a product: ");
scanf("%s", price_unit);
while(cursor != NULL){
if(name == cursor->name){
cursor->quantity_value += quantity_value;
printf("The product with name **%s** already exists.", name);
printf("The quantity was updated. New quantity is: %f", cursor-
>quantity_value);
return result;
}
cursor = cursor->next;
}
if(!cursor){
result = append(l, buildNode(name, quantity_value, quantity_unit,
price_value, price_unit));
puts("New product added successfully!");
}
return result;
}
product * append(product *l, product * p)
{
product* cursor = l;
if(cursor == NULL){
return p;
} else {
while(cursor->next != NULL){
cursor = cursor->next;
}
cursor->next = p;
return l;
}
}
void checkPrice(product* l, char p[])
{
product* cursor = l;
while(cursor->next != NULL){
if(strcmp(cursor->name, p) == 0 ){
printf("The current price of %s is %f %s", p, cursor->price_value,
cursor->price_unit);
}
cursor = cursor->next;
}
}
void findProduct(product* l, char p[])
{
product* cursor = l;
while(cursor->next != NULL){
if(strcmp(cursor->name, p) == 0){
printf("Product Found: %s %f %s %f %s", cursor->name, cursor-
>quantity_value, cursor->quantity_unit, cursor->price_value, cursor-
>price_unit);
return;
}
cursor = cursor->next;
}
printf("The requested product was not found.");
}
void display(product *l)
{
product* cursor = l;
printf("Product: \n");
while(cursor){
printf("%s %f %s %f %s\n", cursor->name, cursor->quantity_value,
cursor->quantity_unit, cursor->price_value, cursor->price_unit);
cursor = cursor->next;
}
}
float purchase(product* l, char p[], float q){
product* cursor = l;
float dollars = 0.0;
while(cursor->next != NULL){
if(strcmp(cursor->name, p) == 0){
if(cursor->quantity_value > q){
dollars = cursor->price_value * q;
cursor->quantity_value -= q;
printf("Sale Completed, dollars made: %f\n", dollars);
return dollars;
} else if(cursor->quantity_value < q){
dollars = cursor->price_value * cursor->quantity_value;
printf("Sale partially completed, dollars made: %f\n", dollars);
rmItem(l, cursor);
return dollars;
}
}
}
printf("The sale was not completed, maybe the product doesn't exist.");
return dollars;
}
void rmItem(product* l, char p[])
{
product * current = l;
product * previous = current;
while(current != NULL) {
if (strcmp(current->name, p) == 0) {
if(previous == current) // the first node
l = (current->next);
else // not the first one
previous->next = current->next;
free (current);
return;
}
previous = current;
current = current->next;
}
}
list.h:
#ifndef PROJECT3_LIST_H
#define PROJECT3_LIST_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 20
struct product
{
char name[N];
float quantity_value;
char quantity_unit[N];
float price_value;
char price_unit[N];
struct product *next;
};
typedef struct product product;
product * load(product *l, char fn[]);
product * buildNode(char name[], float quantity_value, char quantity_unit[],
float price_value, char price_unit[]);
void showList(product *l);
product * addProduct(product* l);
product * append(product *l, product * p);
void checkPrice(product* l, char p[]);
void findProduct(product* l, char p[]);
void display(product *l);
float purchase(product* l, char product[], float q);
void rmItem(product* l, char p[]);
void doneToday(product* l, char fn[]);
#endif //PROJECT3_LIST_H

How would I go about saving and reading an integer then a struct array in the same .dat file? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Basicly, I have a counter that I need to save and read as an integer as the first thing in a data file while in the same data file save a struct array. I don't want to post my entire code as its a bit too long but below are the functions that I have written so far.
void write(InventoryItemType *writefile[], int count)
{
int i;
FILE *ptr;
ptr=fopen("inventory.dat","wb");
if(ptr==NULL)
{
printf("Unable to Open File\n");
system("pause");
return;
}
putw(count, ptr);
for(i=0;i < count; i++)
{
fwrite(&writefile[i], sizeof writefile, 1, ptr);
}
fclose(ptr);
}
InventoryItemType *read(InventoryItemType *readfile[])
{
int i, count;
FILE *ptr;
ptr=fopen("inventory.dat","wb");
if(!ptr)
{
printf("Unable to Open File\n");
system("pause");
return;
}
count=getcount();
for(i=0;i < count; i++)
{
fread(&readfile[i], sizeof readfile, 1, ptr);
}
fclose(ptr);
return *readfile;
}
int getcount(void)
{
int i;
FILE *ptr;
ptr=fopen("inventory.dat","wb");
if(ptr<=0)
{
i=0;
return i;
}
i=getw(ptr);
fclose(ptr);
return i;
}
I call the functions in the main block like so:
At the top of code for file reading:
int i=0, item_count=getcount();
char selection, code[4];
InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE];
*inventoryItems=read(inventoryItems);
And at the exit statements like so:
write(inventoryItems, item_count);
break;
I am relatively new to this concept so any help would be appreciated.
memmory allocation edit:
InventoryItemType *addItem(void)
{
InventoryItemType *current = (InventoryItemType*) malloc (sizeof *current);
system("cls");
if(current == NULL)
return NULL;
....
system("cls");
return current;
}
EDIT #2: I tried my best to implement your suggestions. Currently, I get a value of -1 for count. Here is the updated code:
Calling Functions for Reading:
int i=0, item_count=getcount();
char selection, code[4];
InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE];
reader(inventoryItems);
Calling Function for writing:
case 'A' :
writer(inventoryItems, item_count);
break;
Reading Functions:
void reader(InventoryItemType *readfile[])
{
int i, count;
FILE *ptr;
ptr=fopen("inventory.dat","rb");
if(!ptr)
{
printf("Unable to Open File\n");
system("pause");
return;
}
count=getcount();
for(i=0;i < count; i++)
{
fread(&readfile[i], sizeof (InventoryItemType), 1, ptr);
}
fclose(ptr);
return;
}
int getcount(void)
{
int i;
FILE *ptr;
ptr=fopen("inventory.dat","rb");
if(ptr==NULL)
{
i=0;
return i;
}
i=getw(ptr);
return i;
}
Writing Functions:
void writer(InventoryItemType *writefile[], int count)
{
int i;
FILE *ptr;
ptr=fopen("inventory.dat","wb");
if(ptr==NULL)
{
printf("Unable to Open File\n");
system("pause");
return;
}
putw(count, ptr);
for(i=0;i < count; i++)
{
fwrite(&writefile[i], sizeof (InventoryItemType), 1, ptr);
}
}
EDIT #3: Entire code just.. frustration setting in Q_Q
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_INVENTORY_SIZE 100
typedef struct {
char item_Number[4];
char item_Name[20];
float item_Profit;
float latest_Price;
float selling_Price;
unsigned int stock;
unsigned int total_Sold;
}InventoryItemType;
void MainMenu();
void displayInventory(InventoryItemType *[], int);
void displaySales(InventoryItemType *[], int);
InventoryItemType *addItem(void);
InventoryItemType *deleteItem(InventoryItemType *[], int);
InventoryItemType *newShipment(InventoryItemType *[], int);
InventoryItemType *updateSales(InventoryItemType *[], int);
InventoryItemType *bubbleSort(InventoryItemType *[], int, char);
void swap(InventoryItemType *[], InventoryItemType *[]);
void writer(const char *,InventoryItemType *[], size_t );
void reader(const char *,InventoryItemType *[], size_t );
int main()
{
int i=0, item_count=0;
char selection, code[4];
const char file[]={"inventory.dat"};
InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE];
reader(file,inventoryItems,item_count);
while(1)
{
MainMenu();
scanf(" %c", &selection);
switch(selection)
{
case 'A' :
displayInventory(inventoryItems, item_count);
system("pause");
system("cls");
continue;
case 'B' :
displaySales(inventoryItems, item_count);
system("pause");
system("cls");
continue;
case 'C' :
if(item_count == MAX_INVENTORY_SIZE - 1)
{
printf("Array is full\n");
system("pause");
continue;
}
inventoryItems[item_count] = addItem();
item_count++;
continue;
case 'D' :
*inventoryItems=deleteItem(inventoryItems, item_count);
item_count--;
continue;
case 'E' :
*inventoryItems=newShipment(inventoryItems, item_count);
continue;
case 'F' :
*inventoryItems=updateSales(inventoryItems, item_count);
continue;
case 'G' :
while(1)
{
system("cls");
printf("A. Sort by Name\n");
printf("B. Sort by Item Number\n");
scanf(" %c", &selection);
switch(selection)
{
case 'A' :
*inventoryItems=bubbleSort(inventoryItems, item_count, selection);
break;
case 'B' :
*inventoryItems=bubbleSort(inventoryItems, item_count, selection);
break;
default:
{
printf("Invalid Input!\n");
system("pause");
continue;
}
}
break;
}
continue;
case 'H' :
while(1)
{
printf("Would you like to save your changed?\n");
printf("A. Yes\n");
printf("B. No\n");
scanf(" %C", &selection);
switch(selection)
{
case 'A' :
writer(file,inventoryItems,item_count);
break;
case 'B' :
break;
default:
{
printf("Invalid Input!\n");
system("pause");
continue;
}
}
break;
}
continue;
default :
printf("Invalid Entry\n" );
system("pause");
}
}
}
void MainMenu()
{
system("cls");
printf("A. Display Inventory\n");
printf("B. Display Sales\n");
printf("C. Add Item\n");
printf("D. Remove Item\n");
printf("E. Enter Shipment\n");
printf("F. Update Sales\n");
printf("G. Sort\n");
printf("H. Exit\n");
printf("Make a selection\n");
}
void displayInventory(InventoryItemType *display[], int key)
{
system("cls");
{
int i;
for(i=0; i<key; i++)
{
printf("Item No.:%s\n", display[i]->item_Number);
printf("Item Name:%s\n", display[i]->item_Name);
printf("Item Stock:%d\n",display[i]->stock);
printf("Item Purchased Price:%.2f\n", display[i]->latest_Price);
printf("Total Value of Items:%.2f\n", (display[i]->stock)*(display[i]->latest_Price));
printf("\n");
}
}
}
void displaySales(InventoryItemType *display[], int key)
{
int i;
float total_profit=0;
system("cls");
for(i=0; i<key; i++)
{
printf("Item No.:%s\n", display[i]->item_Number);
printf("Item Name:%s\n", display[i]->item_Name);
printf("Number of Item Sold:%d\n", display[i]->total_Sold);
printf("Item Selling Price:%.2f\n", display[i]->selling_Price);
printf("Total Profit from Item:%.2f\n", (display[i]->selling_Price-display[i]->latest_Price)*display[i]->total_Sold);
total_profit=total_profit+((display[i]->selling_Price-display[i]->latest_Price)*display[i]->total_Sold);
if(i==key-1)
printf("\nTotal Over-all Profit:%.2f", total_profit);
printf("\n\n");
}
}
InventoryItemType *addItem(void)
{
InventoryItemType *current = (InventoryItemType*) malloc (sizeof *current);
system("cls");
if(current == NULL)
return NULL;
printf("\nEnter details of item \n\n");
printf("Enter Item no: \n");
scanf("%s", current->item_Number);
printf("Enter Item Name: \n");
scanf("%s", current->item_Name);
printf("Enter Stock: \n");
scanf("%d", &current->stock);
printf("Enter Purchase Price: \n");
scanf("%f", &current->latest_Price);
current->selling_Price=(current->latest_Price)*1.5;
current->total_Sold=0;
system("cls");
return current;
}
InventoryItemType *deleteItem (InventoryItemType *deleted[], int item_count)
{
char code[4];
int i;
system("cls");
displayInventory(deleted,item_count);
printf("Enter Item Number to be Deleted\n");
scanf("%3s", code);
for(i=0;i<item_count;i++)
{
if(strcmp(code,deleted[i]->item_Number)==0)
break;
}
free(deleted[i]);
for(;i<item_count; i++)
deleted[i]=deleted[i+1];
return *deleted;
}
InventoryItemType *newShipment (InventoryItemType *shipment[], int item_count)
{
char code[4];
int i, add;
float newprice;
while(1)
{
system("cls");
displayInventory(shipment, item_count);
printf("\nEnter Item Number to Update Stock\n");
scanf("%3s", code);
for(i=0;i<item_count;i++)
{
if(strcmp(code,shipment[i]->item_Number)==0)
{
printf("Enter the Quantity of Item being added\n");
scanf("%d", &add);
printf("Enter the Purchase Price of the Item\n");
scanf("%f", &newprice);
shipment[i]->stock=shipment[i]->stock+add;
shipment[i]->latest_Price=newprice;
shipment[i]->selling_Price=shipment[i]->latest_Price*1.5;
displayInventory(shipment, item_count);
return *shipment;
}
}
printf("Invalid Item Number, Please Try Again\n");
system("Pause");
continue;
}
}
InventoryItemType *updateSales (InventoryItemType *sale[], int item_count)
{
char code[4], choice;
int i, sold;
while(1)
{
system("cls");
displayInventory(sale, item_count);
printf("\nEnter Item Number to Update Stock and Profits\n");
scanf("%3s", code);
for(i=0;i<item_count;i++)
{
if(strcmp(code,sale[i]->item_Number)==0)
{
printf("Enter the Quantity of Item Sold\n");
scanf("%d", &sold);
if(sale[i]->stock>sold)
{
sale[i]->stock=sale[i]->stock-sold;
sale[i]->item_Profit=sale[i]->selling_Price*sold;
displayInventory(sale, item_count);
system("pause");
return *sale;
}
else
{
printf("Invalid Input!\nThere can not be more sold than in stock!\nWould you like to try again?\n");
printf("A. Yes\n");
printf("B. No\n");
scanf(" %c", &choice);
switch(choice)
{
case 'A' :
system("cls");
displayInventory(sale, item_count);
continue;
case 'B' :
return *sale;
}
}
}
else
{
printf("Invalid Item Number, Please Try Again\n");
system("Pause");
}
}
}
}
void swap(InventoryItemType *a[], InventoryItemType *b[])
{
InventoryItemType *temp=*a;
*a=*b;
*b=temp;
}
InventoryItemType *bubbleSort(InventoryItemType *sorting[], int item_count, char swaptype)
{
int i, sorted;
system("cls");
if(swaptype=='A')
{
do{
sorted=1;
for (i = 0; i < item_count - 1; i++)
{
if (strcmp(sorting[i]->item_Name,sorting[i + 1]->item_Name)==1)
{
swap(&sorting[i],&sorting[i + 1]);
sorted = 0;
}
}
}while(!sorted);
}
else
{
do{
sorted=1;
for (i = 0; i < item_count - 1; i++)
{
if (strcmp(sorting[i]->item_Number,sorting[i + 1]->item_Number)==1)
{
swap(&sorting[i],&sorting[i + 1]);
sorted = 0;
}
}
}while(!sorted);
}
printf("Your Inventory is Sorted!\n\n");
system("pause");
return *sorting;
}
void writer(const char *fname,const InventoryItemType *saveinventory , size_t count)
{
FILE *ptr = fopen(fname, "wb");
if(ptr == NULL)
{
fclose(ptr);
printf("Unable to Open File\n");
system("pause");
return;
}
if (fwrite(&count, sizeof(count), 1, ptr)!= 1)
{
fclose(ptr);
printf("Write count failed\n");
system("pause");
return;
}
if (fwrite(saveinventory, sizeof (*saveinventory), count, ptr)!= count)
{
fclose(ptr);
printf("Write inventory failed\n");
system("pause");
}
}
void reader(const char *fname,InventoryItemType **inventory_ptr, size_t *count_ptr)
{
InventoryItemType *inventory;
size_t count;
FILE *ptr = fopen(fname, "rb");
if(ptr == NULL) {
printf("Unable to Open File\n");
system("pause");
return;
}
if (fread(&count, sizeof count, 1, ptr)!= 1) {
fclose(ptr);
printf("Read count failed\n");
system("pause");
return;
}
inventory = (InventoryItemType *)malloc(sizeof *inventory * count);
if (inventory == NULL && count > 0) {
fclose(ptr);
printf("Allocation failed\n");
system("pause");
return;
}
if (fread(inventory, sizeof *inventory, count, ptr)!= count) {
fclose(ptr);
free(inventory);
printf("Read inventory failed\n");
system("pause");
return;
}
fclose(ptr);
*inventory_ptr = inventory;
*count_ptr = count;
return;
}
How would I go about saving and reading an integer then a struct array in the same .dat file?
I suggest an architecture change. Rather than
// void write(InventoryItemType *writefile[], int count)
// InventoryItemType *read(InventoryItemType *readfile[])
Consider
// return 0 on success
int iwrite(const char *fname, const InventoryItemType *inventory, size_t count)
int iread(const char *fname, InventoryItemType **inventory, size_t *count)
I found OP's approach too tangled.
To write, open the file, write the count and data. Recall the inventory is still allocated and eventually needs to be freed.
int iwrite(const char *fname, const InventoryItemType *inventory, size_t count) {
FILE *ptr = fopen(fname, "wb");
if(ptr == NULL) {
// printf("Unable to Open File\n");
return 1;
}
if (fwrite(&count, sizeof count, 1, ptr)!= 1) {
fclose(ptr);
// printf("Write count failed\n");
return 2;
}
if (fwrite(inventory, sizeof *inventory, count, ptr)!= count) {
fclose(ptr);
// printf("Write inventory failed\n");
return 3;
}
fclose(ptr);
return 0;
}
To write, open the file, read the count, allocate memory for the inventory and then read the inventory.
int iread(const char *fname, InventoryItemType **inventory_ptr, size_t *count_ptr) {
FILE *ptr = fopen(fname, "rb"); // read mode
if(ptr == NULL) {
// printf("Unable to Open File\n");
return 1;
}
size_t count;
if (fread(&count, sizeof count, 1, ptr)!= 1) {
fclose(ptr);
// printf("Read count failed\n");
return 2;
}
InventoryItemType *inventory = malloc(sizeof *inventory * count);
if (inventory == NULL && count > 0) {
fclose(ptr);
// printf("allocation failed\n");
return 3;
}
if (fread(inventory, sizeof *inventory, count, ptr)!= count) {
fclose(ptr);
free(inventory);
// printf("Read inventory failed\n");
return 3;
}
fclose(ptr);
*inventory_ptr = inventory;
*count_ptr = count;
return 0;
}
Thee are a number of problems in your code:
InventoryItemType *inventoryItems[MAX_INVENTORY_SIZE];
*inventoryItems=read(inventoryItems);
You declare an array of pointers to items and then you read the items. But in the code for reading the items, I do not see you allocate memory for the items. Then, when the function returns, you assign the returned result to *inventoryItems, that is you dereference the array and so have its first element. This seems like nonsense and you compiler should have complained. Do not return any thing from the function, except success/failure.
And note that read is the name of a function from the standard library. Use another name. Also for write.
When yu open the file, you specify "wb" but that means you open the file for writing. That should be "rb" (read binary).
In the read function, you read sizeof readfile bytes. But readfile is a pointer to an array of pointers. So sizeof readfile will be the size of a pointer. You should use sizeof *readfile[i] or sizeof(InventoryItemType).
But before you read anything into readfile[i], you should allocate memory for it! And note that readfile[i] is already a pointer, so you don't need the & operator in fread and fwrite.
As an example of what it should be, I provide the read function:
int myread(InventoryItemType *readfile)
{
int i, count;
FILE *ptr;
ptr=fopen("inventory.dat","rb"); // "rb" = Read Binary
if(!ptr)
{
printf("Unable to Open File\n");
system("pause");
return 0;
}
count=getcount();
for(i=0;i < count; i++)
{
readfile[i]= malloc(sizeof(InventoryItemType));
fread(readfile[i], sizeof(InventoryItemType), 1, ptr);
}
fclose(ptr);
return 1;
}
..and turn warnings of your compiler on!

Program doesnt write to file and crashes when loading

So i need to write and read to and from a binary file, but cant seem to do it, and when using readFromFile, the program crashes. I need help write to binary file, and then reading from it and resuming my work later after turning off the program.I have no idea what i am doing wrong, and i have googled for a long time now, but with no results. Here is the code of my program:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char *subjName;
char *lectName;
char *lectSurname;
int credits;
int num_students;
}Subject;
typedef struct{
Subject **subjs;
int num_subjs;
}Subjects;
int numOfSubjs=0;
void listInput();
void listEdit();
void listDelete();
void listPrint();
int userChoice(int select);
int enterNumber(char *name);
void saveToFile(Subjects *subjects);
void readFromFile(Subjects *subjects);
int main() {
Subjects *subjects = malloc(sizeof(Subjects));
subjects->num_subjs = 0;
subjects->subjs = NULL;
readFromFile(subjects);
int r=1;
while(r!=0){
int select=userChoice(select);
switch(select){
case 1:
listPrint(subjects);
break;
case 2:
listInput(&subjects);
break;
case 3:
listDelete(subjects);
break;
case 4:
listEdit(subjects);
break;
case 0:
r=0;
break;
}
}
saveToFile(subjects);
return 0;
}
int userChoice(int select){ // menu options
int choice,input=0;
printf("(1). View all the data\n");
printf("(2). Enter new data\n");
printf("(3). Delete data\n");
printf("(4). Edit data\n");
printf("(0). Exit\n");
printf("-----------------------------\n");
while(input!=1){
choice = enterNumber("menu");
if(choice>4 || choice<0){
printf("Invalid input \n");
}
else
input = 1;
}
return choice;
}
void listPrint(Subjects *subjects){ // print data
int i;
for(i=0; i< numOfSubjs; i++){
printf("%d, %s, %s, %s, %d, %d\n",i+1, subjects->subjs[i]->subjName, subjects->subjs[i]->lectName, subjects->subjs[i]->lectSurname, subjects->subjs[i]->credits, subjects->subjs[i]->num_students);
}
printf("Number of entries: %d \n", numOfSubjs);
}
char *getln() //dynamically allocate input string
{
char *line = NULL, *tmp = NULL;
size_t size = 0, index = 0;
int ch = 1;
while (ch) {
ch = getc(stdin);
if (ch == '\n')
ch = 0;
if (size <= index) {
size += 1;
tmp = realloc(line, size);
if (!tmp) {
free(line);
line = NULL;
break;
}
line = tmp;
}
line[index++] = ch;
}
return line;
}
void saveToFile(Subjects *subjects){
FILE *data;
data = fopen("data.bin","wb");
printf("%s", subjects->subjs[0]);
for(int i=0; i<numOfSubjs; i++){
fwrite(&subjects->subjs[i],sizeof(Subject*),1,data);
}
fclose(data);
}
void readFromFile(Subjects *subjects){
FILE *data;
int i=0;
data = fopen("data.bin","rb");
while(!feof(data))
{
fread(&subjects->subjs[i],sizeof(Subject*),1,data);
i++;
}
fclose(data);
}
int isText(char *str,char *name){ // check if is text
for(int i = 0; i < strlen(str);i++){
if((str[i]<'A' || str[i]>'z') && str[i]!=' '){
printf("Error, %s must be a text \n",name);
return 0;
}
}
return 1;
}
int enterNumber(char *name){ // enter number and check if is number
int input=0, crash=0, num=0;
while(input!=1)
{
crash=0;
printf("Enter the number of %s\n", name);
scanf("%d", &num);
while(getchar()!='\n')
{
crash++;
}
if(crash>0 || num<0)
printf("Error, enter a not negative number of %s\n", name);
else if(crash==0)
input=1;
}
return num;
}
void listInput(Subjects **p_subjects){ // input new data
Subject *new_subj = malloc(sizeof(Subject));
new_subj->subjName = NULL;
new_subj->lectName = NULL;
new_subj->lectSurname = NULL;
new_subj->credits = 0;
new_subj->num_students = 0;
do{
printf("Enter the name of the subject \n");
new_subj->subjName = getln();
}while(!isText(new_subj->subjName,"Subject name"));
do{
printf("Enter the name of the lecturer \n");
new_subj->lectName = getln();
new_subj->lectName[0] &= '_';
}while(!isText(new_subj->lectName,"Lecturer's name"));
do{
printf("Enter the surname of the lecturer\n");
new_subj->lectSurname = getln();
new_subj->lectSurname[0] &= '_'; //Convert to uppercase if lowercase
}while(!isText(new_subj->lectSurname,"Lecturer's name"));
new_subj->credits = enterNumber("credits");
new_subj->num_students = enterNumber("students");
(*p_subjects)->subjs = realloc((*p_subjects)->subjs,sizeof(Subject*)*(++(*p_subjects)->num_subjs));
(*p_subjects)->subjs[(*p_subjects)->num_subjs-1] = new_subj;
numOfSubjs++;
printf("Added a new entry.\n\n");
}
void listDelete(Subjects *subjects){ // delete entries
int del;
if(numOfSubjs==0)
printf("Number of entries is 0, can't delete anything\n");
else{
printf("Enter 0 to exit. Number of subjects : %d \n", numOfSubjs);
while(1){
del = enterNumber("entry which you would like to delete");
if(del<=numOfSubjs && del>0){
for(int i = del-1; i<numOfSubjs-1; i++){
subjects->subjs[i]=subjects->subjs[i+1];
subjects->subjs = realloc(subjects->subjs,sizeof(Subject*)*(--subjects->num_subjs));
}
numOfSubjs--;
break;
}
if(del>numOfSubjs)
printf("Error, input a number between 1 and %d (or enter 0 to exit)\n", numOfSubjs);
else
break;
}
}
}
void listEdit(Subjects *subjects){ // edit entries
int choice=0, editEntry=0, editSubj=0;
if(numOfSubjs == 0)
printf("Number of entries is 0, can't edit anthing\n");
else{
while(1){
printf("Number of entry must be between 1 and %d \n", numOfSubjs);
choice = enterNumber("entry you would like to edit.");
if(choice>0 && choice<=numOfSubjs){
while(1){
editEntry = enterNumber("what would you like to edit\n 1 - Subject name\n 2 - Lecturer's name\n 3 - Lecturer's surname\n 4 - Number of credits\n 5 - Number of students");
if(editEntry>0 && editEntry <=5){
switch(editEntry){
case 1:
do{
printf("Enter the name of the subject \n");
subjects->subjs[choice-1]->subjName = getln();
}while(!isText(subjects->subjs[choice-1]->subjName,"Subject name"));
break;
case 2:
do{
printf("Enter Lecturer's name \n");
subjects->subjs[choice-1]->lectName = getln();
}while(!isText(subjects->subjs[choice-1]->lectName,"Lecturer's name"));
break;
case 3:
do{
printf("Enter Lecturer's surname \n");
subjects->subjs[choice-1]->lectSurname = getln();
}while(!isText(subjects->subjs[choice-1]->lectSurname,"Lecturer's surname"));
break;
case 4:
subjects->subjs[choice-1]->credits = enterNumber("credits");
break;
case 5:
subjects->subjs[choice-1]->num_students = enterNumber("students");
break;
}
}
break;
}
}
break;
}
}
}
&subjects->subjs[i], This is Undefined behavior. Accessing garbage value. You need to properly initialize it proper memory address. You ddin't do it anywhere.
(*subjects).subjs or subjects->subjs -> This is not pointing anywhere. It is NULL.
Also here you don't need the double pointer. A single pointer would do the thing you want to do.
typedef struct{
Subject *subjs;
int num_subjs;
}Subjects;
For single pointer this would be like
Subjects *subjects = malloc(sizeof(Subjects));
subjects->num_subjs = 10;
subjects->subjs = malloc(subjects->num_subjs * sizeof Subject);
subjects->subjs[0].subjName = malloc(40);
Each of the malloc should be checked with it's return Value. If it's NULL then it would be error to proceed further or access it.
And free() it accordingly when you are done working with it.
Some basic things:-
typedef struct{
Subject *subjs;
int num_subjs;
}Subjects;
Now let's look a bit in the code.
Op asked why OP should initialize and isn;t subjects->num_subjs = 0;
subjects->subjs = NULL; not enough?
A pointer is a variable that is supposed to hold address. here Subject* will hold the address of the variables of type Subject.
Now here initially you initialized it.
You have allocated a memory and assigned it's address to the Subject* variable subjects.
Now let's see what else you do.
subjects->num_subjs = 0;
subjects->subjs = NULL;
You initialized it. And then you try to access it(subjects->subjs[i]). Can you tell me where it points to? (subject->subjs)?
Answer is nope. It is pointing to nowhere. It contains NULL value now. Don't you think you should tell it how many subject you want to hold and allocate accordingly? Yes you should and that's what I did precisely in the example shown.
Whenever you have a pointer variable ask yourself what it contains - and if the value is something you know about, not some random garbage value.

C programming why is junk printing before the value?

I am making a linked list of objects. For some reason when i go to print the value of a value within the object (a char array) i'm getting junk printing before the value. Why is this happening and how do i get rid of it? Here is a part of my code:
int num = 0;
int input = 1;
int retval = 0;
struct PDB2 *llist;
char avalue[100] = "";
llist = (struct PDB2 *)malloc(sizeof(struct PDB2));
llist->data1[100] = NULL;
llist->next = NULL;
while(input != 0) {
printf("\n-- Menu Selection --\n");
printf("0) Quit\n");
printf("1) Insert\n");
printf("2) Delete\n");
printf("3) Search\n");
printf("4) Display\n");
scanf("%d", &input);
switch(input) {
case 0:
default:
printf("Goodbye ...\n");
input = 0;
break;
case 1:
printf("Your choice: `Insertion'\n");
printf("Enter the value which should be inserted: ");
scanf("%s", &avalue);
append_node(llist, avalue);
break;
case 2:
printf("Your choice: `Deletion'\n");
printf("Enter the value which should be deleted: ");
scanf("%s", &avalue);
delete_node(llist, avalue);
break;
case 3:
printf("Your choice: `Search'\n");
printf("Enter the value you want to find: ");
scanf("%s", &avalue);
if((retval = search_value(llist, avalue)) == -1)
printf("Value `%s' not found\n", avalue);
else
printf("Value `%s' located at position `%d'\n", avalue, retval);
break;
case 4:
printf("You choice: `Display'\n");
display_list(llist);
break;
} /* switch */
} /* while */
free(llist);
return(0);
}
void append_node(struct PDB2 *llist, char message[])
{
int x = 0;
while(llist->next != NULL)
{
llist = llist->next;
}
llist->next = (struct PDB2 *)malloc(sizeof(struct PDB2));
for(x = 0; x < 100; x++)
{
llist->next->data1[x] = message[x];
}
llist->next->next = NULL;
}
void display_list(struct PDB2 *llist)
{
while(llist->data1 == NULL)
{
llist = llist->next;
}
while(llist->next != NULL)
{
printf("%s ", llist->data1);
llist = llist->next;
}
printf("%s", llist->data1);
}
The char array in your initial node is uninitialized. Change
llist->data1[100] = NULL;
to
llist->data1[0] = '\0';
to stop it from being printed.
These two lines, together, are wrong:
char avalue[100] = "";
[...]
scanf("%s", &avalue);
The proper way to scanf a string is:
scanf("%s", avalue); // No Address-Of operator.
The important part of your code (based on your description of the problem) can be boiled down to this:
struct PDB2 {
char data[100];
...other fields...
};
struct PDB2 * llist = (struct PDB2 *)(malloc(sizeof(struct PDB2)));
llist->data[100] = NULL; /* This is wrong */
printf("%s", llist->data); /* This prints rubbish */
The marked line is wrong because:
NULL is meant to be used as a pointer value, not as a character. You probably mean to use '\0'.
The point seems to be to clear the string, so the correct method is
.
llist->data[0] = '\0';
Also, the call to scanf seems that it should be
char avalue[100];
scanf("%s", avalue);
since avalue is already of type char *. With the extra & you may be writing to an invalid location. However,
int input;
scanf("%d", &input);
is correct for integer input.

Resources