Learn C Tutorial: SD Minimal.side - Making file available to multiple functions
John Kauffman
Posts: 653
The sample SD Minimal.side here opens a file to write then opens same file again to read.
At time of write it creates the fp object and opens. For read it re-opens the existing fp object. Write and Read operations are both in one function main().
A function other than main() does not have access to fp. What if the write and read are in 2 functions other than main()?
How to write and place the creation of fp so it is available to any function?
- thanks
At time of write it creates the fp object and opens. For read it re-opens the existing fp object. Write and Read operations are both in one function main().
A function other than main() does not have access to fp. What if the write and read are in 2 functions other than main()?
How to write and place the creation of fp so it is available to any function?
- thanks
/* SD Minimal.side Create test.txt, write characters in, read back out, display. */ #include "simpletools.h" // Include simpletools header int DO = 22, CLK = 23, DI = 24, CS = 25; // SD card pins on Propeller BOE int main(void) // main function { sd_mount(DO, CLK, DI, CS); // Mount SD card FILE* fp = fopen("test.txt", "w"); // Open a file for writing fwrite("Testing 123...\n", 1, 15, fp); // Add contents to the file fclose(fp); // Close the file char s[15]; // Buffer for characters fp = fopen("test.txt", "r"); // Reopen file for reading fread(s, 1, 15, fp); // Read 15 characters fclose(fp); // Close the file print("First 15 chars in test.txt:\n"); // Display heading print("%s", s); // Display characters print("\n"); // With a newline at the end }
Comments
However, if you really want to use globals...
Now, in this case, "fp" doesn't need to be shared. We could make fp local to both doWrite and doRead with no ill effect.
All that is being shared is the space for an address, because fp is a pointer. No significant change in the above two samples. However, to show how global variables work, I'll show two other examples too:
We expect the above to print 6 and then 9. This is because the second assignment references itself in the assignment. Compare that with the second assignment of fp in your example "fp = fopen("test.txt", "r")". Notice that fp is not referenced in the assignment - the old value is completely ignored and overwritten.
We could break my example with x into separate functions with a global variable though:
And this will print the same as above. However, clean code suggests removing all global variables (constants are okay, just not variables that changes)
And this will again print 6 and then 9, but without the need for globals.
"Available to any function" is probably not what you want. Available to specific functions is pretty easy though. It's also worth noting that in this case, the variable "fp" is a pointer to a completely different thing when used for reading and writing. Have a look:
This bit of code declares a variable called fp (on the stack) that is a pointer to a FILE object. That pointer is returned by the fopen() function, in this case opening a file for write-only access (the "w" at the end of fopen). The file is written to, then closed. That means that the fp variable is now pointing at memory it doesn't own any more - that object has been thrown away during the fclose() call.
The next bit of code:
...opens a file, but this time for reading. It doesn't matter that it's the same file that you wrote previously because it's being opened in a completely different mode ("r", meaning read-only) so the fp variable is pointing to a different object with new contents, it's just re-using the fp variable to point to it because it's convenient.
Now, if you want to be able to read from or write to this file in a number of different functions, that's a different question, with a pretty easy answer. Pass the fp variable around, like this:
You can pass the pointer variable fp around just like anything else. Notice that I gave it a different name in my "WriteSomeOtherStuff" function - the 'fp' variable is being passed as an argument to the function, and has the local alias 'fileHandle', but it's the same object in use in both places.
So far I think I get:
I thought it would be more efficient to create the fp once. But that is not right because it is just a pointer that will be pointing to "nothing" after each use. The only preservation would be the name, not the pointer value and not the file to which the pointer referred.
In general, rather than create global variables, pass the values as parameters when needed.
Much thanks.