我使用了以下代码。 ' S'是结构的变量。有人可以告诉我fseek的当前用法,因为此代码不会替换,但会在文件中添加已编辑的部分。
文件名' g'是模式r +
HA
在输出部分,只要卷不匹配,它一次显示2行,并且不等待输入。
您想更改名称吗? (Y / N) 你想改变班级吗? (Y / N)
void edit()
{
int x;
char ch,c;
printf("\nEnter roll no. \n");
scanf("%d", &x);
rewind(g);
while(!feof(g))
{
fscanf(g, "%d %s %d %s %s", &s.roll, s.name, &s.standard, s.sub, s.address);
if(s.roll==x)
{
printf("\nDo you want to change the name? (y/n)\n");
scanf("%c",&ch);
if(ch=='y')
{
printf("\nEnter new name\n");
scanf("%s", s.name);
}
printf("\nDo you want to change the class? (y/n)\n");
scanf("%c",&ch);
if(ch=='y')
{
printf("\nEnter new class\n");
scanf("%d",&s.standard);
}
printf("\nDo you want to change the subject? (y/n)\n");
scanf("%c", &ch);
if(ch=='y')
{
printf("\nEnter new subject\n");
scanf("%s", s.sub);
}
printf("\nDo you want to change the address? (y/n)\n");
scanf("%c", &ch);
if(ch=='y')
{
printf("\nEnter new address\n");
scanf("%s", s.address);
}
fseek(g,sizeof(struct student) ,SEEK_SET);
fprintf(g,"%d %s %d %s %s",s.roll, s.name, s.standard, s.sub, s.address);
}
}
fclose(g);
}
答案 0 :(得分:0)
我认为你有两种选择:一种是以二进制模式打开文件,读取/写入结构 as-is 。另一种方法是继续使用带有可变长度记录的文本文件。解决方案在很大程度上取决于您在此选择后如何继续。我将为两者提供示例代码。
首先是你读写整个结构的二进制解决方案。
为此你可以这样做:
// Open the file for reading and writing, in binary mode
// Initial position is at the beginning of the file
g = fopen("some path to the file", "r+b");
...
// While we can read one structure
while (fread(&s, sizeof(s), 1, g) == 1)
{
// Your code to update the structure...
// Seek backwards in the file from the current position
// So when we write we will overwrite the structure we just read
fseek(g, -sizeof(s), SEEK_CUR);
// Write out the structure again, overwriting the previous data
fwrite(&s, sizeof(s), 1, g);
}
处理文本文件中的可变长度记录的代码要困难得多,因为那时你实际上无法“替换”文件中的内容,你必须写入一个临时文件,你重命名为完成后的原始文件。
// Open the input file in read-only text mode
g = fopen("some path to the file", "r");
t = fopen("some path to the file.tmp", "w");
...
// Buffer where we read each line of the input file into
char line[256];
// Loop while we can read a line
while (fgets(line, sizeof(line), g) != NULL)
{
sscanf(line, "%d %29[^1234567890] %d %19[^1234567890] %99[^\n]%*c",
&s.roll, s.name, &s.standard, s.sub, s.address);
// Your existing code to update the structure...
// Write to the temporary file
fprintf(t, "%d %s %d %s %s\n",
s.roll, s.name, s.standard, s.sub, s.address);
}
// Close the files
fclose(t);
fclose(g);
// Rename the files, overwriting the old original file
// with the temporary file
rename("some path to the file.tmp", "some path to the file");
这两种解决方案都有利有弊。对于第一个解决方案,专业人士认为它显然更容易和更简单。结果是文本编辑器无法真正读取它,并且您不能简单地将文件复制到具有不同endianness的平台。
使用文本文件的优点是您可以在任何程序中读取和编辑文件,例如简单的文本编辑器。可以说,它更难,需要更多代码。
当您使用scanf
读取用户的输入时,您会读取一个字符。当你给单个字符输入你写字符,然后你按下Enter
键,对吗?字符和 Enter
键都将放入输入缓冲区。 scanf
调用会读取输入但保留Enter
键,因此下次尝试读取输入scanf
时,会看到Enter
键添加的换行符。
您可以通过添加格式中的单个空格来解决此问题,例如
scanf(" %c",&ch);
// ^
// |
// Note space here
额外的前导空格会告诉scanf
读取并丢弃任何空格。
数字和字符串格式不需要它们,它们会自动跳过前导空格,只有"%c"
和"%["
格式才需要它。