当我将数据写入文件然后我读取它们时,我创建了一个包含三个人(Code-Name-Sex)的二进制文件,它完全可以正常运行..
我希望下一个函数读取X人的所有信息(如果存在)。
语法:
#include <stdio.h>
struct alu{
int cod;
char name[30]; //alu[0]="juan" alu[1]="pedro" alu[2]="leo"
int sex;
};
int FSearch(char path[],char X[]) {
char Name[30];
FILE *arc;
arc=fopen(path,"rb");
fseek(arc,sizeof(int),SEEK_SET);
while (fread(Name,sizeof(char[30]),1,arc)) {
/*Here is when the errors happen..
The next sentence tell me that A.name don't have
the name from the second time*/
printf("%s and %s.",X,Name);
if (strcmp(Name,X)==0) return 1;
fseek(arc,2*sizeof(int),SEEK_CUR);
}
fclose(arc);
return 0
}
int main(int argc, char **argv)
{
char path[]="file.bin";
printf("\n%d",FSearch(path,"pedro"));
return 0;
}
输出如下:
pedro和juan.pedro和.pedro和。
0
这意味着找到了第一个名字('juan')但第二个和第三个名字不是(pedro和leo)。
有什么问题?
答案 0 :(得分:4)
fseek(arc,sizeof(int),SEEK_SET);
while (fread(Name,sizeof(char[30]),1,arc)) {
if (strcmp(A.name,X)==0) return 1;
fseek(arc,2*sizeof(int),SEEK_CUR); //--> ERROR
}
fseek(arc,sizeof(int),SEEK_SET);
while (fread(Name,sizeof(char[30]),1,arc)) {
if (strcmp(A.name,X)==0) return 1;
fseek(arc,2*sizeof(int)+sizeof(char[2]),SEEK_CUR); //--> SOLVED
}
问题是在while循环中第二个参数,从原点偏移的字节数,传递给fseek()
调用。它计算两个INT而不是两个CHAR(在到达第二个字符串之前)。您可以在sizeof(char[30])
调用后看到fread()
,它显示32个字节,但为字符串分配了30个字节。
为什么要再移动两个字节?因为任何字符串都在其末尾,保留字节(用于指示字符串的开头和结尾)。 e.g:
char a[10]="Example";
如果将其保存为二进制文件,则此文件的大小为12个字节。
答案 1 :(得分:1)
我会在每次循环中打印fread
调用的结果。我在第一个对象上打赌你在文件上击中了EOF。我的预测是第一个fread
调用返回1,其他调用返回0.
答案 2 :(得分:0)
我不知道你的二进制文件格式。 您的代码告诉二进制文件只有30个字符的名称。
struct alu{
int cod;
char name[30]; //juan - pedro - leo
int sex;
};
此结构大小不是38个字节。
检查结构尺寸。
printf("%d", sizeof(struct alu));
结构大小取决于您的编译器选项......
如果您的二进制格式格式不正确。
{ // 1st record
cod = 10
names[30] = "juan"
sex = 1
}
{ // 2nd record
cod = 20
names[30] = "pedro"
sex = 1
}
{ // 3rd record
cod = 12
names[30] = "leo"
sex = 2
}
查看您的代码。
#include <stdio.h>
#pragma pack(push, 1) or 4 or 8 depend on your binary format.
struct alu{
int cod;
char name[30]; //juan - pedro - leo
int sex;
};
#pragma pack(pop)
int FSearch(char path[],char X[]) {
char Name[30];
struct alu A;
FILE *arc;
arc=fopen(path,"rb");
//fseek(arc,sizeof(char[30]),SEEK_SET);
fseek(arc,0,SEEK_SET); // first record.
//while (fread(Name,sizeof(char[30]),1,arc)) {
while (fread(A,sizeof(A),1,arc)) {
/*Here is when the errors happen..
The next sentence tell me that A.name don't have
the name from the second time*/
printf("%s and %s.",X,A.name);
if (strcmp(A.name,X)==0) {
printf("Information of %s:\n",X);
//fshow_str(A);
fclose(arc);
return 1; // found
}
}
fclose(arc);
return 0; // not found
}
int main(int argc, char **argv)
{
char path[]="file.bin";
printf("\n%d",FSearch(path,"pedro"));
return 0;
}
cod大小取决于编译器OPTION !!!
int FSearch(char path[],char X[]) {
char Name[30];
struct alu A;
FILE *arc;
arc=fopen(path,"rb");
fseek(arc,0,SEEK_SET); // first record.
//while (fread(Name,sizeof(char[30]),1,arc)) {
while (1) {
//if ( -1 == fseek(arc,4,SEEK_CUR)) // Important!!! case structure pack(4) for skip cod or
// break;
if ( -1 == fseek(arc,8,SEEK_CUR)) // Important!!! case structure pack(8) for skip cod
break;
if (!fread(Name,sizeof(Name),1,arc))
break;
A.name = Name;
/*Here is when the errors happen..
The next sentence tell me that A.name don't have
the name from the second time*/
printf("%s and %s.",X,A.name);
if (strcmp(A.name,X)==0) {
printf("Information of %s:\n",X);
//fshow_str(A);
fclose(arc);
return 1; // found
}
}
//if ( -1 == fseek(arc,4,SEEK_CUR)) // Important!!! case structure pack(4) for skip sex or
// break;
if ( -1 == fseek(arc,8,SEEK_CUR)) // Important!!! case structure pack(8) for skip sex
break;
fclose(arc);
return 0; // not found
}
二进制文件和结构用4个字节组成。
// Attention! pragma pack(push, 4) needs!!!
// Your now running machine is 32 bits system.
// This source code will invoke addressing fault 64 bits NON Intel processor.
#pragma pack(push, 4) // align 4 bytes.
struct alu{
int cod; // Integer type. 4 bytes on 32bits system. but 8 bytes on 64 bits system.
// I recommend using "long" type. "long" type is 4 bytes on any system.
char name[30]; //juan - pedro - leo
int sex; // also, Integer type.
};
#pragma pack(pop)
int FSearch(char path[],char X[]) {
char Name[30];
struct alu A;
FILE *arc;
arc=fopen(path,"rb");
fseek(arc,0,SEEK_SET); // first record.
//while (fread(Name,sizeof(char[30]),1,arc)) {
while (1) {
if ( -1 == fseek(arc,4,SEEK_CUR)) // Skip "cod" 4 bytes.
break;
if (!fread(Name,sizeof(Name),1,arc)) // Read "name" 30 bytes.
break;
if ( -1 == fseek(arc,2,SEEK_CUR)) // Skip "name"'s aligned 2 bytes.
break;
A.name = Name;
/*Here is when the errors happen..
The next sentence tell me that A.name don't have
the name from the second time*/
printf("%s and %s.",X,A.name);
if (strcmp(A.name,X)==0) {
printf("Information of %s:\n",X);
//fshow_str(A);
fclose(arc);
return 1; // found
}
}
if ( -1 == fseek(arc,4,SEEK_CUR)) // Skip "sex" 4 bytes.
break;
fclose(arc);
return 0; // not found
}
答案 3 :(得分:-1)
printf
中的{p> main()
打印了FSearch()
的返回值,如果您想查看结果是否已找到,则至少应返回一个bool值在FSearch()