This program takes multiple file names as command-line arguments and finds out the number of words in each file and how many times each word appears (i.e., the frequency) in all files. Specifically, the program will first determine the number of files to be processed. Then, the program will create multiple threads (one for each file). Each thread will count the number of words for the given file. In addition, each thread will access a global linked-list and update the number of times each word appears in all files.
However, I cannot print the word in each node. When I tried:
printf("%s appears %d times\n", node->word, node->count);
I got a segmentation fault.
Thread 1: number of words in File:input_file_1.txt is 6
Thread 2: number of words in File:input_file_2.txt is 14
All 2 files have been counted and the total of 20 words found !
Segmentation fault: 11
There's something wrong when I push nodes in linked list or print the linked list but I couldn't figure it out. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <pthread.h>
struct thread_info {
pthread_t thread_id; /* ID returned by pthread_create() */
int thread_num; /* Application-defined thread # */
char * filename; /* From command-line argument filename */
};
// A linked list node
struct Node{
char * word;
int count;
struct Node * next;
};
struct Node * head = NULL;
static int totalWordCount = 0;
void push(struct Node **head, char * new_data){
struct Node * new_node = (struct Node * ) malloc(sizeof(struct Node));
struct Node *last = *head;
new_node->word = new_data;
new_node->count = 1;
new_node->next = NULL;
if (*head == NULL) {
*head = new_node;
return;
}
while (last->next != NULL)
last = last->next;
last->next = new_node;
return;
}
bool search(struct Node **head, char * x){
struct Node * current = *head; // Initialize current
while (current != NULL){
if (strcmp(current, x) == 0){
current->count++;
return true;
}
current = current->next;
}
return false;
}
// This function prints contents of linked list starting from head
void printList(struct Node *head){
struct Node *node = head;
while (node != NULL){
printf("%s appears %d times\n", node->word, node->count);
node = node->next;
}
}
void * processFile(void * vargp){
int numberofwords = 0;
// Store the value argument passed to this thread
struct thread_info * tinfo = vargp;
FILE * fp;
fp = fopen(tinfo->filename, "r"); // read mode
if (fp == NULL){
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
char word[100];
while (fscanf(fp, "%s", word) != EOF) {
if (search(&head,word)){
} else{
push(&head, word);
}
numberofwords+=1;
}
printf("Thread %d: number of words in File:%s is %d\n", tinfo->thread_num, tinfo->filename, numberofwords);
totalWordCount += numberofwords;
fclose(fp);
}
int main(int argc, char const * argv[]){
pthread_t thread_id;
char ch, file_name[25];
int numberoffile = argc-1;
for (size_t i = 0; i < numberoffile; i++){
struct thread_info tinfo;
tinfo.thread_num = i + 1;
tinfo.filename = argv[i + 1];
pthread_create( & tinfo.thread_id, NULL, processFile, & tinfo);
pthread_join(tinfo.thread_id, NULL);
}
printf("All %d files have been counted and the total of %d words found !\n", argc - 1, totalWordCount);
printList(head);
//printf("%s appears %d times\n", head->word, head->count);
return 0;
}
Thank you so much!