C 在函数调用之间保留文件指针

C 在函数调用之间保留文件指针,c,file-io,binaryfiles,C,File Io,Binaryfiles,我有一个代码,可以多次访问二进制文件。每次调用该函数时,它都会打开文件进行读取,并且只读取所需的字节数(比如每次nbytes) 二进制文件包含时间序列数据,我希望它能够通过循环运行函数调用,每次我调用函数打开同一个文件时,它都需要读取下一个数据块,也就是说,我不希望每次都重置文件指针。有办法做到这一点吗 该函数如下所示: int readBinary(float *binImage, int gelements) { imageFile = fopen("tmpImageFile", "

我有一个代码,可以多次访问二进制文件。每次调用该函数时,它都会打开文件进行读取,并且只读取所需的字节数(比如每次
n
bytes)

二进制文件包含时间序列数据,我希望它能够通过循环运行函数调用,每次我调用函数打开同一个文件时,它都需要读取下一个数据块,也就是说,我不希望每次都重置文件指针。有办法做到这一点吗

该函数如下所示:

int readBinary(float *binImage, int gelements) {
    imageFile = fopen("tmpImageFile", "r");
    if (imageFile == NULL) {
       fprintf(stderr, "Error opening file\n");
       return (1);
    }
    fread(binImage, sizeof(float), gelements, imageFile);
    return 0;
}

在我的主代码中,我想通过一个循环运行它,每次给它一个大小为
gelements
的数组
binImage
。如果可以避免的话,我宁愿不给它一个大小为
gelements*nLoop
的数组

您可以将文件指针设为静态并将其初始化为NULL。然后下一次继续,如果它不为NULL,则它包含打开的文件。此外,在关闭文件时,请确保再次将其设置为NULL。全局指针也可以这样做

int readBinary(float *binImage, int gelements) {
static imageFile = NULL;
if(imageFile == NULL ) imageFile = fopen("tmpImageFile", "r");
if (imageFile == NULL) {
   fprintf(stderr, "Error opening file\n");
   return (1);
}
fread(binImage, sizeof(float), gelements, imageFile);
return 0;
}

使用静态变量以保留文件指针:

int readBinary(float *binImage, int gelements) {
    static FILE *imageFile = NULL;
    if (imageFile == NULL) {
       imageFile = fopen("tmpImageFile", "r");
       if (imageFile == NULL) {
          perror("Error opening file: ");
          return (1);
       }
    }
    fread(binImage, sizeof(float), gelements, imageFile);
    return 0;
}

我将
文件*
作为参数传递给函数:

int readBinary(float *binImage, int gelements, FILE *imageFile) {
    int bytes = fread(binImage, sizeof(float), gelements, imageFile);
    return bytes != -1 ? 0 : 1;
}

我还添加了对
fread
返回值的简单检查,并将其转换为您的返回值约定。虽然这个函数看起来很简单,但您可以直接调用
fread
,除非您想在其中添加错误打印之类的内容。

快速经验法则如下

“如果你能在职能之间适当地划分职责,生活会变得更轻松”

“如果使用静态或全局变量,生活会变得复杂”

在这种情况下,赋予
readBinary
函数管理
文件和读取数据的责任太重了

请注意,该函数不会关闭手柄。

如果句柄是函数中的本地静态句柄,则无法关闭它。 这还意味着函数将永远被锁定为只使用“tmpImageFile”(从函数的签名或缺少的文档中看不出这一点)

如果句柄是全局句柄,则可能会过早关闭它

请注意,如果您删除了“打开文件”的责任,
readBinary
函数只是对
fread
的调用

处理此问题的最佳方法是完全跳过
readBinary
函数

你说你有一个调用者在循环中读取数据。 让此调用者负责打开
文件
,直接在循环中使用
fread
,完成后关闭文件

现在,这可能会让打电话的人承担太多的责任。只需让调用者接受
文件*
作为参数,并将文件管理责任交给调用者即可。
或者调用者的调用者的调用者,这取决于管理文件生命周期的意义所在。

为什么要不断重新打开文件?只要打开它一次,然后继续使用它。