我是一个正在努力解决作业C问题的新手。我需要创建一个简单的程序,将一个struture类型写入一个文件,然后读取恢复之前插入的数据的文件。我把这两部分都搞定了。
还需要另一个功能,它基本上要求在先前在文件中输入的结构中用另一个值替换'char'类型。理想的效果是它有一个初始的'0'值,可以显示该项目,当用另一个值替换时,它不再显示。
如果有人愿意看看这个以帮助我解决这个问题,我会非常感激。
顺便说一句,我已经在SO中阅读了关于这些主题的其他问题,并且他们都遵循了“替换”输出文件逻辑,据我所知。他们使用缓冲区来保存数据并按顺序进行比较,然后输出具有不同内容的新文件。
我正在尝试做一些与众不同的事情,而我发现的事情并没有真正帮助我。
如果答案是其中一个问题,请非常友好地向我指出并解释。
这是我到目前为止生成的代码,我添加了一些注释来简要解释部分代码,因为输出是葡萄牙语。我的难点在于switch()的情况3:S
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct{
char license_plate[6];
char owner_name[80];
char deleted;
}vehicle_t;
void read_register(vehicle_t *v){ // function to read a struture of the type vehicle_t
char temp[8];
printf("insert license plate: \n");
scanf("%s", temp);
memcpy(v->license_plate, temp, 6);
printf("Insert owner name: \n");
getchar();
fgets(v->owner_name, 80, stdin);
v->deleted=0; // initializtion of 'deleted'
}
void print_register(vehicle_t *v){ // function to print a vehicle_t type
printf("\nRegister details: \n");
printf("License plate: ");
fwrite(v->license_plate, sizeof(char), 6, stdout);
printf("\nOwner: ");
printf("%s", v->owner_name);
printf("\n");
}
void show_menu(){ //just a small interface to display several options in a menu
vehicle_t reg;
char temp_del[10];
FILE *fp;
int opt;
system("clear");
printf("make your option:\n 1. new register \n 2. see registers \n 3. delete registers \n 4. exit \n");
scanf("%d", &opt);
getchar();
switch(opt){
case 1: //option to insert in the file 'registos.txt' - OK
system("clear");
fp = fopen("registers.txt", "a+");
read_register(®);
fwrite(®, sizeof(vehicle_t), 1, fp);
fclose(fp);
show_menu();
break;
case 2: // function to read from 'registos.txt' - also OK
system("clear");
fp = fopen("registers.txt", "r");
if(fp==NULL){ //no file test
system("clear");
printf("No file!\n");
getchar();
show_menu();
}else{ // if 'deleted' is != 0 don't print it out
while(fread(®, sizeof(vehicle_t), 1, fp)!=0){
if(reg.deleted==0){
print_register(®);
}
}
printf("Press enter!");
fclose(fp);
getchar();
show_menu();
}
break;
case 3:
system("clear");
printf("License plate to delete?:\n");
scanf("%s", temp_del);
fp = fopen("registers.txt", "r+");
while(fread(®, sizeof(vehicle_t), 1, fp)!=0){
// my problem is here! i'm not getting the 'deleted' value replaced in the file from '0' to '1'. I'm trying to find it's position and then goback the size of the struture and replace with the value '1' at the end. what am i doing wrong?
if(strcmp(reg.license_plate, temp_del)==0){
reg.apagado='1';
fseek(fp, -sizeof(vehicle_t), SEEK_CUR);
fwrite(®, sizeof(vehicle_t), 1, fp);
printf("Register deleted!\n");
}
fclose(fp);
getchar();
show_menu();
}
break;
case 4:
system("clear");
return;
break;
default:
printf("No such option, please wait 3 seconds.\n");
system("sleep 3");
show_menu();
break;
}
}
int main(){
show_menu();
return 0;
}
答案 0 :(得分:1)
你应该检查几件事:
strcmp
是否会返回0? (在块之后设置一个断点)temp_del
- 它只是apagado
,还是有额外的字符(可能是\n
)答案 1 :(得分:1)
您可以尝试使用strncmp(str1, str2, 6)
来避免任何行尾字符问题。
答案 2 :(得分:1)
尝试将两个值reg.license_plate
和temp_del
打印为十六进制,以查看完全它们的样子。
for (int i=0; i<6; ++i) {
printf("reg.license_plate[%d]=%X temp_del[%d]=%X\n",
i, reg.license_plate[i], i, temp_del[i]);
}
如果未输入if (strcmp(...)
,则strcmp将其视为两个不同的字符串,或者while(fread(®, sizeof(vehicle_t), 1, fp)!=0)
失败
这不像找到错误那么紧急或重要,但因为这是作业,我建议你稍微修改你的结构定义。
有很多数字可以确定难以改变的事物的大小。教师通常会寻找那种东西。这样做的经典方法是使用一些定义大小的名称:
#define MAX_LICENSE_PLATE (6)
#define MAX_OWNER_NAME (80)
typedef struct {
char license_plate[MAX_LICENSE_PLATE];
char owner_name[MAX_OWNER_NAME];
char deleted;
} vehicle_t;
如果你的编译器支持它,最好使用
const int MAX_LICENSE_PLATE = 6;
const int MAX_OWNER_NAME = 80;
相反,但是有些C编译器不会让你以这种方式定义数组大小。
* 当你memcpy()值时,总是将'\ 0'放在字符串的末尾。 例如
void read_register(vehicle_t *v){ // function to read a struture of the type vehicle_t
char temp[MAX_LICENSE_PLATE+2];
printf("insert license plate: \n");
scanf("%7s", temp); // I should go check how to specify width at run-time
memcpy(v->license_plate, temp, MAX_LICENSE_PLATE);
v->license_plate[MAX_LICENSE_PLATE-1] = '\0';
printf("Insert owner name: \n");
getchar();
fgets(v->owner_name, MAX_LICENSE_PLATE, stdin);
v->deleted=0; // initializtion of 'deleted'
}
注意: fgets保持换行符'\ n';所以你也应该减掉它。