C fopen/fwrite 快把我逼疯了 - fwrite 不写

C fopen/fwrite driving me to madness - fwrite not writing

好的,这是交易...我记得上周创建了一个程序,它要求我以二进制模式打开一个文件并向其中写入数据。起初,我尝试使用fopen函数,检查结果是否可以,然后尝试写入数据。我记得第一次尝试时,fwrite 操作不工作。然后,在将变量声明从一个地方移动到另一个地方之后,我终于能够让 fwrite 将数据插入到文件中。

现在,我需要创建另一个类似的程序来做一些其他的事情,所以我想使用相同的分配代码(实际上,我想创建一个特定的函数来做同样的事情),这就是我能够想出:

#include <stdio.h>                                        

int openfile(FILE *main, char *name, int option);    

int main(void)                                            
{                                                         

  FILE *main;                                        
  int header_init;                                        
  int result;                                             

  switch (openfile(main,"main_file.bin",1)) {
    case 1:                                               
      header_init = -1;                                   
      //fseek(main,0,SEEK_SET);    --> useless
      fwrite(&header_init,sizeof(int),1,main);       
      printf("ftell = %d\n",ftell(main)); break;     
    case 2:                                               
      fread(&header_init,sizeof(int),1,main);        
      printf("%d\n",header_init); break;                  
    default:                                              
      printf("Error trying to open file\n");                  
  }                                                       
  printf("header_init is %d\n",header_init);              
  fclose(main); exit(0);                             
}                                                         

int openfile(FILE *main, char *name, int option)      
{                                                         
  int result_alloc;                                       
  int F_OK;                                               
  if (result_alloc = access (name, F_OK) != 0) {          
    printf("File not found, allocating a new one\n");    
    if ((main= fopen(name,"w+b")) != NULL) return 1;
  }                                                       
  else {                                                  
    printf("File exist, allocating as r+b\n");    
    if ((main= fopen(name,"r+b")) != NULL) return 2;
  }                                           
  printf("Failure trying to open"); 
  return 0;                                   
}                                             

由于某些不幸的原因,fwrite 操作没有将 -1 写入分配的文件。我对这个程序的意图是让它始终检查该特定文件是否存在:如果有,只需使用 r+b 打开它以允许更新功能而不覆盖实际文件内容。否则,分配一个header值为-1的新文件(我将把这个文件作为链表结构的记录文件)。

说真的,我不明白为什么这不起作用。这个想法和我之前的程序是一样的。唯一改变的是我创建了一个函数,因为这将在我以后发生(因为第三个参数将允许我减少我的代码并使其更多 "readable" - 至少这是意图!)。我不得不承认我对细节问题有些关注,但我正在努力做得更好,我可能在这段代码中遗漏了一些愚蠢的东西,但在看了几个小时之后我真的很想在这里寻求帮助。谢谢

编辑:我是运行它在z/Linux下。我想了解的是,为什么上面的代码没有将 -1 写入文件,而下面的代码却写好了?

#include <stdio.h>                                                 
int main(void)                                                     
{                                                                  
  FILE *main;                                                      
  int result_alloc;                                                
  int header_init;                                                 
  int F_OK;                                                        

  if (result_alloc = access ("test.bin", F_OK) != 0) {             
    printf("File not found, allocating a new one\n");              
    if ((main = fopen("test.bin","w+b")) == NULL) {                
      printf("Failure trying to open file");                       
      return 1;                                                    
    }                                                              
    else {                                                         
      header_init = -1;                                            
      printf("current pos is: w+b %d\n",ftell(main));              
      fwrite(&header_init,sizeof(int),1,main);                     
      printf("current pos is: write header_init %d\n",ftell(main));
    }                                                              
  }                                                                
  else {                                                           
    if ((main = fopen("test.bin","r+b")) == NULL) {                
      printf("Failure trying to open file");                       
      return 2;                                                    
    }                                                              
    else {                                                         
      printf("current pos is: r+b %d\n",ftell(main));              
      fread(&header_init,sizeof(int),1,main);                      
      printf("current pos is: read header_init %d\n",ftell(main)); 
    }                                                              
  }                                                                
}                                                                  

调用函数看不到 openfile 函数内部对 main 变量的赋值的主要问题。因为C是按值传递的,你只是改变了函数参数的值,而不是传入的变量的值。所以当openfile returns时,main变量main 函数内部没有变化。

你需要做的是将该变量的地址传递给函数,然后在函数中取消引用局部变量(这是一个指针)并赋值到取消引用的变量。

此外,使用与函数同名的变量不是一个好主意,因为它隐藏了该作用域中的函数并可能导致混淆。

因此您可以按如下方式定义您的函数:

int openfile(FILE **fp, char *name, int option);

然后您可以这样调用它(将 main 变量的名称更改为 fp):

FILE *fp;
...
openfile(&fp,"main_file.bin",1)

然后在 openfile 中,取消引用 fp 以更改调用函数中的值:

*fp = fopen(name,"w+b")

第二个代码示例工作的原因是您直接分配给局部变量,然后稍后在函数中使用相同的变量。

此外,您 "lucky" 第二段代码可以正常工作是因为您这样做了:

int F_OK;

F_OK 已在 unistd.h 中定义,其中 access() 已定义。所以通过这样做你重新声明它而不是给它一个值,导致未定义的行为。摆脱这个定义,#include <unistd.h>,对 access() 的调用保证按预期工作。