2017-04-11 91 views
0

我写了一个程序使用fwrite的和正确的方法使用fread

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    FILE *fp; 
    int r; 
    char arr[] = "this is the string"; 
    char str[20] = {'\0'}; 

    fp = fopen("fwrite.txt", "w"); 
    fwrite(arr, 1, sizeof(arr), fp); 
    fseek(fp, SEEK_SET, 0); 
    r = fread(str, 1, sizeof(arr), fp); 

    if(r == sizeof(arr)) 
     printf("read successfully\n"); 
    else 
    { 
     printf("read unsuccessfull\n"); 
     exit(1); 
    } 

    printf("read = %d\n", r); 
    printf("%s\n", str); 

    fclose(fp); 
    return 0; 
} 

我想以这种方式来读,但我不能这样做。这里有什么问题,是我应该把&str[i]并为fread运行一个循环,否则fread能够将数据放入str

我越来越垃圾,我不明白为什么?

+2

您需要'fseek(fp,0L,SEEK_SET)'。偏移量来自哪个('SEEK_SET')之前。 –

+1

我猜你正在使用www.tutorialspoint.com作为参考,由于某些原因,他们以错误的顺序使用fseek,fread和fwrite参数。 – Dunno

+2

你也需要在'w + b'模式下打开 –

回答

3

主要问题是您有反向参数fseek() - 您需要在此之前的偏移量(0)(SEEK_SET)。第二个问题是您尝试从仅用于写入的文件中读取文件。在这种情况下的一个更小的问题,但一个非常重要的问题是,你不会错误地检查fopen()调用。 (这个fopen()相对不太可能会失败,但更有趣的事情已经知道了。)您还应该检查fwrite()电话(当然,您已经检查了fread())。

修复所有这些可能会导致:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int rc = EXIT_SUCCESS; 
    int r; 
    const char file[] = "fwrite.txt"; 
    char arr[] = "this is the string"; 
    char str[20] = {'\0'}; 
    FILE *fp = fopen(file, "w+b"); 
    if (fp == 0) 
    { 
     fprintf(stderr, "Failed to open file %s for reading and writing\n", file); 
     rc = EXIT_FAILURE; 
    } 
    else 
    { 
     if (fwrite(arr, 1, sizeof(arr), fp) != sizeof(arr)) 
     { 
      fprintf(stderr, "Failed to write to file %s\n", file); 
      rc = EXIT_FAILURE; 
     } 
     else 
     { 
      fseek(fp, 0, SEEK_SET); 
      r = fread(str, 1, sizeof(arr), fp); 
      if (r == sizeof(arr)) 
      { 
       printf("read successful\n"); 
       printf("read = %d bytes\n", r); 
       printf("read data [%s]\n", str); 
      } 
      else 
      { 
       printf("read unsuccessful\n"); 
       rc = EXIT_FAILURE; 
      } 
     } 
     fclose(fp); 
    } 
    return rc; 
} 

实例运行:

$ ./fi37 
read successful 
read = 19 bytes 
read data [this is the string] 
$ 

注意,因为你在输出字符串的结尾的文件写入空字节,这一工作在部分,然后再读入。如果文件包含空字节,则该文件不是真正的文本文件。在Unix系统中,在二进制文件和文本文件之间没有区别的情况下,"w+b"模式中的b并不是真的需要。如果您要将空字节写入Windows上的文件,则应使用b来指示二进制模式。

如果您选择了,可以通过在main()函数中没有一个return来减少“粗糙”(或嵌套深度)。您可以使用return EXIT_FAILURE;并避免使用else和另一组大括号。显示的代码仔细关闭文件,如果它被打开。在通用功能中,这很重要。在main()中,由于退出过程将刷新并关闭打开的文件,所以它并不重要。

+0

是的问题是fseek参数和w + b,我使用ubuntu,如果我删除w + b到w,它将无法工作。 – acidlategamer

+1

是;用'“w”'表示只写。使用'“w +”'表示读写并在做其他事情之前清空文件。 –

+0

不检查'fopen'的返回值不是一个小问题,imo,这是非常重要的。忽略库函数的返回值会使调试非常非常痛苦。我甚至在文档中提出了有关此问题的文章:http://stackoverflow.com/documentation/c/2006/common-pitfalls/15692/ignoring-return-values-of-library-functions#t=20170411151208958515 无论如何,+1提及这个 – Dunno

0

对于fopen,您无法使用"w"模式读取文件,请改为使用"w+"

"r" - 打开文件进行阅读。该文件必须存在。

"w" - 创建一个空文件用于书写。如果已存在同名文件 ,则其的内容将被删除,并将该文件视为新的空文件。

"a" - 附加到文件。写入操作,在 文件末尾追加数据。如果该文件不存在,则会创建该文件。

"r+" - 打开文件以更新读取和写入。该文件必须存在。

"w+" - 为读取和写入创建一个空文件。

"a+" - 打开文件进行阅读和追加。