我是c编程语言的初学者,我尝试了很多次来解决这个问题。 这里的问题代码不会将文件中的数据更新为新数据,但代码不起作用。 我想由用户将文件更新为新数据并显示在服务器端。
此代码用于更新数据,我使用缓冲区将数据存储在其中。
void bilgi_guncelle()
{
struct daire d;
FILE *dosya, *temp;
int no, bulundu = 0;
printf("Daire no: ");
scanf("%d", &no);
dosya = fopen("aidatlar.txt", "a+");
if (dosya == NULL)
{
printf("Dosya acilamadi\n");
return;
}
temp = fopen("gecici.txt", "w");
while (fread(&d, sizeof(struct daire), 1, dosya) == 1)
{
if (d.no == no)
{
bulundu = 1;
printf("Ad (%s): ", d.ad);
scanf("%s", d.ad);
printf("Soyad (%s): ", d.soyad);
scanf("%s", d.soyad);
printf("Aidat (%.2f): ", d.aidat);
scanf("%f", &d.aidat);
printf("Tarih (%s): ", d.tarih);
scanf("%s", d.tarih);
}
fwrite(&d, sizeof(struct daire), 1, temp);
}
fclose(dosya);
fclose(temp);
if (!bulundu)
{
printf("Daire bulunamadi\n");
remove("gecici.txt");
return;
}
remove("aidatlar.txt");
rename("gecici.txt", "aidatlar.txt");
printf("Bilgi basariyla guncellendi\n");
}
不完整的代码。我假设您在
struct daire
中使用固定大小的字符串。如果不是,那么您需要在使用前分配这些字符串,通常还存储字符串长度。
没有样本数据。
write_date()
生成测试数据。
如果你在 Windows 上,那么问题是你在对二进制数据进行操作时没有使用二进制模式。
检查
fopen("gecici.txt", "w");
是否成功。
fopen("...", "a+")
根据 fopen(3) 以操作系统特定的方式设置文件位置:
对于glibc,读取的初始文件位置在文件的开头,但是对于Android/BSD/MacOS,读取的初始文件位置在文件的末尾。
下面的代码明确设置了文件位置。
(未修复)如果用户在中途按 ctrl-c,请考虑注册一个退出处理程序以删除您的临时文件。
(不固定)您当前存储
no
,如果它们是顺序的,也许不存储它,而只是fseek(, no * sizeof(struct daire), SEEK_SET)
以获得感兴趣的记录?这意味着如果您插入或删除记录,数字将会改变。这对您的用例可能重要,也可能不重要。
(不固定)考虑使用 SQLite 而不是编写自己的文件格式。
(部分固定)使用常量而不是魔法值(文件名)。
这适用于 Linux:
#include <stdio.h>
#define AIDATLAR "aidatlar.txt"
#if defined(_WIN32) || defined(WIN32)
#define BINARY_MODE "b"
#define F_OK 0
#include <io.h>
#else
#define BINARY_MODE ""
#include <fcntl.h>
#include <unistd.h>
#endif
#define STR_LEN 10
#define str(s) str2(s)
#define str2(s) #s
struct daire {
int no;
char ad[STR_LEN+1];
char soyad[STR_LEN+1];
float aidat;
char tarih[STR_LEN+1];
};
// write data if file doens't already exist
void write_data(size_t n, struct daire d[n]) {
if(!access(AIDATLAR, F_OK)) return;
FILE *dosya = fopen(AIDATLAR, BINARY_MODE "w");
if (!dosya) {
printf("Dosya acilamadi\n");
return;
}
fwrite(d, sizeof *d, n, dosya);
fclose(dosya);
}
void bilgi_guncelle() {
printf("Daire no: ");
int no;
scanf("%d", &no);
FILE *dosya = fopen(AIDATLAR, BINARY_MODE "a+");
if (!dosya) {
printf("Dosya acilamadi\n");
return;
}
fseek(dosya, 0L, SEEK_SET);
FILE *temp = fopen("gecici.txt", BINARY_MODE "w");
if (!temp) {
printf("Dosya acilamadi\n");
fclose(dosya);
return;
}
int bulundu = 0;
struct daire d;
while (fread(&d, sizeof(struct daire), 1, dosya) == 1) {
if (d.no == no) {
bulundu = 1;
printf("Ad (%s): ", d.ad);
scanf("%" str(STR_LEN) "s", d.ad);
printf("Soyad (%s): ", d.soyad);
scanf("%" str(STR_LEN) "s", d.soyad);
printf("Aidat (%.2f): ", d.aidat);
scanf("%f", &d.aidat);
printf("Tarih (%s): ", d.tarih);
scanf("%" str(STR_LEN) "s", d.tarih);
}
fwrite(&d, sizeof(struct daire), 1, temp);
}
fclose(dosya);
fclose(temp);
if (!bulundu) {
printf("Daire bulunamadi\n");
remove("gecici.txt");
return;
}
remove(AIDATLAR);
rename("gecici.txt", AIDATLAR);
printf("Bilgi basariyla guncellendi\n");
}
int main() {
struct daire d[] = {
{0, "a0", "a1", 0.12, "a2"},
{1, "b0", "b1", 1.12, "b2"},
{2, "c0", "c1", 2.12, "c2"}
};
write_data(sizeof d / sizeof *d, d);
bilgi_guncelle();
}
和示例会话:
$ ./a.out
Daire no: 0
Ad (a0): a0
Soyad (a1): a1
Aidat (0.12): 1.2
Tarih (a2): a2
Bilgi basariyla guncellendi
$ ./a.out
Daire no: 0
Ad (a0): a0
Soyad (a1): a1
Aidat (1.20):