2015-03-19 73 views
1

我目前正在编写一个C程序来创建,查看和更新​​文件中的员工记录。我的程序没有出现严重错误,并且一切都很顺利,直到我输入员工ID,Xcode才会发出EXC_BAD_ACCESS错误。C编程Xcode - EXC_BAD_ACCESS

我回到我的代码,这发生在它应该将数据写入文件的部分(请参阅评论),但我仍然不确定这里出了什么问题。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define size 300 

struct emp 
{ 
    int id; 
    char *name; 
}*emp1, *emp3; 

void display(); 
void create(); 
void update(); 

FILE *fp, *fp1; 
int count = 0; 

void main(int argc, char **argv) 
{ 
    int i, n, ch; 

    printf("1] Create a Record\n"); 
    printf("2] Display Records\n"); 
    printf("3] Update Records\n"); 
    printf("4] Exit"); 
    while (1) 
    { 
     printf("\nEnter your choice : "); 
     scanf("%d", &ch); 
     switch (ch) 
     { 
      case 1: 
       fp = fopen(argv[1], "a"); 
       create(); 
       break; 
      case 2: 
       fp1 = fopen(argv[1],"rb"); 
       display(); 
       break; 
      case 3: 
       fp1 = fopen(argv[1], "r+"); 
       update(); 
       break; 
      case 4: 
       exit(0); 
     } 
    } 
} 

/* To create an employee record */ 
void create() 
{ 
    int i; 
    char *p; 

    emp1 = (struct emp *)malloc(sizeof(struct emp)); 
    emp1->name = (char *)malloc((size)*(sizeof(char))); 
    printf("Enter name of employee : "); 
    scanf(" %[^\n]s", emp1->name); 
    printf("Enter emp id : "); 
    scanf(" %d", &emp1->id); 
    fwrite(&emp1->id, sizeof(emp1->id), 1, fp); //The error occurs here 
    fwrite(emp1->name, size, 1, fp); 
    count++; // count to number of entries of records 
    fclose(fp); 
} 

/* Display the records in the file */ 
void display() 
{ 
    emp3=(struct emp *)malloc(1*sizeof(struct emp)); 
    emp3->name=(char *)malloc(size*sizeof(char)); 
    int i = 1; 

    if (fp1 == NULL) 
     printf("\nFile not opened for reading"); 
    while (i <= count) 
    { 
     fread(&emp3->id, sizeof(emp3->id), 1, fp1); 
     fread(emp3->name, size, 1, fp1); 
     printf("\n%d %s",emp3->id,emp3->name); 
     i++; 
    } 
    fclose(fp1); 
    free(emp3->name); 
    free(emp3); 
} 

void update() 
{ 
    int id, flag = 0, i = 1; 
    char s[size]; 

    if (fp1 == NULL) 
    { 
     printf("File cant be opened"); 
     return; 
    } 
    printf("Enter employee id to update : "); 
    scanf("%d", &id); 
    emp3 = (struct emp *)malloc(1*sizeof(struct emp)); 
    emp3->name=(char *)malloc(size*sizeof(char)); 
    while(i<=count) 
    { 
     fread(&emp3->id, sizeof(emp3->id), 1, fp1); 
     fread(emp3->name,size,1,fp1); 
     if (id == emp3->id) 
     { 
      printf("Enter new name of emplyee to update : "); 
      scanf(" %[^\n]s", s); 
      fseek(fp1, -204L, SEEK_CUR); 
      fwrite(&emp3->id, sizeof(emp3->id), 1, fp1); 
      fwrite(s, size, 1, fp1); 
      flag = 1; 
      break; 
     } 
     i++; 
    } 
    if (flag != 1) 
    { 
     printf("No employee record found"); 
     flag = 0; 
    } 
    fclose(fp1); 
    free(emp3->name);  /* to free allocated memory */ 
    free(emp3); 
} 
+0

您确定错误发生在第一个'fwrite '调用?我无法在Linux上使用GCC重现您的问题,但在Valgrind下运行程序,* second *'fwrite'会产生警告,因为它是wri即使其中只有一部分已经被初始化(通过scanf调用),整个300字节的缓冲区也是如此。编写整个缓冲区应该仍然有效(尽管其中大部分都是垃圾),但值得深入研究。 – Wyzard 2015-03-19 02:01:25

+0

另外,你是否得到一个与错误一起报告的信号名称,如SIGSEGV或SIGBUS? – Wyzard 2015-03-19 02:02:17

+0

可能与您看到的问题无关,但在托管环境(即您拥有的)中_main()_需要返回_int_ - 其他任何内容都是未定义行为。 – mlp 2015-03-19 02:05:11

回答

0

您在评论中提到fp为NULL。这意味着你实际上没有打开的文件要写入;早期的fopen调用返回NULL以指示错误。 直接崩溃的原因是fwrite通过尝试访问它应该指向的FILE结构的字段来解引用空指针; 间接原因是您在使用它之前没有从fopen检查返回值。

每个fopen通话后,加入这样的事情:

if (fp == NULL) 
{ 
    perror("Failed to open file"); 
    exit(1); 
} 

fopen失败,则返回NULL,并设置全局变量errno来表示什么地方出了错。 perror函数打印一条对应于errno值的描述性消息。


因为你的程序需要被赋予在命令行上的文件名(即argv[1],确保Xcode中实际上是给它一个。启动程序从IDE通常运行它不受任何命令行参数当argc小于2时,访问argv[1]会是另一个错误,并且可能会显示为无效字符串,这不是有效的文件名,导致fopen失败

+0

谢谢。我在第一次fopen调用后添加了if语句,输出结果如下: 无法打开文件:地址不正确 – ZenX0904 2015-03-19 02:46:34

+0

在我的Linux系统上,errno(3)的联机帮助页指出“不良地址”是EFAULT的消息错误,fopen(3)表示它可以产生open(2)中的任何错误,而open(2)则表示如果“pathname指向可访问的地址空间之外”,它将产生EFAULT。 [本文](http://www.linuxquestions。org/questions/programming-9/fopen-returns-with-errno-14-bad-address-4175479196 /)表示这可能是路径字符串的问题。很可能,Xcode没有将程序传递给文件名参数,所以'argv [1]'是NULL。 – Wyzard 2015-03-19 03:06:05

+0

非常感谢。我现在试图找出如何确保Xcode正确地将文件名传递给fp。这个程序应该在Linux上运行(我的学校实验室使用Linux),所以我相信在那里一切都会好起来的,但是我仍然想在OSX上解决这个问题。 – ZenX0904 2015-03-19 03:20:46