【问题标题】:fscanf array pointer array in CC中的fscanf数组指针数组
【发布时间】:2021-07-30 12:17:49
【问题描述】:

这种情况我需要帮助

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

谁能帮忙?

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);
}

【问题讨论】:

    标签: arrays c pointers scanf


    【解决方案1】:

    首先你需要了解float (*P)[]是什么意思。

    用 2 个词来说,它意味着一个指向浮点数组的指针,没有边界。实际上, 它只是一个指向浮点值的指针。

    在你的 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。所以现在我们得到了一个指向浮点数的指针(当 P 是指向浮点数的指针时)。通过操作 (*P)[0] 我们将指针递增 0。所以现在它将指向 (address + 0) 元素。在它之后我们取消引用它并获取 0 元素的值。 所以基本上(*P)[0]*(*P + 0) 是一样的。 但是由于我们不需要值而是元素的地址,所以我们使用运算符 & 来获取它。所以最后,我们得到&amp;(*P)[0] 等于&amp;*(*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;
    }
    
    

    您可以比较以下 2 行:

    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);
    

    现在它只是一个隐式转换为浮点指针的表。 所以会和ReadFile(&amp;table[0]);一样

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

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

    因为P + 1&amp;P[1] 相同

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

    【讨论】:

    • 它有效 :) 谢谢你的好解释 :)
    【解决方案2】:

    用途:

    ReadFile(table);
    

    因为当你提到一个数组时编译器使用地址,所以这传递了数组地址。这里不需要&amp;

    所以:

    void ReadFile(float *P) {
    

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

    所以:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-25
      • 1970-01-01
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-25
      相关资源
      最近更新 更多