I created a code that inserts and deletes nodes from a Linked List depending on what a .txt file instructs. I previously used scanf("%s",fname) to open the file but now I want to open it using the command line, specifically argv[1] == file name to open it and read from it. Now that I decided to use this I keep getting a segmentation fault. Any ideas why this is occurring? I just started taking a C course in my University and am brand new to it.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct node{
int val;
struct node *next;
} Node;
void count_node(Node *head){
Node *temp;
int i=0;
temp = head;
while(temp!=NULL){
i++;
temp=temp->next;
}
printf("number of nodes are %d \n ",i);
}
void displayList(Node *head){
Node *temp;
temp = head;
while(temp != NULL){
printf(" %d ",temp->val);
temp = temp->next;
}
}
Node * findBefore(Node *head,int value){
Node *curr = head;
Node *prev = NULL;
while(curr != NULL){
if(value <= curr->val){
return prev;
}
prev = curr;
curr = curr->next;
/*printf("a\n");
break;*/
}
return prev; // 1 2 4
//printf("b\n");
}
void add(Node *head,int newValue){ //return a Node 0 for some reason
ask TA
printf("check \n");
Node *newNode = malloc(sizeof(Node));
if(newNode == NULL){
printf("check \n");
return;
}
newNode->val = newValue;
//if list is empty:
if(head == NULL){
printf("check \n");
head = newNode;
}
//if list is not empty:
Node *prev = findBefore(head,newNode->val); //a -> b
if(prev == NULL){
printf("check \n");
newNode->next = head;
head = newNode;
return;
}
printf("check \n");
Node *temp = prev->next;
prev->next = newNode;
newNode->next = temp;
}
void delete(Node *head, int delVal){
if(head == NULL){
return;
}
Node *prev = NULL;
Node *curr = head;
if(delVal == curr->val && prev !=NULL ){ // 1 2
prev->next = curr->next;
free(curr);
return;
}
else if(delVal == curr->val && prev == NULL){ // 1
head = NULL;
free(curr);
return;
}
while(curr != NULL) {
while(curr != NULL && curr->val != delVal){
prev = curr;
curr = curr->next;
}
if (curr == NULL){
return;
}
prev->next = curr->next;
free(curr);
curr = prev->next;
}
}
int main(int argc,char *argv[]) {
FILE * fp;
char singleLine[150];
char command;
int val;
fp = fopen(argv[1],"r");
if(fp == NULL ){
exit(1);
}
Node *head = malloc(sizeof(Node));
if(head == NULL){ //malloc returns null is there is a memory leak
return 1;
}
while(fgets(singleLine,100,fp)){
//printf("%s\n",singleLine);
sscanf(singleLine,"%c %d",&command,&val);
//printf("command character is: %c\n" , command);
//printf("The value we have to add is: %d\n",val);
if(command == 'i'){
printf("Found i, and add %d\n",val);
add(head,val);
}
else if(command == 'd'){
delete(head,val);
printf("found d and delete %d\n",val);
}
}
free(head);
fclose(fp);
printf("\n");
count_node(head);
printf("The linked list is : \n ");
displayList(head);
return 0;
}
What is the command you are using to run the program? Especially in larger projects, when we need to deal with external input, it's good practice to check it's validity.
Maybe something like:
if (argc < 2) {
println("Invalid input: No arguments");
return 1;
}
char *filename = argv[1];
fp = fopen(filename,"r");
To see what may be the reason the call is failing. Try to add this short debug code before your call to argv[1]:
println("Number of arguments: %d", argc);
for (int i = 0, i < argc, i++) {
println("Argument %d: \"%s\"", i, argv[i]);
}
Related
I created a standard linked list in C. It asks the user to input a number, and program end if user input #. If the user inputs anything else the program will stop.
The problem is that my program runs forever and prints the normal list at first then keeping print the last element of the linked list.
Hope someone could tell me where did I made mistake.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NodeT;
void freeLL(NodeT *list) {
NodeT *p, *temp;
p = list;
while (p != NULL) {
temp = p->next;
free(p);
p = temp;
}
}
void showLL(NodeT *list) {
NodeT *temp = list;
temp = temp->next;
printf("Done. The list is ");
printf("%d", temp->data);
temp = temp->next;
//iterate the entire linked list and print the data
while (temp != NULL) {
printf("-->");
printf("%d", temp->data);
temp = temp->next;
}
}
NodeT *joinLL(NodeT *list, int v) {
NodeT *current = list;
NodeT *head;
head->data = v;
head->next = NULL;
while (current->next != NULL) {
current = current->next;
}
current->next = head;
return head;
}
int main() {
int data;
NodeT *list = NULL;
list = (NodeT *)malloc(sizeof(NodeT));
printf("Enter a number: ");
if (scanf("%d", &data) != 1) {
printf("Done. ");
} else {
printf("Enter a number: ");
joinLL(list, data);
while (1 == scanf("%d", &data)) {
printf("Enter a number: ");
joinLL(list, data);
}
showLL(list);
freeLL(list);
}
return 0;
}
I believe the problem is in the joinLL function which add a new node at the end of the linked list.
The problem is you do not allocate elements in joinLL: only a single element in allocated in main().
You should instead always allocate the element in joinLL and update the head pointer from the return value.
Similary, freeLL should take a pointer to head and set it to NULL for consistency.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} NodeT;
void freeLL(NodeT *p) {
while (p != NULL) {
NodeT *temp = p->next;
free(p);
p = temp;
}
}
void showLL(const NodeT *list) {
NodeT *p = list;
printf("The list is ");
if (p == NULL) {
printf("empty");
} else {
printf(" %d", temp->data);
while ((p = p->next) != NULL) {
printf("--> %d", temp->data);
}
}
printf("\n");
}
NodeT *joinLL(NodeT *head, int v) {
NodeT *newp = malloc(sizeof(*p));
NodeT *current;
if (newp == NULL) {
fprintf(stderr, "allocation failure\n");
exit(1);
}
newp->data = v;
newp->next = NULL;
if (head == NULL) {
return newp;
}
for (current = head; current->next != NULL; current = current->next)
continue;
current->next = newp;
return head;
}
int main() {
NodeT *list = NULL;
for (;;) {
int data;
printf("Enter a number: ");
if (scanf("%d", &data) != 1) {
printf("Done. ");
break;
}
list = joinLL(list, data);
}
showLL(list);
freeLL(list);
return 0;
}
Your program keeps running because of a memory access error, you did not allocate memory for your head(you set a pointer, but use it directly without initializing it)
Change to this may solve the problem:
head=(NodeT*)malloc(sizeof(NodeT));
if(NULL==head)
{
// failed : do something...
return NULL;
}
head->data=v;
head->next=NULL;
When I just tested it, I found that there was another problem:
list = (NodeT*)malloc(sizeof(NodeT));
malloc will not be initialize your list, so the value that your list->next initially points to is uncertain.
in c, malloc does not need to be cast.
The idea is to be able to add a name to the end of the linked list when the user enters "1" and print and delete the first name in the linked list when the user enters "0". This is working if there is only 2 names in the linked list but anymore than 2 it only does the first name and last name, yet I cannot see my error.
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define bool int
#define TRUE 1d
#define FALSE 0
typedef struct node{
char name[100];
struct node *next;
} Node;
Node *head;
void call(){
if(head == NULL){
printf("List is empty.\n");
}
else{
Node *temp;
printf("Calling %s\n", head->name);
if(head->next!=NULL){
temp = head->next;
free(head);
head = temp;
}
else{
head = NULL;
}
}
}
void add(char input[]){
Node *temp;
temp = (Node*)malloc(sizeof(Node));
strcpy(temp->name, input);
temp->next = NULL;
if(head == NULL){
head = temp;
}
else{
head->next = temp;
}
}
int main(){
start:;
int user_menu_answer;
char waste;
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
printf("0) Call a customer\n");
printf("1) Add a customer\n");
printf("2) Quit\n");
printf("Please input your command \n");
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n");
scanf("%d%c", &user_menu_answer, &waste);
//main menu options
if(user_menu_answer == 0){
call();
goto start;
}
else if (user_menu_answer == 1){
char input[23];
printf("Please give me the customers name: \n");
scanf("%[^\n]", input);
add(input);
goto start;
}
else if (user_menu_answer == 2){
printf("Quitting...");
return 0;
}
else{
printf("You did not enter a valid option, Please try again. \n");
goto start;
}
}
First MISTAKE:
void call(){
if(head == NULL){
printf("List is empty.\n");
}
else{
Node *temp;
printf("Calling %s\n", head->name);
if(head->next!=NULL){
temp = head->next;
free(head);
head = temp;
}
else{
free(head); //you don't free the memory if it's just one in the list
head = NULL;
}
}
}
Second mistake:
void add(char input[]){
Node *AuxHead; //create an aux to the head so you can move threw the list
Node *temp;
temp = (Node*)malloc(sizeof(Node));
if(temp!=NULL) //verify if it got allocated
{
strcpy(temp->name, input);
temp->next = NULL;
if(head == NULL){
head = temp;
}
else{
AuxHead=head; //pass the address of the head
while(AuxHead->next!=NULL) //catch the lest node of the list
AuxHead=AuxHead->next;
AuxHead->next = temp; //make the temp, the last of the list
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Lists seem really hard for me. I want to find the smallest element in a file: 1 5 8 6 4 8 6 48 9. It's 1 and I want to delete that 1. I can find the smallest element but can not delete it. I find the smallest element place but not the value. I tried copying deleting function from the web, however I cant understand it due to the fact that I'm really new to C. It writes an error that dereferencing to incomplete type. Please help. Post whole code because it should be more convenient to understand.
#include <stdio.h>
#include <stdlib.h>
typedef struct linkedList {
int value;
struct linkedList *next;
} linkedList, head;
linkedList *readList(linkedList *head) {
FILE *dataFile;
dataFile = fopen("duom.txt", "r");
if (dataFile == NULL) {
printf("Nepasisekė atidaryti failo\n");
} else {
printf("Duomenų failą pavyko atidaryti\n");
}
while (!feof (dataFile))
if (head == NULL) {
head = malloc(sizeof(linkedList));
fscanf(dataFile, "%d", &head->value);
head->next = NULL;
} else {
struct linkedList *current = head;
struct linkedList *temp = malloc(sizeof(linkedList));
while (current->next != NULL) {
current = current->next;
}
fscanf(dataFile, "%d", &temp->value);
current->next = temp;
temp->next = NULL;
}
return head;
}
void search(linkedList *head, int *lowest) {
int a[100];
int i = 0;
int minimum;
int b = 0;
linkedList *current = head;
while (current != NULL) {
a[i] = current->value;
current = current->next;
i++;
}
b = i;
i = 0;
minimum = a[0];
while (b > 0) {
if (minimum > a[i]) {
minimum = a[i];
lowest = i;
}
i++;
b--;
}
}
void deleteNode(struct node **head_ref, int key) {
struct node* temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next; // Changed head
free(temp); // free old head
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL)
return;
prev->next = temp->next;
free(temp);
}
void printList(linkedList *head) {
linkedList *current = head;
while (current != NULL) {
printf("%d->", current->value);
current = current->next;
}
printf("NULL\n");
return;
}
int main() {
linkedList *A = NULL;
A = readList(A);
search(A);
head = head->next;
minimum = head->value;
headk->next = head->next;
free(head);
printList(A);
return 0;
}
like this
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef struct linkedList{
int value;
struct linkedList *next;
} linkedList, node;
linkedList *readList(void){
FILE *dataFile;
dataFile = fopen("duom.txt", "r");
if(dataFile == NULL) {
perror("file open");
return NULL;
}
int v;
node head = {0, NULL}, *curr = &head;
while (1 == fscanf(dataFile, "%d", &v)){
node *new_node = malloc(sizeof(node));
if(new_node == NULL){
perror("malloc");
break;
}
new_node->value = v;
new_node->next = NULL;
curr = curr->next = new_node;
}
fclose(dataFile);
return head.next;
}
int searchMin(linkedList *head){
if(head == NULL){
fprintf(stderr, "%s: The list MUST NOT be NULL.\n", __func__);
return INT_MIN;
}
int min = head->value;
node *p = head->next;
while(p){
if(p->value < min)
min = p->value;
p = p->next;
}
return min;
}
void deleteNode(node **head_ref, int key){
node *curr = *head_ref, *prev = NULL;
while (curr != NULL && curr->value != key){
prev = curr;
curr = curr->next;
}
if (curr == NULL) return;//not found
if(prev)
prev->next = curr->next;
else
*head_ref = curr->next;
free(curr);
}
void printList(linkedList *head){
node *current = head;
while (current != NULL) {
printf("%d->", current->value);
current = current -> next;
}
puts("NULL");
}
void freeList(linkedList *list){
while(list){
node *temp = list;
list = list->next;
free(temp);
}
}
int main(void){
linkedList *A = readList();
int min = searchMin(A);
printList(A);
deleteNode(&A, min);
printList(A);
freeList(A);
return 0;
}
Please try if this program can help you.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
struct node {
int data;
struct node *next;
};
void push(struct node **head_ref, int new_data) {
struct node *new_node = (struct node *) malloc(sizeof(struct node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void deleteNode(struct node **head_ref, int key) {
struct node *temp = *head_ref, *prev;
if (temp != NULL && temp->data == key) {
*head_ref = temp->next;
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return;
prev->next = temp->next;
free(temp);
}
void printList(struct node *node) {
while (node != NULL) {
printf(" %d ", node->data);
node = node->next;
}
}
void min(struct node **q) {
struct node *r;
int min = INT_MAX;;
r = *q;
while (r != NULL) {
if (r->data < min) {
min = r->data;
}
r = r->next;
}
printf("The min is %d", min);
deleteNode(q, min);
printf("\n");
}
int main() {
struct node *head = NULL;
FILE *file = fopen("duom.txt", "r");
int i = 0;
fscanf(file, "%d", &i);
while (!feof(file)) {
push(&head, i);
fscanf(file, "%d", &i);
}
fclose(file);
puts("Created Linked List: ");
printList(head);
min(&head);
puts("\nLinked List after Deletion of minimum: ");
printList(head);
return 0;
}
file duom.txt
1 5 8 6 4 8 6 48 9
Test
./a.out
Created Linked List:
9 48 6 8 4 6 8 5 1 The min is 1
Linked List after Deletion of minimum:
9 48 6 8 4 6 8 5 ⏎
I'm writing a programm in c that reads words from a file, and adds the different from them in a linked list. However, i don't get the right result.I have problem finding if a word exists in the list. Any help could be appreciated.Thanks.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct list_el {
char val[30];
struct list_el * next;
};
typedef struct list_el item, item2;
void main() {
item * curr, * head, * curr2, * head2;
FILE *fp;
char words[30];
int i;
head = NULL;
head2 = NULL;
if ((fp=fopen("file.txt","r"))==NULL)
printf("cannot open file\n");
i=0;
while (fscanf(fp,"%s",&words)!=EOF) {
if (i!=0)
while(curr2) {
if (!strcmp(words,curr2->val)){
break;
}
curr2 = curr2->next ;
}
if (curr2==0 || i==0){
curr = (item *)malloc(sizeof(item));
curr2 = (item2 *)malloc(sizeof(item2));
strcpy(curr->val,words);
strcpy(curr2->val,words);
curr->next = head;
curr2->next = head2;
head = curr;
head2 = curr2;
}
i++;
}
while(curr) {
printf("%s\n", curr->val);
curr = curr->next ;
}
fclose(fp);
}
int main(void) {//void main() is invalid.
item *curr, *head = NULL;
FILE *fp;
char words[30];
if ((fp=fopen("file.txt","r"))==NULL){
printf("cannot open file\n");
return EXIT_FAILURE;//can't continue
}
while (fscanf(fp,"%29s", words) != EOF) {//remove &
curr = head;
while(curr) {//Search the current list
if (!strcmp(words, curr->val)){
break;
}
curr = curr->next;
}
if (curr == NULL){//not find words
item *node = malloc(sizeof(*node));
strcpy(node->val, words);
node->next = head;
head = node;
}
}
fclose(fp);
curr = head;
while(curr) {
printf("%s\n", curr->val);
curr = curr->next ;
}
}
I am trying to implement a doubly linked list that acts like a queue (I want it to act like queue).
[EDIT]
When I add nodes to the list (e.g 5 nodes) and empty the list (delete all elements) and try to add another node to the list again, it gives me a segmentation fault (core dumped) error.
linkedlist.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node{
int d;
struct node *prev;
struct node *next;
}node;
typedef struct linkedlist{
int size;
struct node *first;
struct node *last;
}linkedlist;
linkedlist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkedlist.h"
linkedlist* createList(){
linkedlist* myList = (linkedlist*)calloc(1,sizeof(linkedlist));
myList->first = NULL;
myList->last = NULL;
myList->size =0;
return myList;
}
static node* createNode(int n){
node *myNode = (node*)calloc(1,sizeof(node));
myNode->d = n;
myNode->prev = NULL;
myNode->next = NULL;
return myNode;
}
void insertNode(linkedlist* l, int num){
node *temp, *newNode;
newNode = createNode(num);
if (l->size == 0){
newNode->next = NULL;
newNode->prev = NULL;
l->first = newNode;
l->last = newNode;
l->size++;
}
else{
temp = l->first;
while (temp->next != NULL){
temp = temp->next;
}
newNode->prev = temp;
temp->next = newNode;
newNode->next = NULL;
l->size++;
}
}
int deleteNode(linkedlist* l){
node *temp = calloc(1,sizeof(node));
if (l->first ==NULL){
return -1;
}
else if (l->size ==1){
free(l->first);
l->first= NULL;
l->last = NULL;
l->size--;
}
else if (l->size > 1){
temp = l->first;
l->first = temp->next;
free(temp);
}
}
void display(linkedlist *l){
node *temp = calloc(1,sizeof(node));
temp = l->first;
if (temp == NULL){
printf("The list is empty\n");
}
while (temp != NULL) {
printf("-> %d ", temp->d);
temp = temp->next;
}
}
int main(){
linkedlist *myList = createList();
int choice, temp=0, numb;
printf("(1) Insert \n (2) Delete \n");
for (temp; temp<10; temp++){
printf("Choice :");
scanf ("%d", &choice);
switch(choice) {
case 1: {
printf("Enter a Number: ");
scanf("%d", &numb);
insertNode(myList, numb);
display(myList);
break;
}
case 2:{
deleteNode(myList);
display(myList);
break;
}
}
}
}
In your delete node function:
else if (l->size > 1){
temp = l->first;
l->first = NULL; //this is problem
l->first->next = NULL;
temp->next = l->first;
l->first->prev = NULL;
You are assigning l->first = NULL and then accessing it in next statement l->first->next = NULL;, which will fail and give you segmentation fault.
Also, when l->size == 1 you should also set l->first = NULL after freeing it.
The problem appears when access to a "NULL" position. Let's revise the code:
temp = l->first;
l->first = NULL; // here, you set l->first = 0
l->first->next = NULL; // here, you access to 0->next: this is not correct.
temp->next = l->first;
Change it for:
temp = l->first;
l->first = temp->next;
delete temp;
int deleteNode(linkedlist* l){
node *temp= (node*)malloc(sizeof(node)) ;
if (l->first ==NULL){
return -1;
}
else
{
temp= l->first;
l->first= temp->next;
l->first->previous= temp;
l->size--;
free(l->first->previous);
}
}
In the deleteNode you leave first pointing to freed memory if the size is 1
It should be:
else if (l->size ==1){
free(l->first);
l->first = NULL;
l->last = NULL;
l->size--;
}
Also temp is a pointer you don't need to allocate memory for it with malloc