file_read block

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
vashek vashek is offline Offline Sep 10th, 2009, 10:26 am |
0
Hi All,

this is my first C code in my professional life. I wanted to write a common function to retrieve file content. I do not know whether below code is upto the mark or not.

any Suggestions/modifications/tips are greatly appreciated.

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. /*
  5. Function Name: get_file_content
  6. Description: fills content of the file to given buffer.
  7. Parameters: file to be read(in), Mode(in), destination buffer(out)
  8. Return Type: pointer to content (SUCCESS), otherwise NULL
  9. */
  10. char* get_file_content (char *file_name, char *file_mode, char *file_content)
  11. {
  12. FILE *fp;
  13. long file_size;
  14. size_t bytes_read;
  15.  
  16. //open file
  17. if (!(fp = fopen (file_name, file_mode))) {
  18. printf ("*** Unable to open file ***\n");
  19. return NULL;
  20. }
  21.  
  22. //get file size
  23. fseek (fp, 0, SEEK_END);
  24. file_size = ftell (fp);
  25. rewind (fp);
  26. printf("*** size = %ld ***\n", file_size);
  27.  
  28. //check memory
  29. file_content = (char *) realloc (file_content, sizeof(char) * file_size);
  30. if (file_content == NULL) {
  31. printf("*** memory insufficient ***");
  32. fclose (fp);
  33. return NULL;
  34. }
  35.  
  36. //get content
  37. bytes_read = fread (file_content, sizeof(char), file_size, fp);
  38. if (bytes_read != file_size) {
  39. printf("*** read failed ***");
  40. fclose (fp);
  41. return NULL;
  42. }
  43.  
  44. //put EOS
  45. file_content[bytes_read-1] = '\0';
  46.  
  47. //clean
  48. fclose (fp);
  49.  
  50. //success
  51. return file_content;
  52. }
  53.  
  54.  
  55. int main (int argC, char *argV[])
  56. {
  57. int status = -1;
  58. char *file_content = (char *) malloc (2);
  59. if ((file_content = get_file_content ("metadata.txt", "r", file_content)) == NULL){
  60. status = 1;
  61. goto FREE_BLOCK;
  62. }
  63.  
  64. printf("\n#%s#\n", file_content);
  65.  
  66.  
  67. FREE_BLOCK:
  68. free (file_content);
  69.  
  70. return 0;
  71. }


Regards,
Vashek
Last edited by vashek; Sep 10th, 2009 at 10:27 am.
Quick reply to this message  
C Syntax
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4.  
  5. /*
  6. Function Name: get_file_content
  7. Description: fills content of the file to given buffer.
  8. Parameters: file to be read(in), Mode(in), destination buffer(out)
  9. Return Type: pointer to content (SUCCESS), otherwise NULL
  10. */
  11. char* get_file_content (char *file_name, char *file_mode, char *file_content)
  12. {
  13. FILE *fp;
  14. long file_size;
  15. size_t bytes_read;
  16.  
  17. //open file
  18. if (!(fp = fopen (file_name, file_mode))) {
  19. printf ("*** Unable to open file ***\n");
  20. return NULL;
  21. }
  22.  
  23. //get file size
  24. fseek (fp, 0, SEEK_END);
  25. file_size = ftell (fp);
  26. rewind (fp);
  27. printf("*** size = %ld ***\n", file_size);
  28.  
  29. //check memory
  30. file_content = (char *) realloc (file_content, sizeof(char) * file_size);
  31. if (file_content == NULL) {
  32. printf("*** memory insufficient ***");
  33. fclose (fp);
  34. return NULL;
  35. }
  36.  
  37. //get content
  38. bytes_read = fread (file_content, sizeof(char), file_size, fp);
  39. if (bytes_read != file_size) {
  40. printf("*** read failed ***");
  41. fclose (fp);
  42. return NULL;
  43. }
  44.  
  45. //put EOS
  46. file_content[bytes_read-1] = '\0';
  47.  
  48. //clean
  49. fclose (fp);
  50.  
  51. //success
  52. return file_content;
  53. }
  54.  
  55.  
  56. int main (int argC, char *argV[])
  57. {
  58. int status = -1;
  59. char *file_content = (char *) malloc (2);
  60. if ((file_content = get_file_content ("metadata.txt", "r", file_content)) == NULL){
  61. status = 1;
  62. goto FREE_BLOCK;
  63. }
  64.  
  65. printf("\n#%s#\n", file_content);
  66.  
  67.  
  68. FREE_BLOCK:
  69. free (file_content);
  70.  
  71. return 0;
  72. }
1
Salem Salem is offline Offline | Sep 10th, 2009
> file_content = (char *) realloc (file_content, sizeof(char) * file_size);
Is this C or C++?
If it is C, then you don't need the cast.

However, what happens if realloc fails? The problem is, you just trashed your pointer with NULL, thus making it impossible to free a memory leak (if that was your only pointer).

Also, if realloc MOVES the memory block, you've only updated your local copy of the pointer (the one in main still points to the original (and now freed) block).

The whole 3rd parameter is a waste of effort. You may as well have a local pointer, initialise it with malloc and return it.

> file_content[bytes_read-1] = '\0';
What if filesize was in fact zero?
Here you're off into the weeds somewhere, getting bogged down by a segfault no doubt.
Even if the file length is non-zero, you trash the last char of the file.

Also, what if someone tries to load in say a DVD image file - will you handle that well?

What if they call the function with a mode of "w" ?
 
0
wildgoose wildgoose is offline Offline | Sep 10th, 2009
I am assuming you are reading an ASCII file. Do not overwrite the last byte in the file. Get file length. Allocated buffer of size+1. Read file of size into the buffer. Set terminator (that extra byte you appended) buffer[size]=0;

It'll handle the empty file scenario! But you really should have a length check for zero, and not read the zero bytes!

Or handle an empty file as a special kind of error!

I personally prefer returning bool and passing the address of the pointer as an argument along with an address of a length count just so I can have both whether I chose to ignore the length count or not! Then it doesn't matter if the file is ASCII or binary, you can use the same loader for all file loads into memory!
Last edited by wildgoose; Sep 10th, 2009 at 2:13 pm.
 
 

Message:


Similar Threads
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC