【发布时间】:2022-04-28 22:46:10
【问题描述】:
感谢所有答案,更正后代码因愚蠢的错误而无效...我用相同的文件指针“数据库”打开了两个文件...
我已经阅读了几十个这样的问题,但我无法摆脱它,我快疯了。 我必须做的练习要求我在文件 .txt 中组织列表中的项目,该文件具有以下类型的元素:姓名 姓 年龄 工资,按照姓氏的字母顺序排列。 我已经创建了一个将元素插入文件的函数,它运行良好。 然后我转到函数来组织它们,但过程在 fscanf 之后停止,并进行了一些测试 printf 我看到没有为字符串分配值或分配了荒谬的数字。 请帮忙...谢谢。
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 64
#define MAXFILE 100
void insert();
int fullcheck();
void sort();
typedef struct {
char name[MAX];
char surname[MAX];
int age;
double wage;
} data;
int main() {
insert();
return EXIT_SUCCESS;
}
void insert() {
char c;
int i;
data tmp;
FILE* database;
if ((fullcheck())>MAXFILE-1)
printf("Errore: database pieno.\n");
else {
database=fopen("database.txt", "a");
printf("Nome: ");
fgets(tmp.name, MAX, stdin);
tmp.name[strlen(tmp.name)-1]='\0';
printf("Cognome: ");
fgets(tmp.surname, MAX, stdin);
tmp.surname[strlen(tmp.surname)-1]='\0';
for (i=0; i<strlen(tmp.surname); i++) {
if (tmp.surname[i]==' ')
tmp.surname[i]='#';
}
printf("Eta': ");
scanf("%d", &tmp.age);
printf("Salario: ");
scanf("%lf", &tmp.wage);
while((c=getchar())!='\n');
fprintf(database, "%s %s %d %.0lf \n", tmp.name, tmp.surname, tmp.age, tmp.wage);
fflush(database); fclose(database);
if ((fullcheck())>1)
sort();
}
}
int fullcheck() {
char c;
int r=0;
FILE* database;
if ((database=fopen("database.txt", "r"))==NULL) {
return 0;
}
else {
while((c=getc(database))!=EOF) {
if(c=='\n')
r++;
}
return r;
}
}
void sort() {
char tmpstr[MAX];
int len=fullcheck(), i, a, b;
data tmp[len];
FILE* database;
FILE* sorted;
database=fopen("database.txt", "r");
database=fopen("sorted.txt", "w");
for (i=0; i<=len; i++) {
fscanf(database, "%s %s %d %lf \n", &tmp[i].name, &tmp[i].surname, &tmp[i].age, &tmp[i].wage);
}
for (a=0 ; a<(len-1); a++) {
for (b=0; b<(len-1); b++) {
if ((tolower(tmp[b].surname[0]))>(tolower(tmp[b+1].surname[0]))) {
strcpy(tmpstr, tmp[b].surname);
strcpy(tmp[b].surname, tmp[b+1].surname);
strcpy(tmp[b+1].surname, tmpstr);
}
}
}
for (a=0; a<(len-1); a++) {
fprintf(sorted, "%s %s %d %.0lf \n", tmp[a].name, tmp[a].surname, tmp[a].age, tmp[a].wage);
}
fflush(database); fclose(database); remove("database.txt");
fflush(sorted); fclose(sorted); rename("sorted.txt", "database.txt");
}
【问题讨论】:
-
混合
fgets和scanf只是自找麻烦。通过使用fgets读取每一行来修复它,然后使用sscanf或strtol转换一行上的数字。 -
fullcheck()打开文件后不会关闭它。此外,在fullcheck中,c应该是int。 -
贴一些
database.txt的示例行。 -
@user3386109 确实,混合
fgets()和 scanf()` 通常是不好的,但这里的 OP 代码不会因此而失败。 -
@chux-ReinstateMonica 是的,你是对的。这里有更多的答案。打印排序列表的循环太短了。并且排序本身只看每个名字的第一个字母,应该使用
strcmp。
标签: c