Now that we know about pointers and memory, we can start talking about more advanced kinds of I/O. First, I'll talk about file pointers, then moving onto the rest of theprintf()
family, and then dealing with more kinds of input.
File I/O
C defines a special kind of pointer in the
stdio.h
library (the same library where almost all of the I/O functions are defined, including all the functions mentioned in this tutorial). Called a file pointer, it allows you to read and write data from files. A file pointer is declared as the typeFILE *
(note the capitals). Once you have declared pointer, you must tell it what file it should point to. This is done via thefopen(char *filename, char *mode)
function. It takes two arguments: the actual name of the file, and the mode. The mode can be one of three single-letter strings (not just characters). Use"r"
if you want to open the file for reading only,"w"
for writing, and"a"
for appending (i.e., adding text to the end of the file and not overwriting what is already there). When you're finished using a file, it's a good idea to close it with thefclose(FILE *fptr)
function. While this is not stricly necessary, it can avoid strange bugs, and is good style. As you read data from a file, the file pointer moves along through the file and keeps track of its current position. If you should need to reposition your place in the file, you can use therewind(FILE *fptr)
function to move the pointer back to the beginning of the file.In addition to any files you open yourself, there are three preopened file pointers declared in every program. These are
stdin
, the standard input,stdout
, the standard output, andstderr
, the standard error reporting output. In general, usingstdin
andstdout
will confine your operations to the terminal and the command line (on a UNIX system, that is).Files are terminated by a special constant called
EOF
(note the capitals). This is the reason that the character-oriented input functions return integers rather than characters.EOF
is a value outside the ASCII code, and so consequently could not be used in a character variable.We'll see how to use a file you've opened in the next few sections.
The
printf()
FamilyWe've already seen the standard kind of
printf()
. But there are two other functions that are very similary which are also useful:sprintf()
andfprintf()
.sprintf()
takes the same kind of arguments as the standard form except for an additional string argument (that goes first in the argument list).sprintf()
will then put its output into this string instead of printing it tostdout
.fprintf()
also takes an additional first argument, but this time it should be a file pointer opened with either the"r"
or"w"
mode.fprintf()
prints output to files. And, just for comparison's sake, the statementprintf("%s", msg)
is identical tofprintf(stdout, "%s", msg)
. Everything else about theprintf()
family remains the same with these new functions.
The
scanf()
FamilyYou're probably wondering by now how to control input. One way to read in information is to use one of the
scanf()
functions. These are in many ways analagous to theprintf()
family we've already seen. In addition to the standardscanf()
function, there are the two variantsfscanf()
and sscanf(). The arguments for these functions are quite similar to theprintf()
arguments. Except for the normalscanf()
, wherestdin
is the default, the first argument should be either a string or a file pointer, depending on the function you're using. The second argument is the string to scan in. The format of this string is very important, sincescanf()
will look for exactly that sequence of characters. Also included in this string can be format codes just like those you use inprintf()
. There are a few new wrinkles, though. First of all, the variables specified in the list that comes after the control string must be pointers. So, if you want to scan a value into a normal variable, you should put the address-of operator (&
) in front of it in the list. There are also a few additional format codes you can use. Use%[]
to specify a set of characters that will be accepted. For example,
char ch; scanf("%[abc]", &ch);will read a character into
ch
if it is either a, b, or c. Remember that case is important. If instead you want to read in everything but some character, put a caret in front of the list. For example, to read in a line of input fromstdin
, you can use
char *str, termch; scanf("%[^\n]%c", str, &termch);The
termch
variable is there to remove the newline character fromstdin
, which would otherwise remain since you read in everything but it. Also note that I didn't put an ampersand in front ofstr
since it was already a pointer.In general, the
scanf()
family is difficult to deal with. I would recommend avoiding it when possible.
Various Other I/O Functions
You've already seen one other input function; recall
getchar()
. This and its more general equivalentgetc(FILE *fptr)
control character-oriented input. Each returns an integer rather than a character for reasons noted above. A common loop construction for reading all the characters from a file is
int ch; FILE *infile; while ((ch = getc(infile)) != EOF) { /* process the characters */ }Since the code within the innermost parentheses gets executed first,
getc()
will assign the next character to the variablech
before checking its value againstEOF
.
getc()
andgetchar()
have analogous output functions inputc()
andputchar()
. In addition, the functionungetc()
can be used to push a single character back into the file (essentially backing the file pointer up one character).For line-oriented input, you can use the functions
gets()
,fgets()
, andputs()
. The action of these functions is fairly straightforward, except that their arguments should be strings rather than characters.
Back to Strings | On to Binary Operations | |
Back to the Outline |