我将如何去阅读这个文本文件的信息并将其分离到数组中?
How would I go about reading and separating this text file's information into arrays?
假设我有一个文本文件,例如:
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.
*/
}
}
有一个名为 strtok() 的函数:https://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm
虽然我从来没有用过它,但有一次我不得不这样做,我实现了一个函数,它将一个字符串分成一个指向字符指针的指针数组,并为整个块动态分配内存,它会查找逗号并在每次找到逗号时生成一个新字符串,我的代码在您的情况下不起作用,因为它是专门为忽略空格而编写的,但是如果您不忽略它们而是将它们用作分隔符,则代码会得到一个简单多了。
编辑:至于从文件中获取信息,我会创建一个大小荒谬的缓冲区,例如 32768 字节并使用 fgets(buffer, 32768, pf),尽管您可能想添加一个检查以查看是否即使是 32K 个字符也不足以读取和处理它,尽管我认为没有必要。
这也是我曾经实现的函数的原型,让您更好地了解您必须编写的代码:
char **separete_string (char *string, char delim);
void free_string_list (char **list);
这个答案可能不完整,但至少可以帮助您处理文本文件中的行。
假设输入文件为file.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] = '[=11=]'; /*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
假设我有一个文本文件,例如:
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.
*/
}
}
有一个名为 strtok() 的函数:https://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm
虽然我从来没有用过它,但有一次我不得不这样做,我实现了一个函数,它将一个字符串分成一个指向字符指针的指针数组,并为整个块动态分配内存,它会查找逗号并在每次找到逗号时生成一个新字符串,我的代码在您的情况下不起作用,因为它是专门为忽略空格而编写的,但是如果您不忽略它们而是将它们用作分隔符,则代码会得到一个简单多了。
编辑:至于从文件中获取信息,我会创建一个大小荒谬的缓冲区,例如 32768 字节并使用 fgets(buffer, 32768, pf),尽管您可能想添加一个检查以查看是否即使是 32K 个字符也不足以读取和处理它,尽管我认为没有必要。
这也是我曾经实现的函数的原型,让您更好地了解您必须编写的代码:
char **separete_string (char *string, char delim);
void free_string_list (char **list);
这个答案可能不完整,但至少可以帮助您处理文本文件中的行。
假设输入文件为file.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] = '[=11=]'; /*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