我需要读取一个文件并将其放在双链表中的结构中。
但是我的方法int insert_File(List* pointer_to_pointer)
不起作用.有人可以帮忙吗?我该如何解决它?如何读取此文件并将其正确放置在结构中的每个变量中?谢谢大家。
/* ListStudent.h */
struct student
{
char name[30];
int cod_student;
float test_1, test_2, activity, test_optional; /* if test_optional not exist in list_students.txt complete with 0 in struct */
};
typedef struct element* List;
int insert_File(List* pointer_to_pointer);
/* ListStudent.cpp */
struct element
{
struct element *previous;
struct student database;
struct element *next;
};
int insert_File(List* pointer_to_pointer)
{
if(pointer_to_pointer == NULL)
return 0;
element *node = *pointer_to_pointer;
FILE *pointer_to_file;
struct student s;
pointer_to_file = fopen("list_students", "r");
if(NULL == pointer_to_file)
{
cout << "ERROR";
return 1;
}
while(fread(&s, sizeof(struct student), 1, pointer_to_file))
{
int a = insert_list_sorted_ascending_by_name(pointer_to_pointer, s);
}
fclose(pointer_to_file);
return 0;
}
/* ListStudent_main.cpp */
#include "ListStudent.cpp"
int main(){
List *pointer_to_pointer;
pointer_to_pointer = create_list();
int f = insert_File(pointer_to_pointer);
return 0;
}
文件 txt
Marcos David 885487 9.4 5.4 8.5 0
Victor Corleone 445587 9.8 5.7 9.5 9
Alban Sernen 115400 8.4 8.4 5.5
Alban Aline 775487 1.4 2.4 1.5 1.1
Alban Victor 905487 2.4 2.6 4.5 1.5
文件中的数据表示形式与内存中的数据表示形式不同。
例如,内存中的int
值由精确的固定字节数(在现代硬件上通常为四个(组成,而文本中的数字由一系列可变的字节组成。此外,字节的值也不相同。
文本文件中的885487
由字节0x38 0x38 0x35 0x34 0x38 0x37
组成,而内存中的相同数字(提供 32 位 int(看起来像0xEF 0x82 0x0D 0x00
(小端表示!
其他成员的大小也不匹配,此外,二进制数据成员之间不会有空格字符 (0x20(。
例如:首次调用fread(&s, sizeof(struct student), 1, pointer_to_file)
后s
内的数据:
name == "Marcos David 885487 9.4 5.4 8." // you read EXACTLY 30 chars
cod_student == 170 926 133 // "5 0n" interpreted as 32-bit int (little endian)
test_1 == <some value> // "Vict" interpreted as 32-bit float
test_2 == <some value> // "or C" interpreted as 32-bit float
activity == <some value> // "orle" interpreted as 32-bit float
test_optional == <some value> // "one " interpreted as 32-bit float
我没有努力将字符转换为实际的浮点值,假设很明显这些值不会是你真正想要的值......我假设 unix 行尾 – 如果您使用 windows 行尾,那么n
前面会有一个额外的r
字符,将用于填充浮点数的字符移动 1,但这不会改变读取不需要的数据的任何内容。
您现在有两个选择:
要么将学生已经存储为二进制文件(在写作时,使用
"wb"
选项打开文件,用于阅读使用"rb"
,以确保不会对换行符进行特殊处理(。请注意,该文件将不再是人类可读的!或者您需要将文本数据转换为二进制数据。
对于后一种选择,我个人会逐行读取文件(C:fgets;C++:std::getline(并自行解析这些行。
您不幸的情况是,您为数据项选择了分隔符,该分隔符也可能出现在其中一个数据字段中:空格字符。如果您将字段分隔符更改为其他内容(例如|
– 还有特殊的分隔符,ASCII 0x1C – 0x1F,非常适合我们的阅读目的,但很难在文本编辑器中输入......(,那么你会让你的生活更轻松:只需用这个分隔符标记字符串并转换子字符串。
现在,您将在字符串中查找第一个数字(假设数字不会出现在名称中(,并将前面的字符(最后一个空格除外(复制到名称字段中。不要忘记以 null 终止字符串。
从现在开始,你可以从之前找到的数字开始标记化。在 C 语言中,看看用于标记化的 strtok 函数以及用于转换的 strtol 和 strtof。
在C++中(正如您最初标记的那样(,有很多不同的方法可以处理剩余的字符串(也许使用std::istringstream
最简单的方法(。