c - 我将如何阅读并将此文本文件的信息分成数组?
问题描述
假设我有一个文本文件,例如:
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.
*/
}
}
解决方案
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
推荐阅读
- java - Spring Boot 找不到 EmbeddedKafkaBroker Bean
- regex - 正则表达式按日期过滤我的日志
- javascript - 在 react js 的同一个组件中预览并上传两个单独的图像
- python - 使 matplotlib 图占据整个 Canvas 区域
- c# - 打印时 devexpress GridView RowAutoHeight 不起作用
- c# - 如何使用正则表达式分隔方括号内的字符串和双精度值
- implicit - 自动隐式未解决,即使它应该是封闭条件下的直接函数应用
- javascript - 在剑道图中检查形状的点击事件有哪些不同的方法
- .net - 为什么 Chirp 的 Windows .net 库会丢失第二个、第四个、第六个等数据包?
- python - 相同(但重新排序)列表返回不同的 scipy.stats.linregress 输出