0

Is it possible to have a pointer notation to a variable outside of its scope?

Here is my main:

int main(){
    int number[15];
    readNumbers();
    return 0;
}

Here is my readNumbers() function:

void readNumbers() {
    FILE *fp;
    fp = fopen("/Users/Documents/testNumbers.txt", "r"); 
    if (fp == NULL) {
        printf("File could not be loaded!");
        exit(0);
    }
    if (fp != NULL) {
        int c;
        while ((c = fgetc(fp)) != EOF) {
            putchar(c);
        }
        fclose(fp);
    }
    return 0;
}

I'm trying to get my readNumbers() function to add numbers from testNumbers.txt into the array of 15 of type int in my main (int* num[15]).

Would this work?:

int num[15]; // This will be in the main

&&

numRef *ip; // This will be in the main also as a pointer variable declaration

And then having instead of int c; in my readScores() function have this instead?:

ip = int* num[15]; // The variable that will store the address of int in pointer variable

Very, very confused about pointer notation. Help would be awesome! Thanks!

Brian McFarland
  • 9,052
  • 6
  • 38
  • 56
  • 1
    You're not just confused about the notation; you seem to be confused about the concept of pointers as well. – user253751 Feb 09 '16 at 22:12
  • @immibis I just started practicing pointers today. Watched a few online tutorials on C pointers, but I thought I'd come here to get some real help. – Steve Johnson Feb 09 '16 at 22:13
  • Try to do it by yourself. And then show your code here, complete please, so we can compile it. – Martín Muñoz del Río Feb 09 '16 at 22:16
  • If `int number[15];` was global you could. If you want the array to be inside main then you need to pass the number variable to the readNumbers function – Jerry Jeremiah Feb 09 '16 at 22:17
  • By passing `number` as an argument to the function **and its length**. – Weather Vane Feb 09 '16 at 22:17
  • @MartínMuñozdelRío, That's the thing. I tried doing exactly what I wrote down and it doesn't work. I'm stumped as a rock right now. – Steve Johnson Feb 09 '16 at 22:17
  • @JerryJeremiah, How would I pass that number variable to the `readNumbers()` function exactly? – Steve Johnson Feb 09 '16 at 22:19
  • And `ip = int* num[100];` makes no sense whatsoever; you might want `ip = &num[0];`. (num[0] being the first element of num, and &num[0] being a pointer to that) – user253751 Feb 09 '16 at 22:19
  • @immibis, `numRef` is a pointer variable declaration... I think? Like I said. I'm just beginning my journey into pointers in C. – Steve Johnson Feb 09 '16 at 22:19
  • @immibis, Could you show me a sample code showing what it does and maybe add a few lines of comments so I could understand? – Steve Johnson Feb 09 '16 at 22:20
  • Imagine being at a cafeteria where the food is behind the counter. You are provided a tray, and someone is behind the counter to give you the food. They need to put it on the tray, but they can't reach across the counter. What do you do? You give them the tray, they put the food on it, and return the tray to you. Now, imagine the tray is an array, the food is some number, the person behind the counter is a function, and you are the caller. – paddy Feb 09 '16 at 22:21
  • @paddy, Thank you for an awesome representation of that idea. However, I'm still clueless as how to code a pointer at the moment. Should I even bother continuing to learn code? Seems like I really suck at it. Java seemed to go fine. – Steve Johnson Feb 09 '16 at 22:23
  • Don't give up. Read Kernighan & Ritchie's _"The C Programming Language"_. You could also read [this StackOverflow FAQ](http://stackoverflow.com/q/4810664/1553090), but it might be confusing if you are struggling with the basics. – paddy Feb 09 '16 at 22:28
  • For future reference - don't tag questions as both C and C++. A lot of C can be compiled as C++, but they are two different languages. In C++, you could use a data type like `std::vector` or `std::array`, pass an array by reference, or do it the "C way". In C, the pointer + length is pretty much the only option. – Brian McFarland Feb 09 '16 at 22:31

3 Answers3

1

You cannot access variables in other functions directly. There are three ways to do what you want. Only the third one is generally accepted as a good idea.

  1. Make the number array global so it can be used from both functions:

    int number[15];
    
    int main() {
        readNumbers(); // side effect: fills the global number array
        // use the filled global number array here
        return 0;
    }
    
    void readNumbers() {  // side effect: fills the global number array
        FILE *fp;
        fp = fopen("/Users/Documents/testNumbers.txt", "r"); 
        if (fp == NULL) {
            printf("File could not be loaded!");
            exit(0);
        }
        if (fp != NULL) {
            int c;
            while ((c = fgetc(fp)) != EOF) {
                // fill the global numbers array with data
                putchar(c);
            }
            fclose(fp);
        }
        return 0;
    }
    
  2. Declare a static number array in readNumbers and return it:

    int main() {
        int* number = readNumbers();
        // use the filled number array here
        return 0;
    }
    
    int* readNumbers() {
        static int number[15];
        FILE *fp;
        fp = fopen("/Users/Documents/testNumbers.txt", "r"); 
        if (fp == NULL) {
            printf("File could not be loaded!");
            exit(0);
        }
        if (fp != NULL) {
            int c;
            while ((c = fgetc(fp)) != EOF) {
                // fill the static numbers array with data
                putchar(c);
            }
            fclose(fp);
        }
        return number;
    }
    
  3. Pass the number array into readNumbers so it can be filled:

    int main() {
        static int number[15];
        readNumbers(number);
        // use the filled number array here
        return 0;
    }
    
    void readNumbers(int* number) {
        FILE *fp;
        fp = fopen("/Users/Documents/testNumbers.txt", "r"); 
        if (fp == NULL) {
            printf("File could not be loaded!");
            exit(0);
        }
        if (fp != NULL) {
            int c;
            while ((c = fgetc(fp)) != EOF) {
                // fill the passed in numbers array with data
                putchar(c);
            }
            fclose(fp);
        }
        return 0;
    }
    
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
  • Better to pass array as an argument. Avoid globals. – lost_in_the_source Feb 09 '16 at 23:02
  • @stackptr I clearly said the first two were a bad idea - only the third would be a good way for this particular question. But the point of answering the question is to do it as comprehensively as possible because the OP isn't the only one that will get value from the answer. – Jerry Jeremiah Feb 10 '16 at 01:01
0

One easy way could be to pass the pointer to the number array as argument to your function:

int main(){
    int number[15];
    readNumbers(numbers, 15);  //<======
    return 0;
}

and use this parameter in your function:

void readNumbers(int *ip, size_t ipmax) {
   ...
}

You would use in your function ip[xxx] as if it were an array. The only think is that its size is unknown in the function. This is why I suggest to pass the size as extra parameter.

Another way would be to use a vector instead, and pass it by reference:

    vector<int> number(15);    // a vector of 15 elements.  it can increase further  
    readNumbers(numbers, 15);  //<======

...

void readNumbers(vector<int> &v) {  // the size if v.size()
   ...
}
Christophe
  • 68,716
  • 7
  • 72
  • 138
0

This is how you could implement readnums using dynamic memory allocation; that is, the caller just passes a pointer, and when the function returns, it will contain the numbers from the file. This way, you don't need to hardcode a limit in your code.

#define INITALLOC    16
#define STEP          8
typedef long ssize_t;
ssize_t readnums(FILE *fp, int **arr)
{
    size_t i, nalloced; /* #ints read and #ints malloced, respectively */
    int *tmp;

    /* allocate INITALLOC ints on the heap. */
    if ((*arr = malloc(INITALLOC * sizeof (int))) == NULL)
        return -1;
    nalloced = INITALLOC;
    /* fscanf reads the next int. It returns 1 if an int was found */
    for (i = 0; fscanf(fp, "%d", *arr + i) == 1; ++i)
        if (i == nalloced - 1) { /* if we run out of space, alloc more */
            /* store it in a temporary, otherwise previous data is lost on 
               failure */
            if ((tmp = realloc(*arr, (nalloced += STEP)*sizeof(int)))==NULL)
                return -1;
            *arr = tmp;
        }

    /* return #ints read */
    return i;
}

Note that the caller must free the memory:

int *arr;
if (readnums(fp, &arr) == -1)
    fprintf(stderr, "Error\n");
else {
    /* ... do stuff ... */
    free(arr);
}
lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75