Sams Teach Yourself C in 24 Hours (61 page)

BOOK: Sams Teach Yourself C in 24 Hours
10.21Mb size Format: txt, pdf, ePub

,

the format specifiers. If successful, the fscanf() function returns the number of data items read. Otherwise, the function returns EOF.

28 067231861x CH22 4.10.2000 11:04 AM Page 382

382

Hour 22

The syntax for the fprintf() function is

AX

#include

int fprintf(FILE *stream, const char *format, ...);

YNTS
Here stream is the file pointer associated with an opened file. format, whose usage is the

,

same as in the printf() function, is a char 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.

To know more about the fprintf() and fscanf() functions, you can review the explanations on the printf() and scanf() functions in Hour 5, “Handling Standard Input and Output,” and Hour 13, “Manipulating Strings.”

The program in Listing 22.3 demonstrates how to use the fscanf() and fprintf() functions to read and write differently typed data items.

TYPE

LISTING 22.3

Using the fscanf() and fprintf() Functions

1: /* 22L03.c: Using the fscanf() and fprintf() functions */

2: #include

3:

4: enum {SUCCESS, FAIL,

5: MAX_NUM = 3,

6: STR_LEN = 23};

7:

8: void DataWrite(FILE *fout);

9: void DataRead(FILE *fin);

10: int ErrorMsg(char *str);

11:

12: main(void)

13: {

14: FILE *fptr;

15: char filename[]= “strnum.mix”;

16: int reval = SUCCESS;

17:

18: if ((fptr = fopen(filename, “w+”)) == NULL){

19: reval = ErrorMsg(filename);

20: } else {

21: DataWrite(fptr);

22: rewind(fptr);

23: DataRead(fptr);

24: fclose(fptr);

25: }

26:

27: return reval;

28: }

29: /* function definition */

30: void DataWrite(FILE *fout)

28 067231861x CH22 4.10.2000 11:04 AM Page 383

Using Special File Functions

383

31: {

32: int i;

33: char cities[MAX_NUM][STR_LEN] = {

22

34: “St.Louis->Houston:”,

35: “Houston->Dallas:”,

36: “Dallas->Philadelphia:”};

37: int miles[MAX_NUM] = {

38: 845,

39: 243,

40: 1459};

41:

42: printf(“The data written:\n”);

43: for (i=0; i

44: printf(“%-23s %d miles\n”, cities[i], miles[i]);

45: fprintf(fout, “%s %d”, cities[i], miles[i]);

46: }

47: }

48: /* function definition */

49: void DataRead(FILE *fin)

50: {

51: int i;

52: int miles;

53: char cities[STR_LEN];

54:

55: printf(“\nThe data read:\n”);

56: for (i=0; i

57: fscanf(fin, “%s%d”, cities, &miles);

58: printf(“%-23s %d miles\n”, cities, miles);

59: }

60: }

61: /* function definition */

62: int ErrorMsg(char *str)

63: {

64: printf(“Cannot open %s.\n”, str);

65: return FAIL;

66: }

The following output is shown on the screen after the executable 22L03.exe is created and run on my computer:

The data written:

OUTPUT
St.Louis->Houston: 845 miles

Houston->Dallas: 243 miles

Dallas->Philadelphia: 1459 miles

The data read:

St.Louis->Houston: 845 miles

Houston->Dallas: 243 miles

Dallas->Philadelphia: 1459 miles

28 067231861x CH22 4.10.2000 11:04 AM Page 384

384

Hour 22

The purpose of the program in Listing 22.3 is to write data items of different
ANALYSIS
types into a file with the help of the fprintf() function and read back the data items in the same format by calling the fscanf() function. The two functions declared in lines 8 and 9, DataWrite() and DataRead(), actually perform the writing and reading.

The statement of the main() function in line 18 tries to create and open a text file called strnum.mix for both reading and writing by specifying the second argument to the fopen() function as “w+”. If fopen() does not return a null pointer, the DataWrite() function is called in line 21 to write strings and int data items into the strnum.mix file.

Note that the fprintf() function is invoked inside the DataWrite() function in line 45

to write the formatted data into the text file.

From the definition of the DataWrite() function in lines 30–47, you can see that there are two arrays, cities and miles. The cities array contains three strings that indicate three pairs of cities, and the miles array has three int values representing the corresponding distances between the cities shown in the cities array. For instance, 845 in the miles array is the distance (in miles) between the two cities expressed by the string St.Louis->Houston: in the cities array.

In line 22, the rewind() function is called to rewind the file position indicator and reset it to the beginning of the strnum.mix file. Then the DataRead() function in line 23 reads back what has been saved in strnum.mix with the help of the fscanf() function. The definition of the DataRead() function is shown in lines 49–60.

From this example, you see that it is convenient to use the fprintf() and fscanf() functions together to perform formatted disk file I/O operations.

Redirecting the Standard Streams with
freopen()

In Hour 5 you learned how to read from or write to standard I/O. Also, you were told that the C functions, such as getc(), gets(), putc, and printf(), direct their I/O operations automatically to either stdin or stdout.

In this section you’re going to learn how to redirect the standard streams, such as stdin and stdout, to disk files. A new C function you’re going to use is called freopen(), which can associate a standard stream with a disk file.

The syntax for the freopen() function is

AX

#include

FILE *freopen(const char *filename, const char *mode, FILE *stream);

YNTS
Here filename is a char pointer referencing the name of a file that you want to associate

,

with the standard stream represented by stream. mode is another char pointer pointing to 28 067231861x CH22 4.10.2000 11:04 AM Page 385

Using Special File Functions

385

a string that defines the way to open a file. The values that mode can have in freopen() are the same as the mode values in the fopen() function. (The definitions of all mode

,

22

values are given in Hour 21.)

The freopen() function returns a null pointer if an error occurs. Otherwise, the function returns the standard stream that has been associated with a disk file identified by filename.

Listing 22.4 demonstrates an example of redirecting the standard output, stdout, with the help of the freopen() function.

TYPE

LISTING 22.4

Redirecting the Standard Stream stdout

1: /* 22L04.c: Redirecting a standard stream */

2: #include

3:

4: enum {SUCCESS, FAIL,

5: STR_NUM = 4};

6:

7: void StrPrint(char **str);

8: int ErrorMsg(char *str);

9:

10: main(void)

11: {

12: char *str[STR_NUM] = {

13: “Be bent, and you will remain straight.”,

14: “Be vacant, and you will remain full.”,

15: “Be worn, and you will remain new.”,

16: “--- by Lao Tzu”};

17: char filename[]= “LaoTzu.txt”;

18: int reval = SUCCESS;

19:

20: StrPrint(str);

21: if (freopen(filename, “w”, stdout) == NULL){

22: reval = ErrorMsg(filename);

23: } else {

24: StrPrint(str);

25: fclose(stdout);

26: }

27: return reval;

28: }

29: /* function definition */

30: void StrPrint(char **str)

31: {

32: int i;

33:

continues

28 067231861x CH22 4.10.2000 11:04 AM Page 386

386

Hour 22

LISTING 22.4

continued

34: for (i=0; i

35: printf(“%s\n”, str[i]);

36: }

37: /* function definition */

38: int ErrorMsg(char *str)

39: {

40: printf(“Cannot open %s.\n”, str);

41: return FAIL;

42: }

After the executable 22L04.exe is created and run, the following output is printed out on the screen of my computer:

Be bent, and you will remain straight.

OUTPUT
Be vacant, and you will remain full.

Be worn, and you will remain new.

--- by Lao Tzu

The purpose of the program in Listing 22.4 is to save a paragraph of
Tao Te
ANALYSIS
Ching
written by a Chinese philosopher, Lao Tzu, into a text file, LaoTzu.txt. To do so, you call the printf() function instead of the fprintf() function or other disk I/O

functions after you redirect the default stream, stdout, of the printf() function to point to the text file.

The function that actually does the writing is called StrPrint(), which calls the C function printf() to send out formatted character strings to the output stream. (See the definition of the StrPrint() function in lines 30–36.)

Inside the main() function, you call the StrPrint() function in line 20 before you redirect stdout to the LaoTzu.txt file. It’s not surprising to see that the paragraph adopted from
Tao Te Ching
is printed on the screen because the printf() function automatically sends out the paragraph to stdout, which directs to the screen by default.

Then, in line 21, you redirect stdout to the LaoTzu.txt text file by calling the freopen() function. There the “w” is used as the mode that indicates to open the text file for writing. If freopen() is successful, you then call the StrPrint() function in line 24.

However, this time, the StrPrint() function writes the paragraph into the opened text file, LaoTzu.txt. The reason is that stdout is now associated with the text file, not the screen, so that strings sent out by the printf() call inside StrPrint() are directed to the text file.

After the execution of the program in Listing 22.4, you can open the LaoTzu.txt file in a text editor and see that the paragraph of
Tao Te Ching
has been saved in the file.

28 067231861x CH22 4.10.2000 11:04 AM Page 387

Using Special File Functions

387

As mentioned previously, the I/O streams are buffered by default.

Occasionally, you may want to turn off the buffering so that you can process
22

the input immediately. In C there are two functions, setbuf() and

setvbuf(), that can be used to turn off the buffering, although unbuffered I/O is beyond the scope of this book.

Also, there is a set of low-level I/O functions, such as open(), create(), close(), read(), write(), lseek(), and tell(), which are not supported by the ANSI C standard. You may still see them in some platform-dependent C

programs. To use them, you need to read your C compiler’s reference manual to make sure they’re available.

Summary

In this lesson you learned the following important concepts and functions regarding disk file input and output in C:

• The file position indicator can be reset by the fseek() function.

• The ftell() function can tell you the value of the current file position indicator.

• The rewind() function can set the file position indicator to the beginning of a file.

• After you specify the mode of the fopen() function for a binary file, you can use the fread() or fwrite() functions to perform I/O operations on binary data.

• Besides the fact that the fscanf() and fprintf() functions can do the same jobs as the scanf() and printf() functions, the fscanf() and fprintf() functions also allow the programmer to specify I/O streams.

• You can redirect the standard streams, such as stdin and stdout, to a disk file with the help of the freopen() function.

In the next lesson you’ll learn about the C preprocessor.

Q&A

Q Why is random access to a disk file necessary?

A
When you want to fetch a piece of information from a large file that contains a huge amount of data, random access to the file is a more efficient way than sequential access to the file. The functions that perform random access can put the file position indicator directly to the right place in the file, and then you can simply start to fetch the required information from there. In C, the fseek() and ftell() functions are two handy functions that help you to carry out the random access operation.

28 067231861x CH22 4.10.2000 11:04 AM Page 388

388

Hour 22

Q How do you specify the format of a new disk file you’re going to create by calling
fopen()
?

A
You have to add b into the mode argument to the fopen() function to specify that the file you’re going to create is a binary file. You can use “wb” to create a new file for writing and “wb+” to create a new file for writing and reading. If, however, the file to be created is a text file, no b is needed in the mode argument.

Q What is the difference between the
printf()
and
fprintf()
functions?

A
Basically, the printf() and fprintf() functions can do a similar job: send the formatted data items to the output streams. However, the printf() function automatically sends formatted data to stdout, whereas the fprintf() function can be assigned a file pointer that is associated with a specified output stream.

Other books

Mr Knightley’s Diary by Amanda Grange
On Looking: Essays by Lia Purpura
The Lifeguard by Deborah Blumenthal
Naked at Lunch by Mark Haskell Smith
Kill the Shogun by Dale Furutani
Softly Falling by Carla Kelly
Date Rape New York by Janet McGiffin