c - 在不先调用 fflush 或写入 stderr 的情况下使用 fwrite

标签 c fwrite stderr printf fflush

我有一个将二进制数据写入文件或 stdout 的函数。然而,对 fwrite() 的调用有时会失败,除非我 fflush(stderr) 或在尝试 fwrite 之前将报告打印到 stderr

这是正常行为,还是表明存在一些潜在的内存问题?很难调试,因为一旦我 fprintstderr 我正尝试将数据 fwritestdout ,“问题”就消失了。

这是该函数的一个非常简化的版本。

int writebinary(FILE *fpout, void *data, long ntowrite) {

    long i; 

    /* lets say we know the input data is double float */
    double *p = data; 

    /* including this test line makes the function work! */
    for(i=0; i<ntowrite;i++) fprintf(stderr,"data[%d]=%g\n",i,p[i]);

    /* attempt to write data[] as a single block of bytes */
    m= fwrite(data,(size_t)(ntowrite*sizeof(double)),1,fpout);

    if(m!=1) {
        fprintf(stderr,"Write error: %d\n",ferror(fpout));
        return(-1); 
    }
    else return(m);
}

任何智慧赞赏:)

最佳答案

这不是正常行为。
推荐以下。帖子中有许多值得关注的事情(见下文)但没有指出问题 - 但有些地方是错误的。

int writebinary2(FILE *fpout, void *data, long ntowrite) {
  size_t n = (size_t) ntowrite;
  double *dp = (double *) data;
  // pedantic checks
  if ((!fpout) || (!data) || (dp != data) || (ntowrite <= 0) || (n != ntowrite)) {
    fprintf(stderr,"Bad parameter\n");
    return(0);
  }
  clearerr(stderr);  // only needed for debug
  clearerr(fpout);
  /* attempt to write blocks of doubles */
  size_t m = fwrite(dp, sizeof(double), n, fpout);
  if (m != n) {
    fprintf(stderr,"Write error: %d\n",ferror(fpout));
    clearerr(fpout);
    return(-1);
  }
  if (fflush(fpout)) {
    fprintf(stderr,"Flush error: %d\n",ferror(fpout));
    clearerr(fpout);
    return(-1);
  }
  return(1);
}
  1. ntowrite s/b size_t,一个无符号整数。 ntowrite = 0 可能会导致对 m 的混淆。 ntowrite < 0 引起问题。
  2. m 未声明,假定为 size_t。
  3. 格式化“数据[%d]=%g\n”s/b“数据[%ld]=%g\n”
  4. 我 s/b size_t。
  5. (size_t)(ntowrite*sizeof(double)) s/b ((size_t)ntowrite)*sizeof(double)。参见#7。
  6. fprintf(stderr... 不需要。这是的问题。
  7. fwrite(..., size, n ...) 即使 size * n 溢出也能正常工作。比 OP 更安全。

关于c - 在不先调用 fflush 或写入 stderr 的情况下使用 fwrite,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17365583/

相关文章:

c++ - 如何从 OCIErrorGet 获取约束错误?

c - 将结构写入文件 C

batch-file - bat 将 stderr 重定向到 stdout 有奇怪的行为

c++ - GNU 的 nana 库死了吗?是否有后继者在使用?

c - 结构体为其成员分配内存

c++ - fwrite 比 Windows 中的 WriteFile 快吗?

bash - 进程替换捕获stderr

bash - 如何重定向写入 tty 的程序?

c++ - 我可以使用 nullptr 作为 Linux 系统调用参数吗?

无法使用 fwrite 将 int 写入文件