简体   繁体   中英

fscanf array pointer array in C

I need help for this situation

I want with the method ReadFile() with fscanf directly write the values from the file in my array table[] in main.

Can anyone help?

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

Use:

ReadFile(table);

because the compiler uses the address when you mention an array, so this passes the array address. You don't need & here.

So:

void ReadFile(float *P) {

because a "pointer to" can also be an "array of"

And so:

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

First you need to understand what means float (*P)[] .

In 2 words it means a pointer to an array of floats with out bounds. Actually, it's just a pointer to a pointer to float value.

And in your scanf line:

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

Your are taking an address of a pointer which points to an array of floats and you are shifting address by 0, 1, 2, 3, 4 (Depends on argument).

So you are assigning float value to a pointer. Not to a float variable.

To fix it, you can dereference P instead of taking address:

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

So in this line we are dereferencing P by operation *P. So now we got a pointer to float (when P is a pointer to pointer to float). With operation (*P)[0] we are incrementing pointer with 0. so now it will point to (address + 0) element. And after it we dereferencing it and getting the value of the 0 element. So basically (*P)[0] is the same as *(*P + 0) . But since we don't need a value but the address of the element, we are using operator & to get it. So finally, we get &(*P)[0] which equals to &*(*P + 0) or just (*P + 0) .

To make it simple, we can use just a pointer to float in function parameters.

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

You can compare these 2 lines:

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

And see that it simplified arguments of fscanf because we don't need to dereference pointer anymore.

Also, you can notice that call to ReadFile has a different argument:

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

        ReadFile(table);

Right now it's just a table which implicitly casts to pointer to float. So it will be the same as ReadFile(&table[0]);

The other way to pass arguments to fscanf is to use pointer arithmetic instead of arrays:

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

Because P + 1 is the same as &P[1]

Did I make it clear? I think not. But I tried:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM