2012-03-26 19 views
0

我是一个C newb挣扎与作业C问题。我需要创建一个简单的程序,将结构类型写入文件,然后读取恢复先前插入的数据的文件。我得到了这两个部分的工作。C结构和文件处理newb - 挣扎

还有一个需要的功能,基本上要求用先前输入的文件中的“字符”类型替换另一个值。期望的效果是它有一个初始的'0'值,可以显示该项目,并且当用另一个vaalue替换时,它不会再显示。

如果有人会这么友好地看看这个,以帮助我理清它,我会非常感激。

顺便说一句,我阅读关于这些类型的话题在SO其他问题,他们都遵循'替换'输出文件的逻辑,据我所知。他们使用一个缓冲区来保存数据并依次比较,然后输出一个新文件,其中包含不同的内容。

我想要做一些不同的事情,而我发现的东西并没有真正帮助我。

如果答案出现在其中一个其他问题中,请尽可能向我指出并解释它。

这是我迄今为止编写的代码,我添加了一些注释来简单地解释部分代码,因为输出是用葡萄牙语的。我的困难是在开关()的情况下,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(&reg); 


      fwrite(&reg, 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(&reg, sizeof(vehicle_t), 1, fp)!=0){ 
        if(reg.deleted==0){ 
        print_register(&reg); 

        } 
      } 
       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(&reg, 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(&reg, 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; 
} 
+2

你正在做什么与替换字符不清楚。更糟糕的是,您已经将每种标识符都命名为非英语语言,这使得难以阅读代码。 – 2012-03-26 18:47:11

+0

好吧,我得到它的工作删除,但另一个问题出现... 它取代了以前放在文件中的结构'删除'字符,但现在它不会取代其他情况下的相同结构的相同的文件...肯定与while循环相关......任何想法? 顺便说一句,除了strncmp建议的海军上将... 现在它的工作原理,但仅用于txt文件结构的第一个实例... – Joum 2012-03-26 22:37:05

+0

猜测我说得太快了...多数民众赞成在所有问题不是问题...我得到的程序取代像我想要的,但现在当我尝试做同样的txt文件中的结构的另一个迭代,没有什么chagnges,但第一个已被改变因为我希望虽然......我应该把光标在while循环结束时推到文件结构的下一个迭代? – Joum 2012-03-26 23:06:30

回答

1

您应该检查两件事情:

  1. 是否strcmp再回到0?
  2. 检查temp_del(在之后的块设置断点) - 它只是apagado,还是有额外的字符(也许\n
+0

1.我试图检查strcmp的返回值,但它实际上并没有输入if语句......没有线索为什么......我认为这种方式应该可行... 2. temp_del据说由于它的大小不应该有\ n。它不能存储超过6个。尝试将temp_del的大小更改为6:尽管... – Joum 2012-03-26 19:11:15

+1

如果temp_del的大小是6,那么它将只存储'apaga',因为temp_del [5] '将会是'\ 0'。确保你在调试器中查看temp_del(如果你不能使用调试器,打印出来!) – RunHolt 2012-03-26 19:22:48

1

你可以尝试使用strncmp(str1, str2, 6)避免换行符的任何结束问题。

+0

已经尝试过了......没有成功,没有进入if ...由于某种原因reg.deleted和temp_del 6个第一个字符不会触发if ...它可能是==运算符吗? – Joum 2012-03-26 19:24:33

+0

我会第二次RunHolt的评论,然后你应该打印/看看字符串的内容。或者,也许只是使用车牌号码来避免任何字符大小写问题。 – GrandAdmiral 2012-03-26 19:42:42

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(&reg, sizeof(vehicle_t), 1, fp)!=0)失败

这是不是紧急或重要的,因为发现的bug,但由于这种作业我建议你修改一下你的结构定义。

有很多数字设置的东西的大小很难歪曲。指导者通常会寻找那种东西。这样做的经典方法是有限定的尺寸了几个名字:

#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';所以你也应该修剪它。