简体   繁体   中英

Problem reading at most two lines in text file, C

I am having trouble reading a specific amount of words from a text file. The program i have so far reads two strings from a text file, and stores it in a linked list. However, the values read from the text file should be:

(Command) (Value)

in that order and no more than that. If I add an extra command or value it stores that string in the next node of the list and shifts everything by one. My problem is that I cannot find a way to error check for extra commands on the same line in the text file. My initial thought was to just read the first two strings and ignore anything else on the line. If there are any other ways to solve this problem please do tell me so. Any help to improve my code is appreciated!

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


/*This typedefs a struct...*/
typedef struct LinkedListNode
{
    char* commandstring;
    char* valuestring;
    char valueint;
    struct LinkedListNode *next;
}LINKEDLISTNODE;


int main (int argc, char *argv[])
{
    FILE* fp;
    LINKEDLISTNODE *current, *head, *temp;

    int integer_check;

    head = NULL;
    current = head;


    fp = fopen (argv[1], "r");


    /*This will set a buffer to find the maximum length we need for the buffer. The max length will be the length of the longest line in the text file.*/
    fseek(fp,0, SEEK_END);
    long filesize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char* buffer = malloc(filesize + 1);

    char tempCommand[filesize];
    char tempValue[filesize];


    /*Initialise linked list with the same amount of nodes that the text file has lines*/
    while(fgets(buffer, filesize, fp) != NULL)
    {
        LINKEDLISTNODE* node = malloc(sizeof(LINKEDLISTNODE));
        node->commandstring = (char*)malloc(sizeof(char)*8);
        node->valuestring = (char*)malloc(sizeof(char)*5);
        node->next = NULL;

        if (head == NULL)
        {
            head = node;
            current = head;
        }
        else
        {
            current->next = node;
            current = current->next;
        }
    }



    /*Allocate the command string to the command field and the value string to the value field:*/
    current = head;
    rewind(fp);
    while(current != NULL)
    {
        fscanf(fp, "%s %s\n", current->commandstring, current->valuestring);
        current = current->next;
    }


    /*Print the list to make sure the strings are set correctly in the fields*/ 
    current = head;
    rewind(fp);
    while(current != NULL)
    {
        printf("node[%p]:[%s],[%s] \n", current->commandstring, current->commandstring, current->valuestring);
    current = current->next;
    }
    /*Free each node:*/
    current = head;
    while(current != NULL)
    {
        temp = current->next;
        current = temp;
    }

    free(head);
    free(temp);
    free(current);
    fclose (fp);

    return (0);
}

Try this loop:

while (current != NULL) {

  char temp[8 + 5 + 1];

  if (fgets(temp, sizeof(temp), fp) != NULL) {

    const char* space = strchr(temp, ' ');

    if (space == NULL) {
      strcpy(current->commandstring, temp);
      *current->valuestring = 0;
    }
    else {
      strncpy(current->commandstring, temp, space - temp);
      strcpy(current->valuestring, space + 1);
    }

    /* rest of your loop code */
  }

}

You can allocate space and pass your values in the same loop. You can use strtok to get the string until the first occurance of space and strdup to allocate space and assign the value at the same time. So now if you have more than one (command) (value) on the same line it will be added.

while(fgets(buffer, filesize, fp) != NULL) {

    char * command = strtok(buffer, " \n");
    char * value = NULL;

    while ((value = strtok(NULL, " \n")) != NULL) {

        LINKEDLISTNODE* node = malloc(sizeof(LINKEDLISTNODE));

        node->commandstring = strdup(command);
        node->valuestring = strdup(value);
        node->next = NULL;

        if (head == NULL) {

            head = node;
            current = head;
        }

        else {

            current->next = node;
            current = current->next;
        }

        command = strtok(NULL, " \n");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM