I have a code that sorts a list, I can get it to sort when the list is hardcoded. I am now attempting to implement getting the list from an input file and running it the same way through the code then printing it to an output file. I am trying to get a scanned list from an input file to go through what I have (that is working) for sorting and for the result to be printed to an output file.
This is how I currently have it set up. What am I doing wrong? I am pretty new to coding. (I know I am including the whole code, but I am a little lost as to why I am unable to print out a sorted list of words and hope it will make it easier to understand seeing the whole thing). below is my code
CodePudding user response:
You have assigned *tmp to head. But I can see that head had always been NULL. So the loop is never entered, and nothing is being inserted to the list.
So what we'd need to do it first initialize head to a node instance
typdef struct node
{
char* data;
struct node *prev;
struct node *next;
}node;
head = malloc(sizeof(node));
then we assign it data.
head->attribute = value;
finally we set this pointer location value to our tmp pointer as well.
tmp = head;
no we can proceed with our loop
strings in C are represented as an array of chars, whose stored location points to the first element of the char array. the array must also end with a NULL chat '\0'. note that strlen(str) will return length of string without the NULL char so you must add 1 while mallocing to take this into sconsideration. i would advise not messing with strings unless absolutely necessary. by that I mean trying to manually manipulate them. this will introduce another set of problems not related to what we're working on in general. we should just use strncar(), strncpy() methods until c style strings become completely intuitive.
CodePudding user response:
I hope I understood right your question. I tried to fix the program like it will read a file and make a list of the data in the file.
I fixed some issues;
For the
transverse
function, i added a for loop and printed the data using%c
.while (temp != NULL) { for(i=0; temp->data[i]!='\0'; i ) { printf("%c\n", temp->data[i]); } temp = temp->next; }
I changed the
insertAtEnd
function like this;void insertAtEnd(FILE* f, char* data)
And naturally, in main function, calling this function changed like;
insertAtEnd(ifp, result[i]);
By the way for the following statement, my complier wanted me to express the temp
as char
, it said it was the first use of this. It also seems like you entered a space after &
.
insertAtEnd(ofp, &temp);
I added the following statements to the
main
function;argc -= optind; argv = optind;
I also changed this
ifp= fopen(ifilename, "r");
statement with thisifp= fopen("ifilename.txt", "r");
statement. I opened a text file namedifilename.txt
and wrote some data there.
I have this data in my text file; APPLE BANANA 8 1 9
So here's the full executable code;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include<string.h>
int debug = 0;
//Structure of double linked list
struct node
{
char* data;
struct node *prev;
struct node *next;
};
//linked list
struct node* head = NULL;
struct node* tail = NULL;
// Function to traverse the linked list
void traverse()
{
int i;
// List is empty
if (head == NULL) {
printf("\nList is empty\n");
return;
}
// Else print the Data
struct node* temp;
temp = head;
while (temp != NULL) {
for(i=0; temp->data[i]!='\0'; i ) {
printf("%c\n", temp->data[i]);
}
temp = temp->next;
}
}
// Function to insert at the front
// of the linked list
void insertAtEnd(FILE* f, char* data) {
//Create a new node
struct node *newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = data;
//If list is empty
if(head == NULL) {
//Both head and tail will point to newnode
head = tail = newnode;
//head's previous will point to NULL
head->prev = NULL;
//tail's next will point to NULL, as it is the last node of the list
tail->next = NULL;
}
else {
//newnode will be added after tail such that tail's next will point to newnode
tail->next = newnode;
//newnode's previous will point to tail
newnode->prev = tail;
//newnode will become new tail
tail = newnode;
//As it is last node, tail's next will point to NULL
tail->next = NULL;
}
}
void removeDuplicateNode() {
//Node current will point to head
struct node *current, *index, *temp;
//Checks whether list is empty
if(head == NULL) {
return;
}
else {
//Initially, current will point to head node
for(current = head; current != NULL; current = current->next) {
//index will point to node next to current
for(index = current->next; index != NULL; index = index->next) {
if(case_sensitive(current->data,index->data) == 0) {
//Store the duplicate node in temp
temp = index;
//index's previous node will point to node next to index thus, removes the duplicate node
index->prev->next = index->next;
if(index->next != NULL)
index->next->prev = index->prev;
//Delete duplicate node by making temp to NULL
temp = NULL;
}
}
}
}
}
int case_sensitive(char* strg1, char* strg2)
{
while( ( *strg1 != '\0' && *strg2 != '\0' ) && *strg1 == *strg2 )
{
strg1 ;
strg2 ;
}
if(*strg1 == *strg2)
{
return 0; // strings are identical
}
else
{
return *strg1 - *strg2;
}
}
void sortList() {
struct node *current = NULL, *index = NULL;
char* temp;
//Check whether list is empty
if(head == NULL) {
return;
}
else {
//Current will point to head
for(current = head; current->next != NULL; current = current->next) {
//Index will point to node next to current
for(index = current->next; index != NULL; index = index->next) {
//If current's data is greater than index's data, swap the data of current and index
//if(current->data>index->data)
if(case_sensitive(current->data,index->data) < 0) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
}
}
}
}
int main(int argc, char **argv)
{
extern char *optarg;
extern int optind;
int c, err = 0;
int cflag=0, dflag=0, oflag = 0, iflag=0;
static char usage[] = "usage: %s [-cd] [-o output_file_name] [input_file_name]\n";
//FILE variables
const char* ifilename;
const char* ofilename;
FILE *ifp;
FILE *ofp;
ifp = fopen("input_file_name.txt", "r");
ofp = fopen("output_file_name.txt", "w");
ifp = stdout;
//Default variables
//char *strs[7] = {"apple", "apple", "APPLE", "APPLE", "Apple", "banana", "BANANA"};
while ((c = getopt(argc, argv, "cdo:")) != -1)
switch (c)
{
case 'c':
cflag = 1;
break;
case 'd':
dflag = 1;
break;
case 'o':
oflag = 1;
ofilename = optarg;
break;
case '?':
err = 1;
break;
}
argc -= optind;
argv = optind;
/* see what we have */
printf("cflag = %d\n", cflag);
printf("dflag = %d\n", dflag);
printf("oflag = %d\n", oflag);
// file reading
fscanf(ifp, "%d, %d", &cflag, &dflag);
fprintf(ofp, "flags are (%d, %d).\n", &cflag, &dflag);
if (argv[optind] != NULL)
{
ifilename = argv[optind];
iflag = 1;
}
if (iflag == 1)
{
ifp= fopen("ifilename.txt", "r");
if (ifp == NULL)
{
fprintf(stderr, "Error: File not found.\n");
fprintf(stderr, usage, argv[0]);
exit(1);
}
char* result[20];
char* temp = (char*)malloc(sizeof(char) * 20);
int i= 0;
while (fscanf(ifp, "%s", temp) == 1)
{
result[i] = (char*)malloc(strlen(temp) 1);
strcpy(result[i], temp);
insertAtEnd(ifp, result[i]);
i ;
}
fclose(ifp);
}
else
{
/*
insertAtEnd(strs[0]);
insertAtEnd(strs[1]);
insertAtEnd(strs[2]);
insertAtEnd(strs[3]);
insertAtEnd(strs[4]);
insertAtEnd(strs[5]);
insertAtEnd(strs[6]); */
}
struct node* tmp = head;
while(tmp) {
int i;
tmp->data = strdup(tmp->data);
for (i = 0; tmp->data[i]!='\0'; i ) {
if(tmp->data[i] >= 97 && tmp->data[i] <= 122) {
tmp->data[i] = tmp->data[i] - 32;
}
}
tmp = tmp->next;
}
printf("BEFORE\n");
traverse();
printf("---------------\n");
printf("SORTED\n");
sortList();
traverse();
printf("---------------\n");
removeDuplicateNode();
printf("AFTER\n");
traverse();
// trying to print to file
char temp;
insertAtEnd(ofp, &temp);
// also for files
fclose(ifp);
fclose(ofp);
exit(0);
}
When I run the code, the output is like the following one;
cflag = 0
dflag = 0
oflag = 0
BEFORE
A
P
P
L
E
B
A
N
A
N
A
8
1
9
---------------
SORTED
B
A
N
A
N
A
A
P
P
L
E
9
8
1
---------------
AFTER
B
A
N
A
N
A
A
P
P
L
E
9
8
1