fwrite() 如何在 c 文件中工作?
how fwrite() works in c files?
fwrite() 用于在c中向文件写入结构,
假设我们有以下结构:
struct student{
int rollno;
char name[20],grade;
float total;
};
- 每次我们用
fwrite()
写入文件时,它是否将完整的 sizeof(struct tudent)
字节写入文件?
- 如果是这样,即使您只在
name
中存储了几个字符,它也会在文件中写入 name
和 20 个字节的存储空间吗?
如果是这样的话,我们可以用fputs() fputc() putw()
等其他功能修改使用fread()
的写入记录吗?
但是这些函数似乎没有正确修改记录?
#include<stdio.h>
#include<stdlib.h>
struct student{
int rollno;
char name[20],grade;
float total;
};
void display(struct student s2 ){
printf("Name: %s\nRoll Number: %d\nTotal markes: %f\nGrade: %c",s2.name,s2.rollno,s2.total,s2.grade);
}
int main(){
struct student s1,s2;
FILE *fp;
int choice;
fp=fopen("file.txt","r+");
if(!fp){
printf("\nerror in opening file.txt");
exit(1);
}
printf("Enter student detail:-\nEnter name: ");
scanf("%s",s1.name);
printf("Enter rollno: ");
scanf("%d",&s1.rollno);
printf("Enter the total marks: ");
scanf("%f",&s1.total);
printf("Enter the grade: ");
scanf(" %c",&s1.grade);
fwrite(&s1,sizeof(s1),1,fp);
fseek(fp,0,SEEK_SET);
fread(&s2,sizeof(s2),1,fp);
display(s2);
printf("\nModify student record");
while(1){
printf("\n1: modify name\n2: modify rollno\n3: Exit\nchoice: ");
scanf("%d",&choice);
switch(choice){
case 1: printf("\nEnter name: ");
scanf("%s",s1.name);
fseek(fp,0,SEEK_SET);
fputs(s1.name,fp);
fseek(fp,0,SEEK_SET);
fread(&s2,sizeof(s2),1,fp);
display(s2);
break;
case 2: printf("\nEnter rollno");
scanf("%d",&s1.rollno);
fseek(fp,sizeof(s1.name),SEEK_SET);
putw(s1.rollno,fp);
fseek(fp,0,SEEK_SET);
fread(&s2,sizeof(s2),1,fp);
display(s2);
default:fclose(fp);
return 0;
}
}
return 0;
}
fwrite 只能看到内存中的结构。它不知道字段的名称、它们的偏移量或任何相关信息。它所能做的就是将你的记忆直接写入文件。因此,它将写入字符串的所有 20 个字节,以及结构的其余部分。
如果您希望它以人类可读的形式编写内容,您必须编写一个了解每个字段并对其进行格式化的函数。
这是因为 C 不具备称为 "reflection" 的东西,它允许程序存储和利用诸如变量或字段的名称或类型等信息,并在运行时使用该信息。还有其他语言,比如 golang,可以做这样的事情。
fwrite
是一个 C 函数,它像其他函数一样处理结构,不做任何特殊处理(除非有要求)。它将该结构作为二进制对象,并写入任意数量的字节。
does it write full sizeof(struct tudent)
bytes to the file every time we write it with fwrite()
?
它会写入您要求 fwrite
写入的尺寸,因此如果它是 sizeof(structX)
,它会写入该尺寸。同样的操作fwrite
两次,就会写两次。
if so then does it write name
with 20 bytes of storage on the file even if you have only stored few characters in the name
?
name
被声明为 char[20]
,占用 20 个字节。所以是的,那部分在磁盘上占用 20 个字节(即使 "string" 包含 "only" 3 个字符(即 '[=20=]'
位于第 4 个位置),所有 20 个字节都被写入。
if that is the case then can we modify the the written record using fread()
with other functions such as fputs() fputc() putw()
,
but these function doesnt seem to modify the record correctly?
putw
将 word 写入流,这意味着 int
原样(二进制字,不是它的字符串表示),但更好按照 man page 中的建议使用 fwrite
。 fputc
写一个独特的字符。 fputs
写入一个以 null 结尾的字符串,与 fwrite
不同,它写入您需要的字符数,而不管其中某处是否隐藏了零字节。
fwrite() 用于在c中向文件写入结构, 假设我们有以下结构:
struct student{
int rollno;
char name[20],grade;
float total;
};
- 每次我们用
fwrite()
写入文件时,它是否将完整的sizeof(struct tudent)
字节写入文件? - 如果是这样,即使您只在
name
中存储了几个字符,它也会在文件中写入name
和 20 个字节的存储空间吗? 如果是这样的话,我们可以用
fputs() fputc() putw()
等其他功能修改使用fread()
的写入记录吗? 但是这些函数似乎没有正确修改记录?#include<stdio.h> #include<stdlib.h> struct student{ int rollno; char name[20],grade; float total; }; void display(struct student s2 ){ printf("Name: %s\nRoll Number: %d\nTotal markes: %f\nGrade: %c",s2.name,s2.rollno,s2.total,s2.grade); } int main(){ struct student s1,s2; FILE *fp; int choice; fp=fopen("file.txt","r+"); if(!fp){ printf("\nerror in opening file.txt"); exit(1); } printf("Enter student detail:-\nEnter name: "); scanf("%s",s1.name); printf("Enter rollno: "); scanf("%d",&s1.rollno); printf("Enter the total marks: "); scanf("%f",&s1.total); printf("Enter the grade: "); scanf(" %c",&s1.grade); fwrite(&s1,sizeof(s1),1,fp); fseek(fp,0,SEEK_SET); fread(&s2,sizeof(s2),1,fp); display(s2); printf("\nModify student record"); while(1){ printf("\n1: modify name\n2: modify rollno\n3: Exit\nchoice: "); scanf("%d",&choice); switch(choice){ case 1: printf("\nEnter name: "); scanf("%s",s1.name); fseek(fp,0,SEEK_SET); fputs(s1.name,fp); fseek(fp,0,SEEK_SET); fread(&s2,sizeof(s2),1,fp); display(s2); break; case 2: printf("\nEnter rollno"); scanf("%d",&s1.rollno); fseek(fp,sizeof(s1.name),SEEK_SET); putw(s1.rollno,fp); fseek(fp,0,SEEK_SET); fread(&s2,sizeof(s2),1,fp); display(s2); default:fclose(fp); return 0; } } return 0; }
fwrite 只能看到内存中的结构。它不知道字段的名称、它们的偏移量或任何相关信息。它所能做的就是将你的记忆直接写入文件。因此,它将写入字符串的所有 20 个字节,以及结构的其余部分。
如果您希望它以人类可读的形式编写内容,您必须编写一个了解每个字段并对其进行格式化的函数。
这是因为 C 不具备称为 "reflection" 的东西,它允许程序存储和利用诸如变量或字段的名称或类型等信息,并在运行时使用该信息。还有其他语言,比如 golang,可以做这样的事情。
fwrite
是一个 C 函数,它像其他函数一样处理结构,不做任何特殊处理(除非有要求)。它将该结构作为二进制对象,并写入任意数量的字节。
does it write full
sizeof(struct tudent)
bytes to the file every time we write it withfwrite()
?
它会写入您要求 fwrite
写入的尺寸,因此如果它是 sizeof(structX)
,它会写入该尺寸。同样的操作fwrite
两次,就会写两次。
if so then does it write
name
with 20 bytes of storage on the file even if you have only stored few characters in thename
?
name
被声明为 char[20]
,占用 20 个字节。所以是的,那部分在磁盘上占用 20 个字节(即使 "string" 包含 "only" 3 个字符(即 '[=20=]'
位于第 4 个位置),所有 20 个字节都被写入。
if that is the case then can we modify the the written record using
fread()
with other functions such asfputs() fputc() putw()
, but these function doesnt seem to modify the record correctly?
putw
将 word 写入流,这意味着 int
原样(二进制字,不是它的字符串表示),但更好按照 man page 中的建议使用 fwrite
。 fputc
写一个独特的字符。 fputs
写入一个以 null 结尾的字符串,与 fwrite
不同,它写入您需要的字符数,而不管其中某处是否隐藏了零字节。