使用带指针的结构读取二进制文件中的某个位置
Reading a certain position in a binary file using structs with pointers
我在二进制文件中存储了这样的结构:
typedef struct user {
char nick[6];
int n_following;
following *following;
}user;
它包含一个这种类型的结构数组:
typedef struct following{
char nick[6];
int last_message;
}following;
我想创建各种用户并将其存储在一个二进制文件中,每次我这样做时,我都会将他们在文件中的位置存储在哈希表中,以便以后能够使用 fseek() 查找他们,这是方面哈希表中的项目:
typedef struct user_pos {
char nick[6];
int position_in_file;
}user_pos;
我尝试实现上面的ideia并创建两个用户,然后尝试获取他们,但我只能获取一个,因为另一个破坏了程序。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct following{
char nick[6];
int last_message;
}following;
typedef struct user {
char nick[6];
int n_following;
following *following;
}user;
void insert_user(char *input_a, int n){
FILE *p;
p=fopen("users","ab");
user *new_user = malloc(sizeof(user));
strcpy(new_user->nick, input_a);
new_user->n_following = n;
new_user->following = malloc(sizeof(following) * new_user->n_following);
strcpy(new_user->following[0].nick, "la");
new_user->following[0].last_message = 0;
strcpy(new_user->following[1].nick, "zz");
new_user->following[1].last_message = 2;
fwrite(&new_user->nick, sizeof(new_user->nick), 1, p);
fwrite(&new_user->n_following, sizeof(new_user->n_following), 1, p);
fwrite(new_user->following, sizeof(following), new_user->n_following, p);
printf("user created\n");
fclose(p);
}
void get_user_info(char *input_a, int pos){
FILE *p;
p=fopen("users","rb");
user *print_user = malloc(sizeof(user));
fseek(p, pos* sizeof(user), SEEK_SET);
fread(&print_user->nick, sizeof(print_user->nick), 1, p);
fread(&print_user->n_following, sizeof(print_user->n_following), 1, p);
print_user->following = malloc(sizeof(following));
fread(print_user->following, sizeof(following), 2, p);
printf("nick: %s, following: %d\n", print_user->nick, print_user->n_following);
for(int i = 0; i < print_user->n_following; i++){
printf("nick: %s, last_read: %d\n", print_user->following[i].nick, print_user->following[i].last_message);
}
fclose(p);
}
int main(){
//hashtable *active_users = create();
char buffer[38];
char tipo;
int n;
char input_a[6];
while(fgets(buffer, 38, stdin)){
sscanf(buffer, "%c %s %d", &tipo, input_a, &n);
switch(tipo) {
case 'U' :
insert_user(input_a, n);
break;
case 'S' :
get_user_info(input_a, n);
break;
case 'X' :
exit(0);
default :
printf("Operacao invalida\n");
}
}
return 0;
}
程序因这种输入而失败:
input: U me 2
output: user created
input: U ro 2
output: user created
input: S me 0
output: nick: me, following: 2
nick: la, last_read: 0
nick: zz, last_read: 2
input: S ro 1//program breaks
为什么上面的程序找到了一个用户而不是另一个?
注意:我知道使用普通的 .txt 文件会更好,但我想使用 fseek() 函数的速度来获取文件中的用户
您不能调用 fseek(p, pos* sizeof(user), SEEK_SET);
跳转到文件中的 pos
用户。 sizeof(user)
returns user
结构的大小(以字节为单位),但此结构中有指针 following
,它指向由 following
对象填充的数组。如果你想跳到 pos
用户,你应该知道每个用户有多少个后续对象。您没有此信息,因此您可以逐个读取您的文件用户以达到 pos
用户。
// pseudocode
get_user_info (int pos) {
while (pos--) {
skip 6 bytes // nick
read 4 bytes n_following;
skip n_following * sizeof(following) bytes
}
// here you can read data of pos user
}
我在 get_user_info
函数中看到三个问题。
偏移量计算不包括 following
结构。该文件包含一个 user
结构和一些 following
结构,然后是下一个 user
结构。因此,如果不读取每个用户结构来获取 n_following
成员,就无法计算偏移量。
代码只有 malloc
s space 用于一个 following
结构,但随后将 2 个结构读入该内存。内存量应该是sizeof(following) * print_user->n_following
读取以下结构时,fread
使用硬编码 2 而不是 n_following
。
我在二进制文件中存储了这样的结构:
typedef struct user {
char nick[6];
int n_following;
following *following;
}user;
它包含一个这种类型的结构数组:
typedef struct following{
char nick[6];
int last_message;
}following;
我想创建各种用户并将其存储在一个二进制文件中,每次我这样做时,我都会将他们在文件中的位置存储在哈希表中,以便以后能够使用 fseek() 查找他们,这是方面哈希表中的项目:
typedef struct user_pos {
char nick[6];
int position_in_file;
}user_pos;
我尝试实现上面的ideia并创建两个用户,然后尝试获取他们,但我只能获取一个,因为另一个破坏了程序。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct following{
char nick[6];
int last_message;
}following;
typedef struct user {
char nick[6];
int n_following;
following *following;
}user;
void insert_user(char *input_a, int n){
FILE *p;
p=fopen("users","ab");
user *new_user = malloc(sizeof(user));
strcpy(new_user->nick, input_a);
new_user->n_following = n;
new_user->following = malloc(sizeof(following) * new_user->n_following);
strcpy(new_user->following[0].nick, "la");
new_user->following[0].last_message = 0;
strcpy(new_user->following[1].nick, "zz");
new_user->following[1].last_message = 2;
fwrite(&new_user->nick, sizeof(new_user->nick), 1, p);
fwrite(&new_user->n_following, sizeof(new_user->n_following), 1, p);
fwrite(new_user->following, sizeof(following), new_user->n_following, p);
printf("user created\n");
fclose(p);
}
void get_user_info(char *input_a, int pos){
FILE *p;
p=fopen("users","rb");
user *print_user = malloc(sizeof(user));
fseek(p, pos* sizeof(user), SEEK_SET);
fread(&print_user->nick, sizeof(print_user->nick), 1, p);
fread(&print_user->n_following, sizeof(print_user->n_following), 1, p);
print_user->following = malloc(sizeof(following));
fread(print_user->following, sizeof(following), 2, p);
printf("nick: %s, following: %d\n", print_user->nick, print_user->n_following);
for(int i = 0; i < print_user->n_following; i++){
printf("nick: %s, last_read: %d\n", print_user->following[i].nick, print_user->following[i].last_message);
}
fclose(p);
}
int main(){
//hashtable *active_users = create();
char buffer[38];
char tipo;
int n;
char input_a[6];
while(fgets(buffer, 38, stdin)){
sscanf(buffer, "%c %s %d", &tipo, input_a, &n);
switch(tipo) {
case 'U' :
insert_user(input_a, n);
break;
case 'S' :
get_user_info(input_a, n);
break;
case 'X' :
exit(0);
default :
printf("Operacao invalida\n");
}
}
return 0;
}
程序因这种输入而失败:
input: U me 2
output: user created
input: U ro 2
output: user created
input: S me 0
output: nick: me, following: 2
nick: la, last_read: 0
nick: zz, last_read: 2
input: S ro 1//program breaks
为什么上面的程序找到了一个用户而不是另一个?
注意:我知道使用普通的 .txt 文件会更好,但我想使用 fseek() 函数的速度来获取文件中的用户
您不能调用 fseek(p, pos* sizeof(user), SEEK_SET);
跳转到文件中的 pos
用户。 sizeof(user)
returns user
结构的大小(以字节为单位),但此结构中有指针 following
,它指向由 following
对象填充的数组。如果你想跳到 pos
用户,你应该知道每个用户有多少个后续对象。您没有此信息,因此您可以逐个读取您的文件用户以达到 pos
用户。
// pseudocode
get_user_info (int pos) {
while (pos--) {
skip 6 bytes // nick
read 4 bytes n_following;
skip n_following * sizeof(following) bytes
}
// here you can read data of pos user
}
我在 get_user_info
函数中看到三个问题。
偏移量计算不包括
following
结构。该文件包含一个user
结构和一些following
结构,然后是下一个user
结构。因此,如果不读取每个用户结构来获取n_following
成员,就无法计算偏移量。代码只有
malloc
s space 用于一个following
结构,但随后将 2 个结构读入该内存。内存量应该是sizeof(following) * print_user->n_following
读取以下结构时,
fread
使用硬编码 2 而不是n_following
。