Inserting at the end of queue in C - c

I am trying to insert node at the end of queue and facing below error . This is simple fundamental error while compiling the code but making my life hard.
#include<stdio.h>
#include<stdlib.h>
typedef struct UNIX {
char str[20];
struct UNIX *next;
}examp;
examp *head=NULL;
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
slide->next=new;
new->str=s;
new->next=NULL;
if(head==NULL)
{ head=new;
return 1;
}
return 1;
}
void display (void);
int main()
{
insert_last("hello ");
insert_last("how ");
insert_last("have ");
insert_last("you ");
insert_last("been ");
insert_last("! ");
display();
}
void display(void)
{
examp *slide;
slide=head;
while(slide->next!=NULL)
{ printf("%s ",slide->str);
slide=slide->next;
}
}
Error :stack_queue.c:27:10: error: assignment to expression with array type
new->str=s;
Update : Using strncpy reolved the error , but code is not working as expected and stopping unexpectedly.

You can't assign to a static array like that. Consider using strcpy or strncpy to copy the contents of the character string instead.

You cannot assign a string to an array! An array have its own memory, you can write or read elements in the array, but cannot assign an address.
You can eventually copy the string s contents to the array:
strncpy(new->str, s, 19);
new->str[19] = '\0'; //Close the string in case of overflow.
We used strncpy to limit the copied characters to the array size (19 chars + the ending '\0').

You can try it. Only replace in new->str=s; to strcpy(new->str, s); (ie. s will be copy in to new->str)
#include<stdio.h>
#include<stdlib.h>
typedef struct UNIX {
char str[20];
struct UNIX *next;
}examp;
examp *head=NULL;
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
slide->next=new;
strcpy(new->str, s);
new->next=NULL;
if(head==NULL)
{ head=new;
return 1;
}
return 1;
}
void display (void);
int main()
{
insert_last("hello ");
insert_last("how ");
insert_last("have ");
insert_last("you ");
insert_last("been ");
insert_last("! ");
display();
}
void display(void)
{
examp *slide;
slide=head;
while(slide->next!=NULL)
{ printf("%s ",slide->str);
slide=slide->next;
}
}

As already stated you will have to use strcpy (or strncpy) in order to assign the string.
Asides from that I wanted to mention two things:
Do not forget to free your memory allocated by malloc. Create a method to free a single node (examp) then you can also provide a method to destroy the whole list.
I would suggest to rename the variable new to avoid confusion (pure C compiler may deal with it, but C/C++ compiler will most likely get into trouble).
Considering your update:
Take a look at the following line
while(slide->next!=NULL)
At this time slide does not even exist (it is NULL), still you perform an operation on the pointer. This is the reason why the program crashes.

Your error is in the first call insert_last("hello "):
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
when you call it first time, head is NULL, so slide becomes NULL, but you don't check it, and call it in
while(slide->next!=NULL)
Here slide is null for the frst function call

Related

C program to add 2 polynomials and then displaying it

I am writing a C program to add 2 polynomials given by user then displaying it in a separate function but it is not adding anything. In fact, it is not giving any type of error message so I am very confused. I think the mistake can be in 'addpoly' function or display function. I don't know what I am doing wrong. Any type of help will be appreciated.
#include<stdio.h>
#include<stdlib.h>
#define MAX 3
struct polynomial
{
int coeff;
int exp;
struct polynomial *next;
};
typedef struct polynomial polynomial;
polynomial *p1=NULL,*p2=NULL,*p3=NULL, *head_address=NULL;
polynomial* create()
{
polynomial *head_address=NULL, *prev_address=NULL, *new_address=NULL;
int i;
for(i=0;i<MAX;i++)
{
new_address=(polynomial*)malloc(sizeof(polynomial));
printf("Enter coeff:\n");
scanf("%d",&new_address->coeff);
printf("Enter exp:\n");
scanf("%d",&new_address->exp );
new_address->next=0;
if(head_address==NULL){
head_address=prev_address=new_address;
}
else{
prev_address->next=new_address;
prev_address=new_address;
}}
return head_address; }
void polyadd(polynomial *p1, polynomial *p2,polynomial *p3)
{
//polynomial* p3=NULL;
while(p1->next!=NULL && p2->next!=NULL){
if(p1->exp > p2->exp){
p3->coeff=p1->coeff;
p3->exp=p1->exp;
p1=p1->next;
}
else if(p1->exp < p2->exp){
p3->coeff=p2->coeff;
p3->exp=p2->exp;
p2=p2->next;
}
else if(p1->exp==p2->exp){
p3->coeff=p1->coeff + p2->coeff;
p3->exp=p1->exp;
p1=p1->next;
p2=p2->next;
}
p3->next=(polynomial*)malloc(sizeof(polynomial));
p3=p3->next;
p3->next=NULL; }
while(p1->next || p2->next){
if(p1->next){
p3->exp=p1->exp;
p3->coeff=p1->coeff;
p1=p1->next;
}
else if(p2->next){
p3->exp=p2->exp;
p3->coeff=p2->coeff;
p2=p2->next;
}
p3->next=(polynomial*)malloc(sizeof(polynomial));
p3=p3->next;
p3->next=NULL;
}
}
void display(polynomial *temp){
polynomial *p3;
p3=temp;
temp=head_address;
while(temp->next!=NULL)
printf("%dx^%d",temp->coeff,temp->exp);
temp=temp->next;
if(temp->next!=NULL){
printf(" + ");
}
}
int main(){
polynomial *p1,*p2,*p3;
p1=create();
printf("Next:\n");
p2=create();
polyadd(p1,p2,p3);
printf("Result:\n");
display(p3);
return 0;
}
Your issue looks like a memory reference error. In your polyadd() function you're not mallocing as much as you need to. Your base p3 pointer for your linked list is still unallocated when you start referencing off it in your first while loop. To fix your memory issue you'll want to malloc p3 before using it and then make sure the subsequent ->next instances all get malloced before being used.
I don't think this is causing you issues currently but you also have global variables defined at the top and then defined again in main(). The local variables will be the only ones used as long as they're present but I would delete your globals and make sure you don't have unused duplicates to avoid confusion.

Having problems displaying structure array content

I want to display structure members based on user input, but I don't know if I've stored the input properly.
When I try display all people, it just outputs random numbers.
These are the structures and function prototypes
#define MAX_NAME_LEN 15
#define MAX_NUM_PERSON 4
#define MAX_JOB_LENGTH 20
typedef struct birth_date
{
int month;
int day;
int year;
} person_birth_t;
typedef struct person
{
char pName[MAX_NAME_LEN];
char job[MAX_JOB_LENGTH];
person_birth_t birth_t;
} person_t[MAX_NUM_PERSON];
void print_menu (void);
void scanPerson(person_t p, int);
void displayPeople(person_t p);
This is the main code for the program, a menu is printed asking user to input a number, if a user enters 1 then it prompts them to add a person. Entering 2 displays all people entered.
int main(void)
{
/* TODO */
print_menu();
return 0;
}
void print_menu (void)
{
int choice;
person_t p;
static int index = 0;
int *indexP = NULL;
indexP = &index;
/*Print the menu*/
scanf("%d", &choice);
switch (choice)
{
case 1:
if (index < MAX_NUM_PERSON){
scanPerson(p, index);
++*indexP;
print_menu();
} else {
printf("Can't add more people - memory full \n");
print_menu();
}
break;
case 2:
displayPeople(p);
break;
case 3:
exit(0);
break;
default:
print_menu();
}
}
/*function called when add person is chosen from menu */
void scanFlight(person_t p, int index){
/*printf to enter name*/
scanf(" %s", p[index].pName);
/*printf to enter job*/
scanf("%s", p[index].job);
}
void displayPeople(person_t p){
for(int i = 0; i < MAX_NUM_PERSON; i++){
printf("%s %d-%d-%d %s \n",p[i].pName
,p[i].birth_t.month
,p[i].birth_t.day
,p[i].birth_t.year
,p[i].job);
}
}
I've tried other ways to take input and add it to a struct array, but I'm just not sure how to do it right.
person_t p;
Here, you use the local variable p (in print_menu function), so each recursion, you just print the parameters of the local variable that is not initialized.
To solve it, you can declare p as the global variable.
OT, in scanFlight function, to avoid overflow, you should change the scanf function to:
/*printf to enter name*/
scanf("%14s", p[index].pName);
/*printf to enter job*/
scanf("%20s", p[index].job);
And, rename scanPerson to scanFlight, because i do not see any implementation of scanPerson function in your code. I think it's typo, no ?
None of the methods were working, so instead of trying to figure it out, I scrapped the static index and indexP.
Instead, I initialized p with malloc:
person_t *p= malloc(MAX_NUM_PERSON * sizeof(person_t));
I changed the scan function to accommodate for the change and made index a pointer instead, and I made the display function pass the index.
When I ran it, the output was correct.

Inserting in Linked List

I'm having a small difficulty inserting a full sentence containing all characters in my string when I'm building a Linked List.
I would like to be able to insert a string like: word_#_2003_#_definition
But when I'm running my code in my main() method it continues repeating the choices to do like it never stops asking me to enter an option. Hope it's clear.
Here's my struct:
struct node
{
char data[100];
struct node *previous; // Points to the previous node
struct node *next; // Points out to the next node
} *head, *last;
Here's my function to insert a node:
void insert_beginning(char words[99])
{
struct node *var, *temp;
var=(struct node *)malloc(sizeof(struct node)); //explination about the (node *)
strncpy(var->data, words,99);
if (head==NULL)
{
head=var;
head->previous=NULL;
head->next=NULL;
last=head;
}
else
{
temp=var;
temp->previous=NULL;
temp->next=head;
head->previous=temp;
head=temp;
}
}
And this is in my main() method:
int main()
{
char loc[99];
char words[99];
int i, dat;
head=NULL;
printf("Select the choice of operation on link list");
printf("\n1.) Insert At Begning\n2.) Insert At End\n3.) Insert At Middle");
printf("\n4.) Delete From End\n5.) Reverse The Link List\n6.) Display List\n7.)Exit");
while(1)
{
printf("\n\n Enter the choice of operation you want to do ");
scanf("%d",&i);
switch(i)
{
case 1:
{
printf("Enter a word you want to insert in the 1st node ");
scanf(" %s",words);
insert_beginning(words);
display();
break;
}
Any ideas on how to do it?
The code is highly questionable:
return codes are never checked. You must check return codes,
especially if you are using scanf
You need to empty the whole buffer with scanf otherwise you will continue
reading old contents for the next command
A better alternative is to use sscanf
You must initialize your variables, for instance last, but there are additional
cases of variables that do not get initialized
Your data types are not consistently defined, this will create security problems
sometimes 99 characters and sometimes 100.
insert_beginning should not return void, the memory allocation can fail
Your code in main() should probably look more like:
int main()
{
char loc[99];
char words[99];
int i, dat;
head = NULL;
printf("Select the choice of operation on link list");
printf("\n1.) Insert At Beginning\n2.) Insert At End\n3.) Insert At Middle");
printf("\n4.) Delete From End\n5.) Reverse The Link List\n6.) Display List\n7.) Exit\n");
while(1)
{
printf("\nEnter the choice of operation you want to do: ");
if (scanf("%d", &i) != 1)
{
fprintf(stderr, "Failed to read a number: exiting\n");
return 1;
}
switch(i)
{
case 1:
{
printf("Enter a word you want to insert in the 1st node: ");
if (scanf("%98s", words) != 1)
{
fprintf(stderr, "Failed to read words; exiting\n");
return 1;
}
insert_beginning(words);
display();
break;
}
...
}
...
}
...
}
return 0;
}
As discussed in the comments, you are not checking the return status from scanf(), so you don't know when it is failing, and when it fails to read a number, it leaves the argument (i) alone, so you go back to the same option again, and rinse and repeat.
Elementary debugging techniques (not shown):
Print the values you get from your inputs. Print the value of i after the scanf() error checking. Print the value of words after the scanf() error checking.
Step through with a debugger.
Create a function to dump (print) your key data structures:
static void dump_data_structure(FILE *fp, char const *tag, data_structure const *data)
{
...code to dump the structure to the specified file stream,
...identified by tag (so you can tell which call it is you are looking at)
}
Use the structure dumper extensively while debugging. Keep it for use later when modifying the code. If done right, it can be enormously helpful.

linked list in linked List in C, segfault at reading in second list

I'm writing at a logfile searchprogramm for A Mailserver. I have eine struct with another struct linked inside. My func put the Data of a TimeStamp, a MailserverIp, the specific MailId in a single-linked list. Moreover I have a List of Receivers, which I also wanna put it in a single linked list which is a pointer in the first single-linked-list. (A linked-list inside a linked-list)
The structs I made are the following:
struct SearchEntry{
int headindex;
char *TimeStamp;
char *IP;
struct Empfaenger *nextE;
struct Empfaenger *anfangE;
char *MailId;
struct SearchEntry *next;
};
struct Empfaenger{
int headindex;
char *Empfaenger;
struct Empfaenger *nextE;
};
This is the function to put the data inside the two lists:
void write_list(char *TimeStamp, char *IP, char *Empfaenger, char *MailId){
printf("MailID: %s\n", MailId);
if(anfang==NULL){
if((anfang=malloc(sizeof(struct SearchEntry)))==NULL){
fprintf(stderr, "Kein Speicherplatz vorhanden für Anfang\n");
return;
}
printf("starta!\n");
anfang->TimeStamp=malloc(sizeof(char)*strlen(TimeStamp));
anfang->IP=malloc(sizeof(char)*strlen(IP));
anfang->MailId=malloc(sizeof(char)*strlen(MailId));
strcpy(anfang->TimeStamp, TimeStamp);
strcpy(anfang->IP, IP);
strcpy(anfang->MailId, MailId);
headindexcounter=0;
anfang->headindex=headindexcounter;
headindexcounter++;
anfang->next=NULL;
}else{
struct SearchEntry *zeiger;
zeiger=anfang;
while(zeiger->next!=NULL)
zeiger=zeiger->next;
if((zeiger->next=malloc(sizeof(struct SearchEntry)))==NULL){
fprintf(stderr, "Kein Speicherplatz vorhanden für Anfang\n");
return;
}
zeiger=zeiger->next;
if(TimeStamp!=NULL){
zeiger->TimeStamp=malloc(sizeof(char)*strlen(TimeStamp));
strcpy(zeiger->TimeStamp, TimeStamp);
}else{
strcpy(zeiger->TimeStamp, "0");
}
if(IP!=NULL){
zeiger->IP=malloc(sizeof(char)*strlen(IP));
strcpy(zeiger->IP, IP);
}else{
strcpy(zeiger->IP, "0");
}
if(Empfaenger!=NULL){
char *empfaenger=strtok(Empfaenger, ", ");
zeiger->anfangE=NULL;
zeiger->nextE=NULL;
//Here begins the code to put kame a new struct/list inside of the firstlist SearchEntry
while(empfaenger!=NULL){
printf("EMPFAENGER: %s\n", empfaenger);
if(zeiger->anfangE==NULL){
if((zeiger->anfangE=malloc(sizeof(struct Empfaenger)))==NULL){
fprintf(stderr, "Kein Speicherplatz vorhanden für Anfang\n");
return;
}
zeiger->anfangE->Empfaenger=malloc(sizeof(char)*strlen(empfaenger));
strcpy(zeiger->anfangE->Empfaenger, empfaenger);
printf("zeiger->anfangE->Empfaenger=%s\n", zeiger->anfangE->Empfaenger);
zeiger->anfangE->headindex=headindexcounterE;
headindexcounterE++;
zeiger->anfangE->nextE=NULL;
printf("xyz_a!\n");
}else{
printf("abc_b!\n");
struct Empfaenger *zeigerE;
zeigerE=zeiger->anfangE;
while(zeigerE->nextE!=NULL)
zeigerE=zeigerE->nextE;
if((zeigerE->nextE=malloc(sizeof(struct Empfaenger)))==NULL){
fprintf(stderr, "Kein Speicherplatz vorhanden für Anfang\n");
return;
}
zeigerE=zeigerE->nextE;
zeigerE->Empfaenger=malloc(sizeof(char)*strlen(empfaenger));
strcpy(zeigerE->Empfaenger, empfaenger);
printf("zeiger->anfangE->Empfaenger=%s\n", zeigerE->Empfaenger);
zeigerE->headindex=headindexcounterE;
headindexcounterE++;
zeigerE->nextE=NULL;
printf("xyz_b!\n");
}
empfaenger=strtok(0, ", ");
}
//
}else{
printf("NULL: %s\n", Empfaenger);
strcpy(zeiger->anfangE->Empfaenger, "NULL");
zeiger->anfangE->headindex=0;
zeiger->anfangE->nextE=NULL;
}
if(MailId!=NULL){
zeiger->MailId=malloc(sizeof(char)*strlen(MailId));
strcpy(zeiger->MailId, MailId);
printf("%s\n", zeiger->MailId);
}else{
strcpy(zeiger->MailId, "0");
}
printf("y!\n");
zeiger->headindex=headindexcounter;
headindexcounter++;
zeiger->next=NULL;
printf("stopb!\n");
}
}
And this is the function to read all the Data out of the two lists:
void Searchoutput(){
struct SearchEntry *zeiger=anfang;
while(zeiger!=NULL){
printf("%s\n", zeiger->TimeStamp);
printf("%s\n", zeiger->IP);
printf("%s\n", zeiger->MailId);
struct Empfaenger *zeigerE=zeiger->anfangE;
while(zeigerE!=NULL){
printf("%s\n", zeigerE->Empfaenger);
zeigerE=zeigerE->nextE;
}
zeiger=zeiger->next;
}
}
The Code To put the Data in the first and second linked list works, and also when I try to read the Data out of the first only, but when I try to read the data out of the first and then inside of the loop also try to read out the data of the second linked list I get a memory access error.
Does anyone know where the problem is? I already tried it out without the part of the second list, because of I know that works.
Your memory allocations for strings are wrong, you fail to allocate room for the terminator. This means that every strcpy() overwrites random memory, which causes undefined behavior.
These:
anfang->TimeStamp=malloc(sizeof(char)*strlen(TimeStamp));
anfang->IP=malloc(sizeof(char)*strlen(IP));
anfang->MailId=malloc(sizeof(char)*strlen(MailId));
should be:
anfang->TimeStamp = malloc(strlen(TimeStamp) + 1);
anfang->IP = malloc(strlen(IP) + 1);
anfang->MailId = malloc(strlen(MailId) + 1);
I removed the pointless scaling by sizeof(char), that's always going to be 1. You should also check the allocations for failure before relying on them having succeeded. Finally the above is quite inefficient since it does three smallish allocations rather than a single large one but perhaps you need them to be independent.

hangman console game in c

#include<stdio.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
typedef struct dic {
int index;
char string[10];
struct dic *next;
}node;
main() {
FILE *fp;int indexrand;node *head;node *mainhead;
char s[10],question[10],answer[10];char check;
int count=-1,i,j,k,len,flag;head=(node *) malloc(sizeof(node));
mainhead=head;
fp=fopen("dictionary.txt","r");
while((fgets(s,10,fp))!=NULL) {
strcpy(head->string,s);
count++;
(head->index)=count;
head->next=(node *)malloc(sizeof(node));
head=head->next;
}
fclose(fp);
head->next=NULL;
srand(time(NULL));
indexrand=rand()%(count+1);
printf("%d\n",indexrand);
for(head=mainhead;(head->next)!=NULL;head=head->next)
if((head->index)==indexrand)
strcpy(question,(head->string));
printf("%s\n",question);
len=strlen(question);
printf("%d\n",len);
for(i=0;i<len-1;i++)
answer[i]='_';
answer[i]='\0';
printf("%s\n",answer);
printf("6 chances to go\n");
for(i=0,k=6;k>0;i++) {
flag=0;
printf("%d\n",i);
scanf("%c",&check);
for(j=0;j<(len-1);j++) {
if(question[j]==check) {
flag++;
answer[j]=check;
}
}
if(flag>0)
printf("%d chances to go\n",k);
if(flag==0) {
k--;
printf("no common letters...%d chances to go\n",k);
}
printf("%s\n",answer);
}
}
The file dictionary.txt has only one word per line.
While running the code, for every attempt from the user (i.e after user enters a character) the statement no common letters...%d chances to go\n",k is being displayed even if the flag > 0 condition is satisfied.
How do I correct this?
The line
scanf("%c",&check);
is reading characters the user types, including the newline.
You probably just want to read the first character on the line: use fgets() to read the whole line, and then set check = line[0].
printf("%d\n",i);
scanf("%c",&check);
Because of these statements,scanf is taking \n as a parameter and so printing "no common letters..." every time.Replace the above code with
printf("%d",i);
scanf("\n%c",&check);
I think you want to pass a string to scanf, so try it :
scanf("%s",&check);

Resources