C中的fscanf数组指针数组

fscanf array pointer array in C

这种情况我需要帮助

我想使用方法 ReadFile()fscanf 直接将文件中的值写入我的数组 table[] 中的 main.

有人能帮忙吗?

int main() {
  float table[] = {1.0, 2.0, 4.0, 8.0, 10.0};
  ReadFile(&table);
  printf(/*...print table at this point...*/)
}

void ReadFile(float (*P)[]) {
  FILE *fp;
  int i;

  // Exists? 
  fp = fopen("results.txt", "r");
  if (fp == NULL) {
    return;
  }

  // read file 
  fscanf(fp, "<p> %f %f %f %f %f\n", (&P)[0], (&P)[1], (&P)[2], (&P)[3],
      (&P)[4]);

  fclose(fp);
}

使用:

ReadFile(table);

因为你提到数组的时候编译器使用的是地址,所以这里传递的是数组地址。这里不需要&

所以:

void ReadFile(float *P) {

因为“指向”的指针也可以是“数组”

等等:

 fscanf(fp, "<p> %f %f %f %f %f\n", &P[0], &P[1], &P[2], &P[3], &P[4]);

首先你需要明白float (*P)[].

是什么意思

简而言之,它的意思是指向一个没有边界的浮点数组的指针。实际上, 它只是一个指向浮点值指针的指针。

在你的 scanf 行中:

fscanf(fp, "<p> %f %f %f %f %f\n",(&P)[0],(&P)[1],(&P)[2],(&P)[3],(&P)[4]);

您正在获取指向浮点数组的指针的地址,并且您正在将地址移动 0、1、2、3、4(取决于参数)。

因此您正在将浮点值分配给指针。不是浮点变量。

要修复它,您可以取消引用 P 而不是获取地址:

fscanf(fp, "<p> %f %f %f %f %f\n", &(*P)[0], &(*P)[1], &(*P)[2], &(*P)[3], &(*P)[4]);

所以在这一行中,我们通过操作 *P 取消引用 P。所以现在我们得到了一个指向 float 的指针(当 P 是指向 float 的指针时)。通过操作 (*P)[0],我们将指针递增 0。所以现在它将指向 (address + 0) 元素。在它之后我们取消引用它并获得 0 元素的值。 所以基本上 (*P)[0]*(*P + 0) 相同。 但是由于我们不需要值而是元素的地址,因此我们使用运算符 & 来获取它。所以最后,我们得到 &(*P)[0] 等于 &*(*P + 0) 或者只是 (*P + 0).

为简单起见,我们可以在函数参数中只使用一个浮点指针。

#include <errno.h>
#include <stdio.h>

void ReadFile(float *P) { 
        FILE *fp; 
        int i;

        fp = fopen("results.txt","r"); 

        if (fp == NULL) {
                perror("failed to open file");
                return;
        }

        // read file 
        fscanf(fp, "<p> %f %f %f %f %f\n", &P[0], &P[1], &P[2], &P[3], &P[4]);

        fclose(fp);
}

int main() {
        float table[] = {1.0,2.0,4.0,8.0,10.0}; 

        ReadFile(table);

        for (size_t i = 0; i < sizeof(table) / sizeof(table[0]); ++i)
                printf("%f ", table[i]);
        printf("\n");

        return 0;
}

你可以比较这两行:

fscanf(fp, "<p> %f %f %f %f %f\n", &(*P)[0], &(*P)[1], &(*P)[2], &(*P)[3], &(*P)[4]);
fscanf(fp, "<p> %f %f %f %f %f\n", &P[0], &P[1], &P[2], &P[3], &P[4]);

并且看到它简化了 fscanf 的参数,因为我们不再需要取消引用指针。

此外,您可以注意到对 ReadFile 的调用具有不同的参数:

        float table[] = {1.0,2.0,4.0,8.0,10.0}; 

        ReadFile(table);

现在它只是一个 table 隐式转换为浮点数的指针。 所以它将与 ReadFile(&table[0]);

相同

将参数传递给 fscanf 的另一种方法是使用指针算法而不是数组:

fscanf(fp, "<p> %f %f %f %f %f\n", P + 0, P + 1, P + 2, P + 3, P + 4);

因为P + 1&P[1]一样

我说清楚了吗?我想不是。但我试过了:)