0

I am trying to read from a file called data.txt. and store it into a LL which looks like this

Quanta 2
New 2
Ready 2
A 1 3 
B 3 4
C 5 6
D 7 9

I would like to read that file, one line at a time, storing each line at a node in a LL, e.g A 1 3, will be at one node.

The desired layout is this

Name    Value
Quanta  2
New     2
Ready   2
-------------------------
Process   NUT   AT
A         1     3
B         3     4
C         5     6
D         7     9

I have wrote the following code, which does read from the file and displays results for name and value correctly, however I do not understand how can I make it so it reads one line at a time and stores that one line into specific node.

This is what my code Currently displays:

Name | Value|

3       1
4       3
6       5
9       7
A       1
B       3
C       5
D       7
New     2
Quanta  2
Ready   2

I have tried to solve this for quiet a while now, I have officially hit a mental block, I would appreciate any help you can offer.

Code:

                #include <stdlib.h>
            #include <stdio.h>
            #include <string.h>

            #define NAME_LENGTH 20
            #define PROCESS_LENGTH 20



            //create quanta structure.

            typedef struct Quanta
            {
                char* name;
                int Value;

                struct Quanta *next;
            }Quanta; 


            Quanta* new_Q(char*, int);
            Quanta* insert_by_Q(Quanta*, Quanta*);
            void print_list(Quanta*);

            int main() 
            {
                FILE *in;
                char* name = (char*)malloc(sizeof(char*) * NAME_LENGTH);
                char filename[25];
                int Value = 0;
            //1. --------------Error Checking-----------------
                printf("File name please:\n");
                gets(filename);

                in = fopen(filename, "rb");
                if (in == NULL)
                {
                    printf("The input file failed to open.\n");
                    printf("Program cannot continue. Exiting. . .\n");
                    return 1; //Exit Program
                }
                //2. ------Linked List Operations------
                Quanta* head = NULL; //Create Empty Linked List
                Quanta* current = NULL;
                while(!feof(in)) //Check for file end
                {
                    //Read first data value to kickstart.
                    if(fscanf(in, "%s %d ", name,&Value) == EOF) 
                    {
                        break;
                    }

                    Quanta* hold = new_Q(name, Value);
                    head = insert_by_Q(head, hold);
                }

                //3. ------Print the new List------
                print_list(head);
                return 1; //Exit Success
            }

            Quanta* new_Q(char* name, int Value) {

                //Create new Quanta and malloc space
                Quanta* new = (Quanta*)malloc(sizeof(struct Quanta));
                new->name = (char*)malloc(sizeof(char) * NAME_LENGTH);
                //Set data
                strcpy(new->name, name);
                new->Value = Value;
                new->next = NULL;
                //Retun a pointer to the node
                return new;

            }

            //Inserts new node into an alphabetically sorted linked list.
            Quanta* insert_by_Q(Quanta* head, Quanta* new)
            {
                Quanta* current = NULL;
                current = head;
                if(current == NULL || strcmp(current->name, new->name) > 0)
                {
                    new->next = current;
                    return new;
                } else
                {
                    while(current->next != NULL && strcmp(current->next->name, new->name) < 0)
                    {
                        current = current->next;
                    }
                }
                    new->next = current->next;
                    current->next = new;
                    return head;

            }


            void print_list(Quanta* head)
            {
                Quanta* current;
                current = head;
                char p[] = "Name";
                char c[] = "Value";


                //Header
                printf("\n\n|%10s | %10s| \n", p, c);
                printf("-----------------------------------------------------------------------\n");


                while(current != NULL)
                {
                    printf("|%10s |%10d|\n", current->name, current->Value);
                    current = current->next;
                }
                printf("-----------------------------------------------------------------------\n");

                return;
            }
MHP
  • 61
  • 8
  • 1
    Please fix your code indentation. Thank you! – Tim Čas Feb 10 '15 at 15:11
  • Please read [why is `while (!foef(file))` always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). and [Do I cast the result of `malloc()`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Iharob Al Asimi Feb 10 '15 at 15:12
  • Your code indentation is not consistent. – Iharob Al Asimi Feb 10 '15 at 15:14
  • From line 4 onwards you have 2 integers and in the struct in which you want to store the data just has a single member `int value;` to hold this value so what exactly are you trying to do? Just read the whole line in the file and store it in structure and don't care for what is there in the line or fetch the contents of the line ? – Gopi Feb 10 '15 at 15:16
  • casting `malloc()` is not good, as you can read in the provided link, but you have a serious mistake too `malloc(sizeof(char *) * NAME_LENGTH);` is wrong, it should be `malloc(sizeof(char) * NAME_LENGTH);` and since `sizeof(char) == 1` then, `malloc(NAME_LENGTH);` – Iharob Al Asimi Feb 10 '15 at 15:19
  • I am in process of fixing the indentation, i do apologize after a few days of messing with it, it kinda took a solid hit. – MHP Feb 10 '15 at 15:19
  • further on, i would like to fetch the contents of the line as well, as i will be using them later on – MHP Feb 10 '15 at 15:20
  • You need to kinds of nodes and two linked lists - one for the lines that have two fields and the other for the lines that have three fields. – R Sahu Feb 10 '15 at 15:20
  • Don't use `gets()` replace it with `fgets()`. – Iharob Al Asimi Feb 10 '15 at 15:20
  • R Sahu, can u expand on that please?, iharob i have fixed the malloc issue, also i was looking into replacing it, with fgets(), i wrote a little separate code where i managed to use fgets to read one line at a time, however when it comes to combining them with the LL i struggled only managed to get it working using the gets() when LL was involded. – MHP Feb 10 '15 at 15:25
  • Also @Gopi yes i would like to fetch the contents of the line – MHP Feb 10 '15 at 15:26

1 Answers1

1
  typedef struct Quanta
    {
        char* name;
        int Value;
        int Value1; /* To hold the second integer from line 4 onwards */
        struct Quanta *next;
    } Quanta;

Use fgets() to read till end of file and after reading each line use sscanf() to fetch the required data. I have made an assumption here to store Value1=0 for the first 3 lines and for the rest of the lines this field is updated properly.

char buf[100];
char name[20];
int val=0,i=0,val1=0;
while(fgets(buf, sizeof(buf),in) != NULL)
{
  if(i<=2)
  {
    if(sscanf(buf,"%s %d",&name,&val) == 2)
    {
      Quanta* hold = new_Q(name, val,0);
      head = insert_by_Q(head, hold);
    }
  }
  else
  {
    if(sscanf(buf,"%s %d %d",&name,&val,&val1) == 3)
    {
      Quanta* hold = new_Q(name, val,val1);
      head = insert_by_Q(head, hold);
    }
  }
  i++;
}

Along with this fix

Quanta* new_Q(char*, int,int);

to hold the extra value from line 4 onwards.

While printing the make sure you take care when to print val1 and when not to.

Gopi
  • 19,784
  • 4
  • 24
  • 36
  • Hello thx for the response, did a couple of quick fixes, as couldnt use name as i have used it previously, just a quick question related to printing, if i wanted to add the extra 3rd field in my printout, would i need to consider anything or is it just a simple matter of printing an extra field? – MHP Feb 10 '15 at 16:02
  • @MHP print is always in your control. Just add a check while printing to take care when you want to print the `val1` – Gopi Feb 10 '15 at 16:24