---------------------------------------------------------------------------------------------
| My Training Period: xx hours
9.7 Random Access To Disk Files
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
THIS IS THE FIRST LINE OF TEXT, tesseven.txt file THIS IS THE SECOND LINE OF TEXT, tesseven.txt file THIS IS THE THIRD LINE OF TEXT, tesseven.txt file THIS IS THE FOURTH LINE OF TEXT, tesseven.txt file
The content of tesseven.txt file
|
1. // random access to a file
2. #include <stdio.h>
3. #include <stdlib.h>
4.
5. enum {SUCCESS, FAIL, MAX_LEN = 120};
6.
7. // function prototypes, seek the file position indicator
8. void PtrSeek(FILE *fptr);
9. // function prototype, tell the file position indicator...
10. long PtrTell(FILE *fptr);
11. // function prototype read and writes...
12. void DataRead(FILE *fptr);
13. int ErrorMsg(char *str);
14.
15. int main(void)
16. {
17. FILE *fptr;
18. char filename[] = "c:\\Temp\\tesseven.txt";
19. int reval = SUCCESS;
20.
21. // if there is some error opening file for reading...
22. if((fptr = fopen(filename, "r")) == NULL)
23. {
24. reval = ErrorMsg(filename);
25. }
26. // if opening is successful..
27. else
28. {
29. // PtrSeek() function call...
30. PtrSeek(fptr);
31. //close the file stream...
32. if(fclose(fptr)==0)
33. printf("%s successfully closed.\n", filename);
34. }
35. // for Borland...
36. // system("pause");
37. return reval;
38. }
39.
40. // PtrSeek() function definition
41. void PtrSeek(FILE *fptr)
42. {
43. long offset1, offset2, offset3, offset4;
44.
45. offset1 = PtrTell(fptr);
46. DataRead(fptr);
47. offset2 = PtrTell(fptr);
48. DataRead(fptr);
49. offset3 = PtrTell(fptr);
50. DataRead(fptr);
51. offset4 = PtrTell(fptr);
52. DataRead(fptr);
53.
54. printf("\nReread the tesseven.txt, in random order:\n");
55. // re-read the 2nd line of the tesseven.txt
56. fseek(fptr, offset2, SEEK_SET);
57. DataRead(fptr);
58. // re-read the 1st line of the tesseven.txt
59. fseek(fptr, offset1, SEEK_SET);
60. DataRead(fptr);
61. // re-read the 4th line of the tesseven.txt
62. fseek(fptr, offset4, SEEK_SET);
63. DataRead(fptr);
64. // re-read the 3rd line of the tesseven.txt
65. fseek(fptr, offset3, SEEK_SET);
66. DataRead(fptr);
67. }
68.
69. // PtrTell() function definition
70. long PtrTell(FILE *fptr)
71. {
72. long reval;
73. // tell the fptr position...
74. reval = ftell(fptr);
75. printf("The fptr is at %ld\n", reval);
76. return reval;
77. }
78.
79. // DataRead() function definition
80. void DataRead(FILE *fptr)
81. {
82. char buff[MAX_LEN];
83. // reading line of text at the fptr position...
84. fgets(buff, MAX_LEN, fptr);
85. // and display the text...
86. printf("-->%s\n", buff);
87. }
88.
89. // error message function definition
90. int ErrorMsg(char *str)
91. {
92. // display this error message...
93. printf("Problem, cannot open %s.\n", str);
94. return FAIL;
95. }
We try to open the tesseven.txt file for reading by calling thefopen() function. If successful, we invoke the PtrSeek() function with thefptr file pointer as the argument in line 30.
PtrSeek(fptr);
The definition of our first function PtrSeek() is shown in lines 41-67. The statement in line 45 obtains the original value of the fptr file pointer by calling another function,PtrTell(), which is defined in lines 70–77.
ThePtrTell() function can find and print out the value of the file position indicator with the help of theftell() function.
The third function,DataRead() is called to read one line of characters from the opened file and print out the line of characters on the screen. Line 47 gets the new value of the fptr file position indicator right after the reading and assigns the value to another long variable, offset2.
Then theDataRead() function in line 48 reads the second line of characters from the opened file. Line 49 obtains the value of the file position indicator that points to the first byte of the third line and assigns the value to the third long variableoffset3 and so on for the fourth line of text.
Line 50 calls the DataRead() function to read the third line and print it out on the screen.
From the first portion of the output, you can see the four different values of the file position indicator at four different positions, and the four lines of texts. The four values of the file position indicator are saved byoffset1, offset2,offset3 and offset4 respectively.
Then, we read the lines of text randomly, one line at a time. Firstly read the second line, then the first line, fourth and finally the third one.
C function, called rewind(), can be used to rewind the file position indicator. The prototype for therewind() function is:
void rewind(FILE *stream);
Here,stream is the file pointer associated with an opened file. No value is returned by rewind() function. In fact the following statement of rewind() function:
rewind(fptr);
Is equivalent to this:
(void) fseek(fptr, 0L, SEEK_SET);
Thevoid data type is cast to thefseek() function because therewind() function does not return a value. Study the following program example.
This program also contains example of reading and writing binary data. We create and open the teseight.bin file for writing.
1. // reading, writing, rewind and binary data
2. #include <stdio.h>
3. #include <stdlib.h>
4.
5. enum {SUCCESS, FAIL, MAX_NUM = 5};
6.
7. // function prototypes...
8. void DataWrite(FILE *fout);
9. void DataRead(FILE *fin);
10. int ErrorMsg(char *str);
11.
12. int main(void)
13. {
14. FILE *fptr;
15. // binary type files...
16. char filename[] = "c:\\Temp\\teseight.bin";
17. int reval = SUCCESS;
18.
19. // test for creating, opening binary file for writing...
20. if((fptr = fopen(filename, "wb+")) == NULL)
21. {
22. reval = ErrorMsg(filename);
23. }
24. else
25. {
26. // write data into file teseight.bin
27. DataWrite(fptr);
28. // reset the file position indicator...
29. rewind(fptr);
30. // read data...
31. DataRead(fptr);
32. // close the file stream...
33. if(fclose(fptr)==0)
34. printf("%s successfully closed\n", filename);
35. }
36. // for Borland
37. // system("pause");
38. return reval;
39. }
40.
41. // DataWrite() function definition
42. void DataWrite(FILE *fout)
43. {
44. int i;
45. double buff[MAX_NUM] = { 145.23, 589.69, 122.12, 253.21, 987.234};
46.
47. printf("The size of buff: %d-byte\n", sizeof(buff));
48. for(i=0; i<MAX_NUM; i++)
49. {
50. printf("%5.2f\n", buff[i]);
51. fwrite(&buff[i], sizeof(double), 1, fout);
52. }
53. }
54.
55. // DataRead() function definition
56. void DataRead(FILE *fin)
57. {
58. int i;
59. double x;
60.
61. printf("\nReread from the binary file:\n");
62. for(i=0; i<MAX_NUM; i++)
63. {
64. fread(&x, sizeof(double), (size_t)1, fin);
65. printf("%5.2f\n", x);
66. }
67. }
68.
69. // ErrorMsg() function definition
70. int ErrorMsg(char *str)
71. {
72. printf("Cannot open %s.\n", str);
73. return FAIL;
74. }
|
The prototype for the fscan() function is:
int fscanf(FILE *stream, const char *format,…);
stream is the file pointer associated with an opened file. format, which usage is similar to the scanf() function, is achar pointer pointing to a string that contains the format specifiers. If successful, the fscan() function returns the number of data items read. Otherwise, the function returns EOF.
The prototype for the fprintf() function is:
int fprintf(FILE *stream, const char *format, …);
Here,stream is the file pointer associated with an opened file. format, is similar as in the printf() function, is achar pointer pointing to a string that contains the format specifiers.
If successful, the fprintf() function returns the number of formatted expressions. Otherwise, the function returns a negative value.
Let try a program example. Firstly create testcal.txt file with the following data and save it.
23 12 33 10 4 6 44 31 7 50
Then create another text file named testavg.txt for writing the average value computed from data read from testcal.txt file. Then compile and run the following program.
/* C Program to calculate the average of a list of numbers. */
/* calculate the total from one file, output the average into another file */
#include <stdio.h>
/* for exit() */
#include <stdlib.h>
int main(void)
{
int value, total = 0, count = 0;
/* fileptrIn and fileptrOut are variables of type (FILE *) */
FILE * fileptrIn, * fileptrOut;
char filenameIn[100], filenameOut[100];
printf("Please enter an input filename (use path if needed):\n");
scanf("%s", filenameIn);
printf("Please enter an output filename (use path if needed):\n");
scanf("%s", filenameOut);
/* open files for reading, "r" and writing, "w" */
if((fileptrIn = fopen(filenameIn, "r")) == NULL)
{
printf("Error opening %s for reading.\n", filenameIn);
exit (1);
}
else
printf("Opening %s for reading is OK.\n", filenameIn);
if((fileptrOut = fopen(filenameOut, "w")) == NULL)
{
printf("Error opening %s for writing.\n", filenameOut);
exit (1);
}
else
printf("Opening %s for writing is OK.\n", filenameOut);
/* fscanf */
printf("\nCalculate the total...\n");
while(EOF != fscanf(fileptrIn, "%i", &value))
{
total += value;
++count;
}/* end of while loop */
/* write the average value to the file. */
/* fprintf */
printf("Calculate the average...\n\n");
fprintf(fileptrOut, "Average of %i numbers = %f \n", count, total/(double)count);
printf("Average of %i numbers = %f \n\n", count, total/(double)count);
printf("Check also your %s file content\n", filenameOut);
if(fclose(fileptrIn) == 0)
printf("%s closed successfully\n", filenameIn);
if(fclose(fileptrOut) == 0)
printf("%s closed successfully\n", filenameOut);
return 0;
}