Warm tip: This article is reproduced from serverfault.com, please click

How would I go about reading and separating this text file's information into arrays?

发布于 2020-11-28 01:33:03

Suppose I have a text file such as:


Adam: Tall Handsome Kind Athlete
  He enjoys playing basketball

Sabrina: Short Pretty Funny Adorable Gymnast
  She loves gymnastics

Sinclair: Blonde
  He is blonde

Assume the file has several more people, each with a Name and then 0 or more characteristics about them and then a new line with a tab following a sentence underneath. For example,

Adam: would be the name

Tall Handsome Kind Athlete would be 4 individual characteristics

He enjoys playing basketball would be the sentence.

I want to store this information in a structure like so:

typedef struct People {
 char *name;
 char **characteristics;
 char *sentence;
} People;

typedef struct List {
  People **list;
  int total_ppl;
} List;

int main (void) {
 List *ppl_list = malloc(sizeof(List));
 ppl_list->list = malloc(sizeof(People));
 int i = 0;
 FILE *pf = fopen("input.txt", "r");
 if (pf == NULL) {
    printf("Unable to open the file");
 } else {
   
/*    I'm not sure how to go about reading the information from here. I was thinking about using
      fscanf but I don't know how to separate and store the Name, each Characteristic, and 
      the sentence separately. I know I will need to realloc ppl_list as more people are read from the 
      file. If I should change my structs to organize it better, please let me know.
*/

 }
}
Questioner
Fred Vann
Viewed
0
21.1k 2020-11-28 12:49:20

This answer is maybe not complete but it will help you, at least, with the processing of the lines in the text file.

Assuming a file.txt as the input file, and with the following format

Adam: Tall Handsome Kind Athlete
  He enjoys playing basketball

Sabrina: Short Pretty Funny Adorable Gymnast
  She loves gymnastics

Sinclair: Blonde
  He is blonde

We can process this file as follows

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


/*process_info_line: process the line with the name and attributes*/
int process_info_line(char *line)
{
    char *next = NULL;
    char *part = strtok_r(line, ":", &next);
    if (part)
        printf("NAME: %s\n", part);
    else
        return 0;

    while (part != NULL) {
        part = strtok_r(NULL, " ", &next);
        if (part)
            printf("ATTRIBUTE: %s\n", part);
    }

    return 0;
}

/*process_sentence: process the line with the sentence*/
char *process_sentence(char *line)
{
    line = line + 4;
    return line;
}

/*is_sentence: checks if the line is a sentence, given your definition
 * with a tab(or 4 spaces) at the begining*/
int is_sentence(char *line)
{
    if (strlen(line) == 0)
        return 0;

    char *ptr = line;
    int space_count = 0;

    while (ptr != NULL) {
        if (strncasecmp(ptr, " ", 1) != 0) {
            break;
        }
        space_count++;
        ptr++;
    }

    if (space_count == 4)
        return 1;

    return 0;
}

/*scan_file: read each of the lines of the file and use
 * the previous functions to process it.*/
int scan_file(char *filename)
{
    char *line_buf = NULL;
    size_t line_buf_size = 0;
    ssize_t line_size;
    int line_count = 0;

    FILE *fp = fopen(filename, "r");
    if (!fp) {
        fprintf(stderr, "Error opening file '%s'\n", filename);
        return 1;
    } 
    /*Get the first line of the file*/
    line_size = getline(&line_buf, &line_buf_size, fp);
    while (line_size >= 0)
    {
        line_count++;
        line_buf[line_size-1] = '\0'; /*removing '\n' */
        if (is_sentence(line_buf)) {
            printf("SENTENCE: %s\n", process_sentence(line_buf));
        } else {
            process_info_line(line_buf);
        }
        
        line_size = getline(&line_buf, &line_buf_size,fp);
    }

    // don't forget to free the line_buf used by getline
    free(line_buf);
    line_buf = NULL;
    fclose(fp);

    return 0;
}


int main(void)
{
    scan_file("file.txt");
    return 0;
}

This will generate the following output

NAME: Adam
ATTRIBUTE: Tall
ATTRIBUTE: Handsome
ATTRIBUTE: Kind
ATTRIBUTE: Athlete
SENTENCE: He enjoys playing basketball
NAME: Sabrina
ATTRIBUTE: Short
ATTRIBUTE: Pretty
ATTRIBUTE: Funny
ATTRIBUTE: Adorable
ATTRIBUTE: Gymnast
SENTENCE: She loves gymnastics
NAME: Sinclair
ATTRIBUTE: Blonde
SENTENCE: He is blonde