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

c-我将如何读取该文本文件的信息并将其分离为数组?

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

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

假设我有一个文本文件,例如:


Adam: Tall Handsome Kind Athlete
  He enjoys playing basketball

Sabrina: Short Pretty Funny Adorable Gymnast
  She loves gymnastics

Sinclair: Blonde
  He is blonde

假设文件中还有其他几个人,每个人都有一个名称,然后有0个或更多与它们有关的特征,然后在一行下面加上一个带有制表符的新行。例如,

亚当:是这个名字

高个子的善良运动员将是4个个性特征

他喜欢打篮球

我想将此信息存储在这样的结构中:

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
11
21.1k 2020-11-28 12:49:20

这个答案可能还不完整,但是至少可以帮助你处理文本文件中的行。

假设将afile.txt作为输入文件,并采用以下格式

Adam: Tall Handsome Kind Athlete
  He enjoys playing basketball

Sabrina: Short Pretty Funny Adorable Gymnast
  She loves gymnastics

Sinclair: Blonde
  He is blonde

我们可以如下处理该文件

#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;
}

这将生成以下输出

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