So I have a program that takes a data string and a number on the end that is it's position in the priority that it's to be printed out. I'm required to use linked list's and I've figured out how to do so with that, however the way this program is executed is at the end of the data strings and priority's the user is supposed to enter NONE and the program executes. The problem is that my check with strcmp is forcing the user to enter NONE twice to execute the program. I don't think I'm using the scanf for string and int values correctly and that's where my problem lies but I'm not sure.
Here's a correct sample input:
andk81739wewe 7
qweod125632ao 3
lenlc93012wasd 0
093deaeiao12 5
13jadacas291 3
...
NONE
Here's what actually has to be typed for the program to execute
andk81739wewe 7
qweod125632ao 3
lenlc93012wasd 0
093deaeiao12 5
13jadacas291 3
...
NONE
NONE
Any ideas as to why a second NONE has to be typed for the program to recognize that none has been typed?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LARGE 100
struct node
{
char data[LARGE];
int position;
struct node* next;
};
void sortedInsert(struct node** first, struct node* new_node)
{
struct node* current;
if (*first == NULL || (*first)->position <= new_node->position)
{
new_node->next = *first;
*first = new_node;
}
else
{
current = *first;
while (current->next!=NULL &&
current->next->position > new_node->position)
{
current = current->next;
}
new_node->next = current->next;
current->next = new_node;
}
}
struct node *newNode(char *new_data,int position)
{
struct node* new_node =
(struct node*) malloc(sizeof(struct node));
strcpy(new_node->data,new_data);
new_node->position=position;
new_node->next = NULL;
return new_node;
}
void printList(struct node *head)
{
struct node *temp = head;
while(temp != NULL)
{
printf("%s \n", temp->data);
temp = temp->next;
}
}
int main(void) {
char job[LARGE],blank[1]={' '},*p,*q;
int number=0,x=0;
q=&blank[1];
struct node* first = NULL;
struct node *new_node = newNode(q,0);
printf("Please enter printing jobs\n");
while(x!=1){
if(strcmp(job,"NONE")==0){
x=1;
}
else{
scanf("%s", job);
scanf("%d", &number);
p=&job[0];
sortedInsert(&first, new_node);
new_node = newNode(p,number);
}
}
printf("Print Job in order from 9-0\n");
printList(first);
return 0;
}
Alternatively you may use following code segment. This one is more reduced and simplified approach.:
int main(void) {
char job[LARGE];
struct node *first = NULL;
struct node *new_node = NULL;
int number;
printf("Please enter printing jobs\n");
while(1)
{
scanf("%s", job);
if(!strcmp(job, "NONE"))
break;
scanf("%d", &number);
new_node = newNode(job, number);
sortedInsert(&first, new_node);
}
printf("Print Job in order from 9-0\n");
printList(first);
return 0;
}
Related
I am trying to implement polynomial addition using linked list. I have only coded a small part of it where i accept the input into first polynomial and while i was testing the code it kept throwing a segmentation fault error. I have sprinkled some random printf statements to try to debug the code.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
int coeff, power;
};
struct node* createNode(){
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->next = NULL;
return temp;
}
struct node* poly1,poly2,poly3;
void createList(struct node* head){
int ch=0;
struct node* temp;
struct node* newNode = createNode();
head=NULL;
temp=NULL;
while(ch!=-1){
printf("Enter coefficient and power");
scanf("%d",&newNode->coeff);
scanf("%d",&newNode->power);
if( head ==NULL){
printf("123123123");
temp = newNode;
head = newNode;
printf("bbbbbb");
}else{
printf("aaaaaaaa");
temp->next = newNode;
temp = newNode;
}
printf("Enter -1 to exit");
scanf("%d",&ch);
printf("9999");
}
printf("1");
}
void display(struct node* head)
{
struct node *temp;
temp=head;
if(temp==NULL)
printf("LL not present");
else
{
while(temp!=NULL)
{
printf("%dx^%d ",temp->coeff,temp->power);
temp=temp->next;
}
}
}
void main(){
printf("Enter the data for the first polynomial\n");
createList(poly1);
printf("%d",poly1->coeff);
display(poly1);
}
This is the output i am getting for it-
Enter the data for the first polynomial Enter coefficient and power3 2
123123123bbbbbbEnter -1 to exit9 9999Enter coefficient and power 1 1
1 1 aaaaaaaaEnter -1 to exit-1 Segmentation fault
Interestingly when i change the second last line of my while loop from
scanf("%d",&ch);
to ch=-1; the output that i get has none of the random printf i added to debug :
Enter the data for the first polynomial Enter coefficient and power3 2
Segmentation fault
I dont understand what the difference is between both of these cases. Also whats the issue with segmentation fault being thrown around?
As noted above you need to pass in the address of poly1, I made it a local rather than a global variable. Then you need to create a new node per loop iteration in createList(). Removed debugging output (use a macro and write something sensible in case you want to leave it in). Prefer for to while loops for iteration.
#include <stdio.h>
#include <stdlib.h>
struct node{
struct node* next;
int coeff, power;
};
struct node* createNode(){
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->next = NULL;
return temp;
}
void createList(struct node **head){
int ch;
*head = NULL;
do {
printf("Enter coefficient and power: ");
struct node* newNode = createNode();
if(scanf("%d %d",&newNode->coeff, &newNode->power) != 2) {
// TBD: free list
*head = NULL;
printf("scanf failed\n");
return;
}
if(!*head){
*head = newNode;
} else {
(*head)->next = newNode;
}
printf("Enter -1 to exit: ");
if(scanf("%d",&ch) != 1) {
// TBD: free list?
// *head = NULL;
printf("scanf failed\n");
return;
}
} while(ch!=-1);
}
void display(struct node *head)
{
if(!head) {
printf("LL not present");
return;
}
for(; head; head=head->next) {
printf("%dx^%d ", head->coeff, head->power);
}
printf("\n");
}
int main(void){
printf("Enter the data for the first polynomial\n");
struct node *poly1;
createList(&poly1);
display(poly1);
}
and example session:
Enter the data for the first polynomial
Enter coefficient and power: 1 2
Enter -1 to exit: 0
Enter coefficient and power: 3 4
Enter -1 to exit: -1
1x^2 3x^4
Consider reading a char instead of a int for the loop control (newline is continue, and 'q' could be quit). If you separate the UI from data structure manipulation then it will much easier to test your code (non-interactively). Write a function to free your list, and call that in the end. This will allow you to use a tool like valgrind to search for memory leaks.
For the first part of your question, I can't reproduce the issue. I changed the line scanf("%d", &ch); to ch = -1, and my output was: "123123123bbbbbbEnter -1 to exit99991", which does not match your output. Are you sure that your code compiled correctly?
For the second part of your question, the reason why you are getting a segment fault, is because you are not actually creating a new node for every polynomial. You only have one instance of a node, and in the while-loop, you constantly change the attributes of that node. In order for this to work, you have to create a new node for every polynomial, and insert that node into the list.
Some stylistic remarks:
It makes more sense to immediately assign a variable when you declare it. For example, in your code it happens a lot that you create a variable like this: int num;, and on the next line: num = 5;, for different datatypes and values. It makes more sense to immediately write: int num = 5;.
You declared poly1, poly2 and poly3, but you are only using poly1. You declared these variables globally, and then changed the contents of poly1 in a function. In order to optimally scope your variables, it makes more sense to write: struct Node *poly1 = createList();.
The code with these remarks implemented looks like this:
#include <stdio.h>
#include <stdlib.h>
struct Node {
struct Node* next;
int coeff;
int power;
};
struct Node* createNode(){
struct Node *head = malloc(sizeof(struct Node));
//error check if malloc failed.
if(head == NULL) {
exit(-1);
}
printf("Enter coefficient and power\n");
scanf("%d %d", &head->coeff, &head->power);
head->next = NULL;
return head;
}
struct Node *createList(){
int ch=0;
struct Node* head = NULL;
struct Node* temp = NULL;
while(ch != -1){
struct Node* newNode = createNode();
if(head == NULL) {
head = newNode;
temp = newNode;
} else {
temp->next = newNode;
temp = newNode;
}
printf("Enter -1 to exit");
scanf("%d",&ch);
}
return head;
}
void display(struct Node* head) {
while(head != NULL) {
printf("%dx^%d ",head->coeff,head->power);
head=head->next;
}
}
I'm new to DSA and currently learning linked-list. I was trying to create an entire linked list in one function. The first scanf in createList function doesn't seem to assign the input to the address provided(i.e. &n). I tried printing n right after scanf. It doesn't print n to console at all.
As a result, the output is not the way I expected. I can't figure out why.
//ENTIRE CODE HERE
#include<stdio.h>
#include<stdlib.h>
struct node {
struct node* prev;
int data;
struct node* next;
};
void print_nodes(struct node* );
struct node* addToEmpty(struct node*, int);
struct node* addAtEnd(struct node*, int);
struct node* createList(struct node*);
int main() {
struct node* head = NULL;
head = createList(head);
print_nodes(head);
}
void print_nodes(struct node* head) {
struct node* ptr = head;
while (ptr != NULL) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n");
}
struct node* addToEmpty(struct node* head, int data) {
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
head = temp;
return head;
}
struct node* addAtEnd(struct node* head, int data) {
struct node* tp = head;
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
while (tp->next != NULL) {
tp = tp->next;
}
tp->next = temp;
temp->prev = tp;
return head;
}
struct node* createList(struct node* head) {
int n, data, i;
printf("Enter the number of nodes: ");
scanf("%d ", &n);
if (n == 0)
return head;
printf("Enter the element of node 1: ");
scanf("%d ", &data);
head = addToEmpty(head, data);
for (i = 1; i < n; i++) {
printf("Enter the element of node %d: ", i + 1);
scanf("%d", &data);
head = addAtEnd(head, data);
}
return head;
}
your problem is so simple , instead of scanf("%d ", &n); , just write scanf("%d", &n); by which I mean to remove the wite space after %d as it's producing some strange behavior in your case , as if you refer to scanf() manual page , they say that :
A sequence of white-space characters (space, tab, newline,
etc.; see isspace(3)). This directive matches any amount
of white space, including none, in the input.
which is supposed to ignore any whitespace after the number entered till getting a valid char.
and here is the full code but with this only small modification:
#include<stdio.h>
#include<stdlib.h>
struct node {
struct node* prev;
int data;
struct node* next;
};
void print_nodes(struct node* );
struct node* addToEmpty(struct node*, int);
struct node* addAtEnd(struct node*, int);
struct node* createList(struct node*);
int main() {
struct node* head = NULL;
head = createList(head);
print_nodes(head);
}
void print_nodes(struct node* head) {
struct node* ptr = head;
while (ptr != NULL) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n");
}
struct node* addToEmpty(struct node* head, int data) {
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
head = temp;
return head;
}
struct node* addAtEnd(struct node* head, int data) {
struct node* tp = head;
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
while (tp->next != NULL) {
tp = tp->next;
}
tp->next = temp;
temp->prev = tp;
return head;
}
struct node* createList(struct node* head) {
int n, data, i;
printf("Enter the number of nodes: ");
scanf("%d", &n);
if (n == 0)
return head;
printf("Enter the element of node 1: ");
scanf("%d", &data);
head = addToEmpty(head, data);
for (i = 1; i < n; i++) {
printf("Enter the element of node %d: ", i + 1);
scanf("%d", &data);
head = addAtEnd(head, data);
}
return head;
}
and this is the output:
Enter the number of nodes:3
Enter the element of node 1:1
Enter the element of node 2:2
Enter the element of node 3:3
1 2 3
I tried out your code and found issues with the space in the literal string in the "scanf" statements. I see that someone else found that and offered up the solution to that with the cleanup of the "scanf" statements. I would say that if you are to accept an answer, select the first one. However, I just wanted to also offer up my code snippet with a couple of additional tweaks.
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node* prev;
int data;
struct node* next;
};
void print_nodes(struct node* );
struct node* addToEmpty(struct node*, int);
void addAtEnd(struct node*, int); /* No requirement for a node to be returned as the pointers are all set up in the function */
struct node* createList(struct node*);
int main()
{
struct node* head = NULL;
head = createList(head);
print_nodes(head);
}
void print_nodes(struct node* head)
{
struct node* ptr = head;
while (ptr != NULL)
{
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\n");
}
struct node* addToEmpty(struct node* head, int data)
{
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
//head = temp;
return temp; /* Return the pointer to the new struct - no need for update of head here */
}
void addAtEnd(struct node* head, int data)
{
struct node* tp = head;
struct node* temp = malloc(sizeof(struct node));
temp->prev = NULL;
temp->data = data;
temp->next = NULL;
while (tp->next != NULL)
{
tp = tp->next;
}
tp->next = temp;
temp->prev = tp;
return;
}
struct node* createList(struct node* head)
{
int n, data, i;
printf("Enter the number of nodes: ");
scanf("%d", &n);
if (n == 0)
return head;
printf("Enter the element of node 1: ");
scanf("%d", &data);
head = addToEmpty(head, data);
for (i = 1; i < n; i++)
{
printf("Enter the element of node %d: ", i + 1);
scanf("%d", &data);
addAtEnd(head, data);
}
return head;
}
First off, since there is not a need to return a "struct" pointer in the function "addAtEnd", I revised that to be a "void" function return signature. Second, in the "addToEmpty" function, one can just return the pointer value in "temp" instead of placing the value into the input parameter "head"; however, it works either way. It is just a matter of choice.
As a sample, here is some output data at the terminal.
#Una:~/C_Programs/Console/CompleteList/bin/Release$ ./CompleteList
Enter the number of nodes: 4
Enter the element of node 1: 65535
Enter the element of node 2: 2458
Enter the element of node 3: -44
Enter the element of node 4: 3258779
65535 2458 -44 3258779
I would suggest trying out both iterations.
Other answers have pointed at the specific problem you experienced (bad scanf() parameter string).
Going beyond that, however, there are two other "issues(?)".
First is to "create an entire linked list in one function".
In your code, main() calls only one function, but that function uses two "helper" functions to get the job done.
Every line of code is an opportunity for a bug to lurk unseen.
Re-using code is a way to reduce the chances for bugs to appear.
Secondly, the code appears to be correct, but does not prove that the doubly linked list is anything more than a singly linked list.
Both of these matters are addressed below creating (in one function, and later demonstrating) a circular doubly linked list.
Comments explain changes from the original code to this version.
Finally, an additional function is used here to prevent memory leaks.
#include <stdio.h>
typedef struct node { // Using 'typedef' saves lots of typing (and reading
int data;
struct node *next;
struct node *prev; // conventional layout of members
} node_t; // Notice '_t' as conventional suffix for user declared datatypes
node_t *print_nodes( node_t *head ) { // return pointer for use by caller
if( head ) { // insurance against NULL pointer
node_t *pn = head;
printf( "Forward: " ); // exercise circular LL in both directions
do {
printf( "%d ", pn->data );
pn = pn->next; // NB: 'next'
} while( pn != head ); // circular, not linear! One full circuit
puts( "" );
printf( "Reverse: " );
pn = pn->prev; // shift 'back' one node to begin
do {
printf( "%d ", pn->data );
pn = pn->prev; // NB: 'prev'
} while( pn != head->prev ); // circular, not linear! One full circuit
puts( "" );
}
return head;
}
node_t *createList() { // Create "one ring to rule them all"
int n = 0; // ALWAYS initialise variables
do {
printf( "Number of nodes (min 3): ");
scanf( "%d", &n ); // 'while' protects against bad input
} while( n < 3 );
node_t *head = NULL;
for( int i = 0; i < n; i++ ) {
printf( "Enter the element of node %d: ", i + 1 );
node_t *pn = (node_t *)calloc( 1, sizeof *pn ); // 'calloc()' zeros the block
/* check 'pn == NULL' omitted for brevity */
scanf("%d", &pn->data ); // read directly into destination (fewer variables)
if( head == NULL )
head = pn->prev = pn->next = pn; // 1st node, circular
else {
pn->prev = head->prev; // other nodes spliced-in ahead of 'head'
pn->next = head;
head->prev->next = pn;
head->prev = pn;
}
}
return head;
}
void freemem( node_t *head ) { // VERY important to respect "heap" storage!
if( head == NULL ) return;
node_t *pn = head; // traverse releasing nodes along the way
do {
node_t *pdel = pn;
pn = pn->next;
free( pdel );
} while( pn != head );
}
int main() {
// create, print, release, done...
freemem( print_nodes( createList() ) );
return 0;
}
Output
Number of nodes (min 3): 5
Enter the element of node 1: 42
Enter the element of node 2: 56
Enter the element of node 3: 10
Enter the element of node 4: -5
Enter the element of node 5: 256
Forward: 42 56 10 -5 256
Reverse: 256 -5 10 56 42
This code implements and proves a circular doubly linked list. The example can be trivially adapted to a linear dbl-LL by severing the connection between head and head->prev after the ring has been formed, and then making necessary adjustments at other locations to account for the change.
I have written a linked list program which stores data member as void *.
while trying to store annd print using scanf/printf functions, I am getting segmentation fault.
node definition -->
typedef struct node {
struct node *next;
void *data;
}node;
main function -->
head=(node *)malloc(sizeof(node));
if (head==NULL){
printf("error in allocation of memory\n");
exit(EXIT_FAILURE);
}
tail=(node*)create(head);
create function -->
void *create(node *current)
{
int user_choice;
while(current){
printf("\nEnter the data:");
scanf("%s",current->data);
printf("stored at %p\n",(void*)current->data);
printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
current=current->next;
}
else{
current->next=NULL;
}
}
return current;
}
can anyone tell what is the correct argument for scanf & prinf should be..?
working code after incorporating points given in answers...
void *create(node *current)
{
node *temp;
int user_choice;
while(current){
printf("\nEnter the data:");
current->data=(char*)malloc(10*sizeof(char));
scanf("%s",current->data);
printf("stored at %p\n",(void*)current->data);
printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
}
else{
current->next=NULL;
temp=current;
}
current=current->next;
}
return temp;
}
In your code,
scanf("%s",current->data);
is attempt to make use of an unitialized pointer, it invokes undefined behavior.
You need to follow either of bellow approach,
make the pointer point to valid chunk of memory (using malloc() and family for dynamic allocation, for example)
use an array.
You should first initialize data member of structure because
current->data = malloc("passes size here");
For putting data you have to typecast first this data because void is not storage type. void pointer can be used to point to any data type.
Like
*(char *)(current->data) = 1;
As others have said:
scanf("%s",current->data);
Is undefined in C. current->data needs to be pointing somewhere before you can store anything in it.
You should instead:
Accept input from scanf.
Store in temporary buffer.
Insert into linked list
print out whole linked list at the end
free() linked list at the end.
I also feel that your current void *create function is doing too much, and it would be easier to split up your code into different functions, just to make it easier to handle all the pointer operations, inserting etc.
To demonstrate these points, I wrote some code a while ago which does these things, and has been modified to help you with your code. It is not the best code, but it does use these points that will help you with your code.
Here it is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTRLEN 100
typedef struct node {
void *data;
struct node *next;
} node_t;
typedef struct {
node_t *head;
node_t *foot;
} list_t;
list_t *create_list(void);
node_t *generate_node(void);
list_t *insert_node(list_t *list, char *data);
void print_list(list_t *list);
void free_list(list_t *list);
int
main(int argc, char *argv[]) {
list_t *list;
char data[MAXSTRLEN];
int user_choice;
list = create_list();
while (1) {
printf("Enter the data: ");
scanf("%s", data);
printf("\nType '1' to continue, '0' to exit:\n");
if (scanf("%d",&user_choice) != 1) {
printf("Invalid input\n");
exit(EXIT_FAILURE);
}
if (user_choice == 1) {
list = insert_node(list, data);
} else {
list = insert_node(list, data);
break;
}
}
print_list(list);
free_list(list);
list = NULL;
return 0;
}
/* inserting at foot, you can insert at the head if you wish. */
list_t
*insert_node(list_t *list, char *data) {
node_t *newnode = generate_node();
newnode->data = malloc(strlen(data)+1);
strcpy(newnode->data, data);
newnode->next = NULL;
if (list->foot == NULL) {
list->head = newnode;
list->foot = newnode;
} else {
list->foot->next = newnode;
list->foot = newnode;
}
return list;
}
node_t
*generate_node(void) {
node_t *new = malloc(sizeof(*new));
new->data = NULL;
return new;
}
void
print_list(list_t *list) {
node_t *curr = list->head;
printf("\nlinked list data:\n");
while(curr != NULL) {
printf("%s\n", (char*)curr->data);
curr = curr->next;
}
}
list_t
*create_list(void) {
list_t *list = malloc(sizeof(*list));
if (list == NULL) {
fprintf(stderr, "%s\n", "Error allocating memory");
exit(EXIT_FAILURE);
}
list->head = NULL;
list->foot = NULL;
return list;
}
void
free_list(list_t *list) {
node_t *curr, *prev;
curr = list->head;
while (curr) {
prev = curr;
curr = curr->next;
free(prev);
}
free(list);
}
UPDATE:
Also note how I allocated memory for newnode->data?
Like this:
newnode->data = malloc(strlen(data)+1); //using buffer from scanf
This now means I can store data in this pointer, your current->data will need to do something similar.
working code-->
void *create(node *current)
{
node *temp;
int user_choice;
while(current){
printf("\nEnter the data:");
current->data=(char*)malloc(10*sizeof(char));
scanf("%s",current->data);
printf("stored at %p\n",(void*)current->data);
printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
}
else{
current->next=NULL;
temp=current;
}
current=current->next;
}
return temp;
}
Please try with this
void *create(node *current)
{
int user_choice;
while(true){
if(current == NULL) {
current = (node *)malloc(sizeof(node));
current->data = NULL;
current->next = NULL;
}
printf("\nEnter the data:");
scanf("%s",current->data);
printf("stored at %p\n", (void *)current->data);
printf("%s",current->data);
//printf("%s",(char*)current->data);
printf("\nType '1' to continue, '0' to exit:\n");
scanf("%d",&user_choice);
if(user_choice == 1){
current->next=(node*)malloc(sizeof(node));
current=current->next;
}
else{
current->next=NULL;
tail = current;
current=current->next;
break;
}
}
return current;
}
Note: The element has to be initialized (ie; it has to be alloted with some memory) before we are trying to make use of it.
When printing out my linked list, what is displayed is not what I assumed it to be. How do I get the right output?
struct node{
int data;
struct node *next;
};
struct node *newNode(int data){
struct node *new_node=(struct node *) malloc(sizeof(struct node));
new_node->data=data;
new_node->next=NULL;
return new_node;
}
void push(struct node*** head, int data){
struct node* new_node=newNode(data);
new_node->next=(**head);
(**head)=new_node;
}
void create(struct node **number, char num[]){
int x=0;
while(x<strlen(num)){
int d=(int)(num[x]);
push(&number, d);
x++;
}
}
void printList(struct node *number){
while(number!=NULL){
printf("%d", number->data);
number=number->next;
}
printf("\n");
}
int main (void){
struct node *first;
char num1[10];
scanf("%s", num1);
create(&first, num1);
printList(first);
return 0;
}
Examples
Input : 1
Expected Output: 1
Actual Output : 49
Input : 12345
Expected Output: 12345
Actual Output : 5352515049
I think it is printing where the value is stored, not the value itself.
Correct me on that if that's wrong. Anyways how do I get the expected output I want.
The problem is that you are reading ascii values, and then trying to print integers, and since you need to store integers and not the ascii values all you need is a simple mathematical operation, i.e. subtract the ascii value of the digit '0', so to convert the ascii value of a digit to it's integer value all you need is
integer = ascii - '0';
here I fixed your code, because you were appending the value to the head of the list instead of it's tail
#include <stdlib.h>
#include <stdio.h>
struct node{
int data;
struct node *next;
};
struct node *newNode(int data)
{
struct node *new_node;
new_node = malloc(sizeof(struct node));
if (new_node == NULL) /* always check that malloc succeeded */
return NULL;
new_node->data = data;
new_node->next = NULL;
return new_node;
}
struct node *push(struct node *tail, int data)
{
struct node *new_node;
new_node = newNode(data);
if (tail != NULL)
return tail->next = new_node;
return new_node;
}
struct node *create(char *numbers)
{
size_t i;
struct node *head;
struct node *tail;
i = 0;
head = NULL;
tail = NULL;
/* since strings are 'nul' terminated, you just need to loop,
* until you find the 'nul' byte, strlen() expects that byte
* anyway.
*/
while (numbers[i] != '\0')
{
tail = push(tail, numbers[i++] - '0');
if (head == NULL)
head = tail;
}
return head;
}
void printList(struct node *number)
{
while (number != NULL)
{
printf("%d", number->data);
number = number->next;
}
printf("\n");
}
void freeList(struct node *number)
{
while (number != NULL)
{
struct node *last;
last = number;
number = number->next;
free(last);
}
}
int main(void)
{
struct node *first;
char numbers[10];
/* '%9s' prevents buffer overflow */
if (scanf("%9s", numbers) != 1)
return -1;
first = create(numbers);
printList(first);
freeList(first);
return 0;
}
You have a linked list which ends up in reverse order, and this is why your second example comes out in reverse order. If you print the linked list like this:
printf("%d ", number->data);
with a space, it would be clearer what is happening, output is ASCII values
53 52 51 50 49
But you are also confusing character values with numeric values. If you correct this,
printf("%c ", number->data);
you will get your original input characters in reverse order.
5 4 3 2 1
I am working on a program that inserts into a linked-list in sorted order, but it keeps seg faulting, and I can't figure out why. I suspect it has something to do with the pointers, but I can't tell as these are still a little bit confusing to me at this point in my programming career. Also, I must keep the insert prototype the same. I can't change the node parameter into a double pointer. Thanks!
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<conio.h>
typedef struct node {
int data;
struct node *next;
};
int main ()
{
struct node* first;
int temp,x,y;
struct node *create (struct node *first);
first = NULL;
void display (struct node *first);
printf ("\n\nCreating a Linked List\n");
printf ("\nEnter Element: ");
scanf ("%d", &x);
y=x;
while(y>0)
{
scanf ("%d", &x);
insert_sorted_linked_list(first,x);
y--;
}
printf ("\nThe list after creation is: ");
display (first);
printf ("\nThe sorted list is: ");
display (first);
return(0);
} /*END OF MAIN*/
insert_sorted_linked_list(struct node* head, int val)
{
struct node* pCur;
struct node* pNew = (struct node*) (malloc(sizeof(struct node)));
pNew -> data = val;
pNew ->next = NULL;
pCur = head;
if( pCur->data == NULL )
{
head->data = pNew->data;
head->next = NULL;
}
else if (pNew->data < pCur->data)
{
pNew ->next = pCur ;
head = pNew;
}
}
void display (struct node *first)
{ struct node *save; /*OR sort *save */
if (first == NULL)
printf ("\nList is empty");
else
{ save = first;
while (save != NULL)
{ printf ("-> %d ", save->data);
save = save->next;
}
getch();
}
return;
}
EDIT: Changed main to int. The debugger doesn't like the lines:
struct node* pNew = (struct node*) (malloc(sizeof(struct node)));
if( pCur->data == NULL )
Not sure what is wrong though.
EDIT 2:
I decided i wasn't going to get it working the original way he ask for it before tomorrow morning, so I went a modified version posted here. That one didn't seg fault, but it turns out there was a logic error as well.
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<conio.h>
typedef struct s
{
int data;
struct s *next;
}node;
void insert_sorted_linked_list(node **head, int val);
void display (node **first);
void freeList(node **first);
int main ()
{
node* first;
int x,y;
first = NULL;
printf ("\n\nCreating a Linked List\n");
printf ("\nEnter number of elements: ");
scanf ("%d", &x);
y=x;
while(y>0)
{
scanf ("%d", &x);
insert_sorted_linked_list(&first,x);
y--;
}
printf ("\nThe sorted list is: ");
display (&first);
freeList(&first);
return 0;
}
void insert_sorted_linked_list(node **head, int val)
{
node* pCur;
node* pNew = (node*) (malloc(sizeof(node)));
pNew->data = val;
pNew->next = NULL;
pCur = (*head);
if( pCur == NULL )
{
(*head) = pNew;
}
else if(pNew->data < pCur->data)
{
pNew->next = pCur;
(*head) = pNew;
}
else
{
while(pCur->next!=NULL && pNew->data > pCur->next->data)
pCur = pCur->next;
pNew->next = pCur->next;
pCur->next = pNew;
}
}
void display (node **first)
{
node *lisprint; /*OR sort *lisprint */
if (*first == NULL)
printf ("\nList is empty");
else
{
lisprint = *first;
while (lisprint != NULL)
{
printf ("-> %d ", lisprint->data);
lisprint = lisprint->next;
}
getch();
}
} /*END OF FUNCTION DISPLAY*/
void freeList(node **first)
{
node *i;
i = *first;
while(i !=NULL)
{
(*first) = (*first)->next;
free(i);
i = *first;
}
}
Thanks!
Please properly format your code! It was a pain in the a** just to see where the error was!
As it is,
/*PROGRAM TO CREATE & THEN DISPLAY THE LINKED LIST IN SORTED FORM*/
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<conio.h>
typedef struct s
{
int data;
struct s *next;
}node;
/* your declaration for typedef was incorrect. We use typedef in C for structures so that we do not have to repeat struct s everytime. Using typedef, we can write node as we do in c++ */
void insert_sorted_linked_list(node **head, int val); /* do not need to return anything, as well as see the parameter. When we want to change a pointer, we pass the address to the pointer, as it results in passing by value */
void display (node **first); /* same here and below */
void freeList(node **first); /* if you don't do this, memory leak!!! */
int main ()
{
node* first; /*OR sort *first,*list,*pass */
int temp,x,y;
first = NULL; /*OR sort *create() */
printf ("\n\nCreating a Linked List\n");
printf ("\nEnter number of elements: "); /* specify what you want the user to enter */
scanf ("%d", &x);
y=x;
while(y>0)
{
scanf ("%d", &x);
insert_sorted_linked_list(&first,x); /*CALLING CREATE FUNCTION, notice the &first*/
y--;
}
printf ("\nThe list after creation is: ");
display (&first);
printf ("\nThe sorted list is: ");
display (&first);
freeList(&first);
return 0;
} /*END OF MAIN*/
void insert_sorted_linked_list(node **head, int val)
{
node* pCur;
node* pNew = (node*) (malloc(sizeof(node)));
pNew->data = val;
pNew->next = NULL;
pCur = (*head);
if( pCur == NULL )
{
(*head) = pNew;
}
else if (pNew->data < pCur->data)
{
pNew->next = pCur ;
(*head) = pNew;
}
}
/*DISPLAY FUNCTION*/
void display (node **first)
{
node *save; /*OR sort *save */
if (*first == NULL)
printf ("\nList is empty");
else
{
save = *first;
while (save != NULL)
{
printf ("-> %d ", save->data);
save = save->next;
}
getch();
}
} /*END OF FUNCTION DISPLAY*/
void freeList(node **first)
{
node *i;
i = *first;
while(i !=NULL)
{
(*first) = (*first)->next;
free(i);
i = *first;
}
}