Reading a text file to a doubly linked list - c

I'm coding a contact manager using a doubly linked list that is manipulated by functions using pointers that reads in a contactList.txt.
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>
#include<stdlib.h>
#include<dos.h>
//functions
listelement * getFirst(listelement *listpointer,string query[MAX]);
void getLast();
void getEmail();
void getCompany();
void getNumber();
void editCon();
void delCon();
void addCon();
void listAll();
void sortCon();
void Menu (int *choice);
#define MAX 20
//struct to order contactList
struct contact
{
string firstName[MAX],lastName[MAX],email[MAX],companyName[MAX];
long phoneNum[MAX];
struct listelement *link
struct contact *next;
struct contact *prev;
}list;
int main()
{
listelement listmember, *listpointer;
string query;int iChoice = 0;
listpointer = NULL;
Menu (&iChoice);
int iChoice;
fflush(stdin);
scanf_s("%d", &iChoice);
// user enters one of 9 values
// options are as follows: get first name,last name,list all contacts,search through contacts,add a new contact,edit/delete or sort contacts.
switch(iChoice)
{
case 1:
{
printf ("Enter contact first name to get details ");
scanf ("%d", &query);
listpointer = getFirst (listpointer, query);
break;
}
case 2:
{
getLast();
break;
}
case 3:
{
listAll();
break;
}
case 4:
{
getEmail();
break;
}
case 5:
{
getCompany();
break;
}
case 6:
{
getNumber();
break;
}
case 7:
{
addCon();
break;
}
case 8:
{
editCon();
break;
}
case 9:
{
delCon();
break;
}
case 10:
{
sortCon();
break;
}
case 11: // exit
{
printf("\n\nProgram exiting!...");
exit(0);//terminates program
break;
}
default:
printf ("Invalid menu choice - try again\n");
break;
}//end of switch
return(iChoice);
}//end of main
//menu function to test if invalid input was entered in a menu choice.
void Menu (int *iChoice)
{
char local;
system("cls");
printf("\n\n\t\\n\n");
printf("\n\n\t\tWelcome to my Contact Manager\n\n");
printf("\n\t\t1. First name");
printf("\n\t\t2. Last name");
printf("\n\t\t3. List all contacts");
printf("\n\t\t4. Search email");
printf("\n\t\t5. Search company name");
printf("\n\t\t6. Search number");
printf("\n\t\t7. Add contact");
printf("\n\t\t8. Edit contact");
printf("\n\t\t9. Delete contact");
printf("\n\t\t10. Sort contacts");
printf("\n\t\t11. Exit");
printf("\n\n\t\tEnter your menu choice: ");
do
{
local = getchar ();
if ( (isdigit(local) == FALSE) && (local != '\n') )
{
printf ("\nYou must enter an integer.\n");
printf ("");
}
} while (isdigit ((unsigned char) local) == FALSE);
*iChoice = (int) local - '0';
}
//function to get a contact by entering first name
listelement * getFirst (listelement *listpointer, string query)
{
//variables
char query[MAX],firstName[MAX];
FILE *fp, *ft;
int i,n,ch,l,found;
system("cls");
do
{
found=0;
l=strlen(query);
fp=fopen("ContactList.txt","r");
system("cls");
printf("\n\n..::Search result for '%s' \n===================================================\n",query);
while(fread(&list,sizeof(list),1,fp)==1)
{
for(i=0;i<=l;i++)
firstName[i]=list.firstName[i];
firstName[l]='\0';
if(stricmp(firstName,query)==0)
{
printf("\n..::First Name\t: %s\n..::Second Name\t: %ld\n..::Email\t: %s\n..::CompanyName\t: %s\n..::Number\t: %s\n",list.firstName,list.lastName,list.email,list.companyName.list.phoneNumber);
found++;
if (found%4==0)
{
printf("..::Press any key to continue...");
getch();
}
}
}
if(found==0)
printf("\n..::No match found!");
else
printf("\n..::%d match(s) found!",found);
fclose(fp);
printf("\n ..::Try again?\n\n\t[1] Yes\t\t[11] No\n\t");
scanf("%d",&ch);
}while(ch==1);
}
Anyone have any idea as to where I'm going wrong in the code?Thanks

Your errors are because:
1) you don't define listelement anywhere
2) you don't define string anywhere (and it's not a type in C)
3) You need to move the #define MAX up above before you use it.
4) You don't define FALSE anywhere (and it's not a type in C)
5) You're redefining elements too, in getFirst() you've passed in query as a "string", then you
define a new query as a char array
6) You get redefinition errors because you've got more than one define. That's somewhat #5 but there's more as well. In your main you declare iChoice here: string query;int iChoice = 0;
then you declare it again int iChoice; right after your Menu() call
7) Please don't do fflush(stdin) that's undefined behavior as per the C standard

Related

Getting "dereferencing pointer to incomplete type 'struct node' "error

I'm making a push/pop program using stacks and linked lists. Running into two errors in function pushpancake(). One is "dereferencing pointer to incomplete type 'struct node'" and the other says my "top" is undeclared. Some help would be greatly appreciated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
int main ()
{
struct node {
int data;
struct node* next;
};
struct node* top=NULL;
int choice = 0;
printMenu ();
do
{
printf ("\nEnter a choice. ");
scanf ("%d", &choice);
switch (choice)
{
case 0:
{
exitProgram();
break;
}
case 1:
{
clrScreen();
break;
}
case 3:
{
pushpancake();
break;
}
default:
printf("\nInvalid Choice!\n");
}
}
while (choice != 0);
return 0;
}
void printMenu ()
{
printf ("0) Exit program.\n\n");
printf ("1) Clear Screen.\n\n");
printf ("2) Display the pancake stack.\n\n");
printf ("3) Push a pancake.\n\n");
printf ("4) Pop a pancake.\n\n");
}
void pushpancake()
{
char pancake[30];
int calories;
printf("Enter pancake name and its calories:");
scanf("%s %d,", pancake, &calories);
printf("The pancake has been added at the top of the stack.");
struct node *temp=(struct node*)malloc(sizeof(struct node));
strcpy(temp->pancake,pancake);
temp->data=calories;
temp->next=top;
top=temp;
}
This is my answer, hope it is useful for you.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define ERROR 0
// infinite stack struct
typedef struct node {
int data;
struct node* next;
char name[100];
}StackNode,*LinkStackPtr;
typedef struct
{
LinkStackPtr top;
int count;
}LinkStack;
void printMenu ();
void clrScreen();
void pushpancake(LinkStack *S);
int popancake(LinkStack *S);
int PrintStackTop(LinkStack S);
int StackLength(LinkStack S);
int ClearStack(LinkStack *S);
// get length of stack
int StackLength(LinkStack S)
{
return S.count;
}
// judge stack if or not empty
int StackEmpty(LinkStack S)
{
if (S.count==0)
return OK;
else
return ERROR;
}
int look(char *strP,int c)
{
printf("%s ",strP);
printf("%d ",c);
return OK;
}
// print stack
int PrintStackTop(LinkStack S)
{
LinkStackPtr p;
p=S.top;
if(S.count == 0){
printf("stack is empty, can't print\n");
return ERROR;
}
else{
printf("The count of stack value is: %d\n",StackLength(S));
printf("\nThe value of stack is:\n");
while(p && S.count){
look(p->name,p->data);
p=p->next;
S.count--;
}
printf("\n");
return OK;
}
}
// pop a number from stack
int popancake(LinkStack *S)
{
LinkStackPtr p;
if(StackEmpty(*S))
return ERROR;
p = S->top;
S->top = S->top->next;
free(p);
S->count--;
return OK;
}
//push a number to stack
void pushpancake(LinkStack *S)
{
char pancake[100];
int calories;
printf("Enter pancake name and its calories : (format : apple 10) ");
scanf("%s %d,", pancake, &calories);
struct node *temp=(struct node*)malloc(sizeof(struct node));
strcpy(temp->name,pancake);
temp->data=calories;
temp->next=S->top;
S->top=temp;
S->count++;
printf("The pancake has been added at the top of the stack.");
}
// init stack
int InitStack(LinkStack *S)
{
S->top = (LinkStackPtr)malloc(sizeof(StackNode));
if(!S->top)
return ERROR;
S->top=NULL;
S->count=0;
return OK;
}
void clrScreen()
{
system("clear"); // may be error at windows, if yes, commment it.
}
void printMenu ()
{
printf ("0) Exit program.\n\n");
printf ("1) Clear Screen.\n\n");
printf ("2) Display the pancake stack.\n\n");
printf ("3) Push a pancake.\n\n");
printf ("4) Pop a pancake.\n\n");
}
int ClearStack(LinkStack *S)
{
LinkStackPtr p,q;
p=S->top;
while(p)
{
q=p;
p=p->next;
free(q);
}
S->count=0;
return OK;
}
int main ()
{
LinkStack s;
int choice = 0;
int booL;
printMenu ();
InitStack(&s);
do
{
printf ("\nEnter a choice. (0-4) ");
scanf ("%d", &choice);
switch (choice)
{
case 0:
{
booL = ClearStack(&s);
if(booL == OK){
printf("stack have been clear!\n");
}
PrintStackTop(s);
printf("exit the program! bye bye\n");
exit(0); // exit the program
break;
}
case 1:
{
clrScreen();
break;
}
case 2:
{
PrintStackTop(s);
break;
}
case 3:
{
pushpancake(&s);
break;
}
case 4:
{
booL = popancake(&s);
if(booL)
printf("delete top of stack by successful!");
else
printf("delete top of stack by failed!");
break;
}
default:
printf("\nInvalid Choice!\n");
break;
}
}
while (choice != 0); // if choice is 0, then exit the program
return 0;
}
this is output :
0) Exit program.
1) Clear Screen.
2) Display the pancake stack.
3) Push a pancake.
4) Pop a pancake.
Enter a choice. (0-4) 2
stack is empty, can't print
Enter a choice. (0-4) 3
Enter pancake name and its calories : (format : apple 10) aa 1
The pancake has been added at the top of the stack.
Enter a choice. (0-4) 2
The count of stack value is: 1
The value of stack is:
aa 1
Enter a choice. (0-4) 3
Enter pancake name and its calories : (format : apple 10) bb 2
The pancake has been added at the top of the stack.
Enter a choice. (0-4) 2
The count of stack value is: 2
The value of stack is:
bb 2 aa 1
Enter a choice. (0-4) 3
Enter pancake name and its calories : (format : apple 10) cc 3
The pancake has been added at the top of the stack.
Enter a choice. (0-4) 2
The count of stack value is: 3
The value of stack is:
cc 3 bb 2 aa 1
Enter a choice. (0-4) 4
delete top of stack by successful!
Enter a choice. (0-4) 2
The count of stack value is: 2
The value of stack is:
bb 2 aa 1
Enter a choice. (0-4) 0
stack have been clear!
stack is empty, can't print
exit the program! bye bye

Passing and returning a struct from a function

I have a function with a book struct array, but when i try to return it to my main it does not return the values and store them in the array. If the addBook function has to be void how would i work around that so that i can access the array elements later.
void addBook(struct Book book[], int *size) {
if (*size == MAX_BOOKS) {
printf("The inventory is full\n");
}
else {
printf("ISBN:");
scanf("%d", &book[*size]._isbn);
printf("Title:");
scanf("%s", book[*size]._title);
getchar();
printf("Year:");
scanf("%d", &book[*size]._year);
printf("Price:");
scanf("%f", &book[*size]._price);
printf("Quantity:");
scanf("%d", &book[*size]._qty);
*size++;
printf("The book is successfully added to the inventory.\n");
}
return book;
}
int main(void) {
struct Book book[MAX_BOOKS];
int size = 0;
int i;
int option;
printf("Welcome to the Book Store\n");
printf("=========================\n");
do {
menu();
printf("Select: ");
scanf("%d", &option);
switch (option) {
case 0:
printf("Goodbye!\n");
break;
case 1:
displayInventory(book, size);
break;
case 2:
addBook(book, &size);
break;
case 3:
//checkPrice();
break;
default:
printf("Invalid input, try again:\n");
}
} while (option != 0);
}
Your return statement isn't going to do what you're intending as the addBook's function signature says it returns void. I'm surprised that the code as is actually compiled without an error about this.
Anyways, the book data can be returned from the same way it was passed in - as an input and output parameter.
Essentially your code could look like the following (which is only meant to be an example of code that compiles and works to save info entered in from standard input into the book):
#include <stdio.h>
struct Book {
int value;
};
#define MAX_BOOKS 2
void addBook(struct Book book[], int *size) {
if (*size == MAX_BOOKS) {
printf("The inventory is full\n");
}
else {
printf("Value:");
scanf("%d", &book[*size].value);
(*size)++;
printf("The book is successfully added to the inventory.\n");
}
}
int main(void) {
struct Book book[MAX_BOOKS];
int size = 0;
addBook(book, &size);
printf("Book 1: Value=%d\n", book[0].value);
}
And here's how this looks when run:
$ ./main
Value:9
The book is successfully added to the inventory.
Book 1: Value=9
Hope this answers your question.
I think your problem is in the line *size++;. You should use parenthesis, otherwise you are modifying the pointer to size, not the value. It should be (*size)++.
Also, the addBook function should not return anything, since it is void, and it is changing the content of the array book already.

Cannot print out data in a binary tree

Actually, I am here asking you to help debug. So, if you don't have any interest in helping me debugging, you can stop here any go back. However, I believe that my code only contain a small bug because I have tested most part of it.
I have do a little test myself. The code work successfully when I commented out the function pinrtOneNode(), which mean that I only input data into that binary tree. So probably the only bug is in the printOnrNode() function.
And also, the compile time error is
c:\users\...\Local\temp\ccwCUbY.oprompt
c:\users\...\.../bst.c:45printOneNode
collect2.exe:error:ld returned 1 exit status
By the way, the bst.c is where my source code in
So here is the code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct BSTnode{
struct BSTnode* leftchild;
struct BSTnode* rightchild;
char data[20];
}BSTnode;
void prompt(); //this function always prompt the user for selection everytime
//after he input data( inputData() ) or print data( printOneNode() )
void inputData();
void printOneNode();
BSTnode firstNode;
BSTnode* MyNode=&firstNode; //I don't know if it's good to initialize it this way
int main()
{
//MyNode=malloc(sizeof(BSTnode));
MyNode->leftchild=NULL;
MyNode->rightchild=NULL;
strcpy(MyNode->data,"");
while(1)
prompt(); // I use a while loop to prompt user for selection continuously
return 0;
}
/* this function is used to prompt user for selection input*/
void prompt(){
int i=0;
printf("Please select:\n");
printf("1.input a data\n2.print only one data\n3.Exit\n");
scanf("%d",&i);
switch(i){
case 1:
inputData();
break;
case 2:
printOneNode();
break;
case 3:
exit(0);
default:
printf("Please input a valid number!(1-3)");
}
}
/* this is used to input data into the binary tree*/
void inputData(){
char data[20]={0};
printf("Input your data here(character only / less than 19 characters!): ");
scanf("%s",data);
BSTnode** ptr=&MyNode;
while(1){
if(strcmp(data,(*ptr)->data)){
if((*ptr)->rightchild!=NULL){
ptr=&((*ptr)->rightchild);
continue;
}
else{
(*ptr)->rightchild=malloc(sizeof(BSTnode));
ptr=&((*ptr)->rightchild);
(*ptr)->rightchild=NULL;
(*ptr)->leftchild=NULL;
strcpy((*ptr)->data,data);
break;
}
}
else{
if((*ptr)->leftchild!=NULL){
ptr=&((*ptr)->leftchild);
continue;
}
else{
(*ptr)->leftchild=malloc(sizeof(BSTnode));
ptr=&((*ptr)->leftchild);
(*ptr)->leftchild=NULL;
(*ptr)->rightchild=NULL;
strcpy((*ptr)->data,data);
break;
}
}
}
printf(" Your data have been input successfully!\n");
return;
}
/* this is used to print data, only one at a time*/
void PrintOneNode(){
BSTnode** ptr=&MyNode;
printf("The first node is%s\n",(*ptr)->data);
while(1){
printf("Select which side of node do you want to print now(l/r)?(q for quit) ");
//I ask user whether he wanna print out the data in node in the right side
// of the current node or left side
char a;
scanf("%c",&a);
switch(a){
case 'l':
if((*ptr)->leftchild!=NULL){
ptr=&((*ptr)->leftchild);
printf("\t%s\n",(*ptr)->data);
}
else
printf("There is no more leftchild");
break;
case 'r':
if((*ptr)->rightchild!=NULL){
ptr=&((*ptr)->rightchild);
printf("\t%s\n",(*ptr)->data);
}
else
printf("There is no more rightchild!");
break;
case 'q':
return;
default:
return;
}
}
}
Please help. And any improvement to this snippet of code beside the bug will be also appreciated vert much. Thanks.

Declaring Int variables causes segmentation fault?

Hey guys I'm having a really peculiar segmentation fault coming up in my program. This program is suppose to automate the card game "war" and so far I've been able to build two randomized half decks for both players. Which would appear to show that enqueue is working correct. I was also able to dequeue all the values and they appeared in the correct order. However inside main if I uncomment the integer declarations in main the program segfaults every time. I can not for the life of me figure out how simple declarations could cause faults. Please note this is my only second assignment for using queues.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct node
{
int value;
int suit;
char*sname;
char*txt;
struct node *next;
} node;
int isempty(node *base){
if (base==NULL)
{return 1;}
else
return 0;
}
void printlist(node *base){
node *current=base;
if(base==NULL)
{
printf("The List is empty!\n");
return;
}
else
{
printf("Content: \n");
int count=0;
while(current!=NULL){
count++;
printf("%s \tof \t%s\n",current->txt,current->sname);
current=current->next;
}
printf("\nCount:%d\n",count);
}
}
char* valname(int n){
char *name;
switch(n)
{
case 0:name="two";break;
case 1:name="three";break;
case 2:name="four";break;
case 3:name="five";break;
case 4:name="six";break;
case 5:name="seven";break;
case 6:name="eight";break;
case 7:name="nine";break;
case 8:name="ten";break;
case 9:name="Jack";break;
case 10:name="Queen";break;
case 11:name="King";break;
case 12:name="Ace";break;
default:printf("Broken\n");exit(1);
}
return(name);
}
char* suitname(int n){
char *name;
switch(n){
case 0:name="Hearts";break;
case 1:name="Spades";break;
case 2:name="Clubs";break;
case 3:name="Diamonds";break;
default:printf("Broken\n");exit(1);
}
return(name);
}
void enqueue(node **base,int item){
node *nn,*current=*base;
nn=malloc(sizeof(node));
if(*base==NULL)
{
*base=nn;
}
else
{
while(current->next!=NULL){
current=current->next;
}
current->next=nn;
}
nn->value=item;
nn->txt=valname(item%13);
nn->sname=suitname(item/13);
nn->next=NULL;
}
int dequeue(node **base){
node *current=*base,*temp;
if (isempty(*base)==0){
int giveback=current->value;
if(current->next==NULL)
{
free(*base);
*base=NULL;
}
else
{
temp=current->next;
free(current);
*base=temp;
}
return giveback;
}else{return -1;}
}
void createdecks(node **deck1,node **deck2){
int i=0;
int thenumber=0;
int deck[52]={0};
for(i=0;i<26;i++){
thenumber=rand()%52;
if(deck[thenumber]==0){
//add to list
enqueue(deck1,thenumber);
deck[thenumber]=1;
}
else
{
i--;
}
}
for(i=0;i<26;i++){
thenumber=rand()%52;
if(deck[thenumber]==0){
//add to list
enqueue(deck2,thenumber);
deck[thenumber]=1;
}
else
{
i--;
}
}
}
int main(void){
node *d1,*d2,*warholder;
//int c1=0,c2=0; //THIS LINE!!!!!!!!!!!
srand(time(NULL));
createdecks(&d1,&d2);
//printlist(d1);
//printlist(d2);
int i=0;
for(i=0;i<26;i++)
printf("%d ",dequeue(&d1)); //return testing
printf("\n");
printlist(d1);
}
Professor's example function
char * namenum( int num)
{
char * name;
switch(num)
{
case 0:
name = "zero"; break;
case 1:
name = "one"; break;
case 2:
name = "two"; break;
case 3:
name = "three"; break;
case 4:
name = "four"; break;
case 5:
name = "five"; break;
case 6:
name = "six"; break;
case 7:
name = "seven"; break;
case 8:
name = "eight"; break;
case 9:
name = "nine"; break;
default:
printf("Invalid Number generated\n");
exit(1);
}
return name;
}
I briefly looked at the code, and it looks to me like you have an uninitialized-variable problem. You declare this in main():
node *d1,*d2,*warholder;
And then you pass it to createdecks(), which in turn calls enqueue(). enqueue() assumes that the pointers are initialized.
Try to initialize d1 and d2 in main():
node *d1,*d2,*warholder;
d1 = d2 = warholder = NULL;
Its not due to declaring int. You have not allocated memory to char *name on several times before using it. for example
char* valname(int n){
char *name;
allocate memory using malloc() before using name after above code
char* suitname(int n){
char *name;
same mistake again
If you want to avoid such situation use array instead of pointer

C stack array problem

My function code for peek is not working? why is that? can anyone help me with my peek function?
#include<stdio.h>
#include<stdlib.h>
#define maxsize 10
int stack[maxsize];
int stacktop=0;
void instructions();
int process();
int push(int value);
int pop();
void display();
void peek();
int main()
{
process();
getch();
}
int process()
{
int val;
int choice;
do
{
instructions();
printf("Enter Your Choice: ");
scanf("%d",&choice);
switch( choice )
{
case 1:
printf("\nElement to be Pushed : ");
scanf("%d",&val);
push(val);
break;
case 2:
val=pop();
if(val!=-1)
{
printf("Popped Element : %d\n",val);
}
break;
case 3:
peek();
break;
case 4:
display();
break;
case 5:
break;
}
}while(choice !=5);
}
void instructions()
{
printf("Enter Your choice for the following process\n");
printf("\n[1]Push a Node on top of the list");
printf("\n[2]Pop a node off the list");
printf("\n[3]Peek The Top Node");
printf("\n[4]Display The Whole list");
printf("\n[5]Exit The Program\n");
}
int push(int val)
{
if(stacktop<maxsize)
{
stack[stacktop++]=val;
}
else
{
printf("Stack is full");
}
}
int pop()
{
int a;
if(stacktop>0)
{
a=stack[--stacktop];
return a;
}
}
void display()
{
int i;
i = 0;
if(stacktop>0)
{
printf("Elements are:");
while(i<stacktop)
{
printf("\n%d--\n",stack[i++]);
}
}
}
void peek()
{
printf("%d",stacktop);
}
Is it supposed to be:
printf("%d\n", stack[stacktop - 1]);
Print the contents, rather than the size of the stack?
Obviously you'd also need to bounds check to make sure you're not printing outside of the range of your stack (when it's empty)
I know this isn't Code Review, but I thought I would give you a few bits of advice.
When you call scanf, always check the result. For example, if the user enters something other than a decimal number, your code will end up putting an indeterminate value into the choice or val variables. The scanf function returns the number of items that were successfully read. If you asked for one item, and scanf returns 1, then you can rely on the value of that object:
int choice;
if (scanf("%d", &choice) != 1)
// handle error, can't rely on value of "choice"
else
// continue onwards, can rely on value of "choice"
Usually, the \n escapes go at the end of the string literal, not at the beginning. It is more common to do it this way, but it doesn't mean it should always go at the end.
printf("Enter Your choice for the following process\n\n");
printf("[1]Push a Node on top of the list\n");
printf("[2]Pop a node off the list\n");
printf("[3]Peek The Top Node\n");
For outputting simple strings, consider just using the puts function, which automatically appends the new-line character for you:
puts("Enter Your choice for the following process");
puts("");
puts("[1]Push a Node on top of the list");
puts("[2]Pop a node off the list");
puts("[3]Peek The Top Node");
Your display method is a perfect example of when to use a for loop instead of a while loop. Generally speaking, use a for loop when you know exactly how many items you have and you want to iterate over each of them:
void display()
{
int i;
puts("Elements are:");
for (i = 0; i < stacktop; i++)
printf("\n%d--\n", stack[i]);
}
To reverse the order of the stack, simply start at the top and go backwards:
void display()
{
int i;
puts("Elements are:");
for (i = stacktop - 1; i >= 0; i--)
printf("\n%d--\n", stack[i]);
}

Resources