没有合适的资源?快使用搜索试试~ 我知道了~
C语言入门下
4星 · 超过85%的资源 需积分: 10 4 下载量 47 浏览量
2014-11-27
12:11:54
上传
评论 1
收藏 4.77MB PDF 举报
温馨提示
试读
238页
C语言入门下
资源推荐
资源详情
资源评论
374
CHAPTER 10
■ ESSENTIAL INPUT AND OUTPUT OPERATIONS
such as a printer, or a device that can have both input and output operations, such as a disk drive.
This is illustrated in Figure 10-1.
Figure 10-1. Standard and nonstandard streams
A disk drive can have multiple input and output streams because it can contain multiple files.
The correspondence is between a stream and a file, not between a stream and the device. A stream
can be associated with a specific file on the disk. The stream that you associate with a particular file
could be an input stream, so you could only read from the file; it could be an output stream, in which
case you could only write to the file; or the stream might allow input and output so reading and writing
the file would both be possible. Obviously, if the stream that is associated with a file is an input stream,
the file must have been written at some time so it contained some data. You could also associate a
stream with a file on a CD-ROM drive. Because this device is typically read-only, the stream would,
of necessity, be an input stream.
There are two further kinds of streams: character streams, which are also referred to as text
streams, and binary streams. The main difference between these is that data transferred to or from
character streams is treated as a sequence of characters and may be modified by the library routine
concerned, according to a format specification. Data that’s transferred to or from binary streams is
just a sequence of bytes that isn’t modified in any way. I discuss binary streams in Chapter 12 when
I cover reading and writing disk files.
Standard Streams
C has three predefined standard streams that are automatically available in any program, provided,
of course, that you’ve included the <stdio.h> header file, which contains their definitions, into your
program. These standard streams are stdin, stdout, and stderr. Two other streams that are available
Horton_735-4C10.fm Page 374 Wednesday, September 20, 2006 9:48 AM
CHAPTER 10 ■ ESSENTIAL INPUT AND OUTPUT OPERATIONS
375
with some systems are identified by the names stdprn and stdaux, but these are not part of the C
language standard so your compiler may not support them.
No initialization or preparation is necessary to use these streams. You just have to apply the
appropriate library function that sends data to them. They are each preassigned to a specific physical
device, as shown in Table 10-1.
In this chapter I concentrate on how you can use the standard input stream, stdin, the standard
output stream, stdout, and the printer stream, stdprn.
The stderr stream is simply the stream to which error messages from the C library are sent, and
you can direct your own error messages to stderr if you wish. The main difference between stdout
and stderr is that output to stdout is buffered in memory so the data that you write to it won’t necessarily
be transferred immediately to the device, whereas stderr is unbuffered so any data you write to it is
always transferred immediately to the device. With a buffered stream your program transfers data to
or from a buffer area in memory, and the actual data transfer to or from the physical device can occur
asynchronously. This makes the input and output operations much more efficient. The advantage of
using an unbuffered stream for error messages is that you can be sure that they will actually be displayed
but the output operations will be inefficient; a buffered stream is efficient but may not get flushed
when a program fails for some reason, so the output may never be seen. I won’t discuss this further,
other than to say stderr points to the display screen and can’t be redirected to another device. Output to
the stream stdaux is directed to the serial port and is outside the scope of this book for reasons of
space rather than complexity.
Both stdin and stdout can be reassigned to files, instead of the default of keyboard and screen,
by using operating system commands. This offers you a lot of flexibility. If you want to run your
program several times with the same data, during testing for example, you could prepare the data as
a text file and redirect stdin to the file. This enables you to rerun the program with the same data
without having to re-enter it each time. By redirecting the output from your program to a file, you
can easily retain it for future reference, and you could use a text editor to access it or search it.
Input from the Keyboard
There are two forms of input from the keyboard on stdin that you’ve already seen in previous chapters:
formatted input, which is provided primarily by the scanf() function and unformatted input, in
which you receive the raw character data from a function such as getchar(). There’s rather more to
both of these possibilities, so let’s look at them in detail.
Table 10-1. Standard Streams
Stream Device
stdin Keyboard
stdout Display screen
stderr Display screen
stdprn Printer
stdaux Serial port
Horton_735-4C10.fm Page 375 Wednesday, September 20, 2006 9:48 AM
376
CHAPTER 10
■ ESSENTIAL INPUT AND OUTPUT OPERATIONS
Formatted Keyboard Input
As you know, the function scanf() reads characters from the stream stdin and converts them to one
or more values according to the format specifiers in a format control string. The prototype of the
scanf() function is as follows:
int scanf(char *format, ... );
The format control string parameter is of type char *, a pointer to a character string as shown
here. However, this usually appears as an explicit argument in the function call, such as
scanf("%lf", &variable);
But there’s nothing to prevent you from writing this:
char str[] = "%lf";
scanf(str, &variable);
The scanf() function makes use of the facility of handling a variable number of arguments that
you learned about in Chapter 9. The format control string is basically a coded description of how
scanf() should convert the incoming character stream to the values required. Following the format
control string, you can have one or more optional arguments, each of which is an address in which
a corresponding converted input value is to be stored. As you’ve seen, this implies that each of these
arguments must be a pointer or a variable name prefixed by & to define the address of the variable
rather than its value.
The scanf() function reads from stdin until it comes to the end of the format control string, or
until an error condition stops the input process. This sort of error is the result of input that doesn’t
correspond to what is expected with the current format specifier, as you’ll see. Something that I
haven’t previously noted is that scanf() returns a value that is the count of the number of input
values read. This provides a way for you to detect when an error occurs by comparing the value
returned by scanf() with the number of input values you are expecting.
The wscanf() function provides exactly the same capabilities as scanf() except that the first
argument to the function, which is the format control string, must be a wide character string of type
wchar_t *.
Thus you could use wscanf() to read a floating-point value from the keyboard like this:
wscanf(L"%lf", &variable);
The first argument is a wide character string constant and in all other respects the function
works like scanf(). If you omit the L for the wide character string literal, you will get an error message
from the compiler because your argument does not match the type of the first parameter.
Of course, you could also write this:
wchar_t wstr[] = L"%lf";
wscanf(wstr, &variable);
Input Format Control Strings
The format control string that you use with scanf() or wscanf() isn’t precisely the same as that used
with printf(). For one thing, putting one or more whitespace characters—blank ' ', tab '\t', or
newline '\n'—in the format control string causes scanf() to read and ignore whitespace characters
up to the next nonwhitespace character in the input. A single whitespace character in the format
control string causes any number of consecutive whitespace characters to be ignored. You can
therefore include as many whitespace characters as you wish in the format string to make it more
readable. Note that whitespace characters are ignored by scanf() by default except when you are
reading data using %c, %[], or %n specifications (see Table 10-2).
Horton_735-4C10.fm Page 376 Wednesday, September 20, 2006 9:48 AM
CHAPTER 10 ■ ESSENTIAL INPUT AND OUTPUT OPERATIONS
377
Any nonwhitespace character other than % will cause scanf() to read but not store successive
occurrences of the character. If you want scanf() to ignore commas separating values in the input
for instance, just precede each format specifier by a comma. There are other differences too, as
you’ll see when I discuss formatted output in the section “Output to the Screen” a bit later in this
chapter.
The most general form of a format specifier is shown in Figure 10-2.
Figure 10-2. The general form of an output specifier
Let’s take a look at what the various parts of this general form mean:
•The % simply indicates the start of the format specifier. It must always be present.
•The next * is optional. If you include it, it indicates that the next input value is to be ignored.
This isn’t normally used with input from the keyboard. It does become useful, however, when
stdin has been reassigned to a file and you don’t want to process all the values that appear
within the file in your program.
• The field width is optional. It’s an integer specifying the number of characters that scanf()
should assume makes up the current value being input. This allows you to input a sequence
of values without spaces between them. This is also often quite useful when reading files.
• The next character is also optional, and it can be h, L, l (the lowercase letter L), or ll (two
lowercase Ls). If it’s h, it can only be included with an integer conversion specifier (d, I, o, u, or x)
and indicates that the input is to be converted as short. If it’s l, it indicates long when preceding
an int conversion specifier, and double when preceding a float conversion specifier. Prefixing
the c specification with l specifies a wide character conversion so the input is read as wchar_t. The
prefix L applied to e, E, f, g, or G specifies the value is of type long double. The ll prefix applies to
integer conversions and specifies that the input is to be stored as type long long.
• The conversion character specifies the type of conversion to be carried out on the input
stream and therefore must be included. The possible characters and their meanings are
shown in Table 10-2.
Horton_735-4C10.fm Page 377 Wednesday, September 20, 2006 9:48 AM
378
CHAPTER 10
■ ESSENTIAL INPUT AND OUTPUT OPERATIONS
You can also read a string that consists of specific characters by placing all the possible charac-
ters between square brackets in the specification. For example, the specification %[0123456789.-]
will read a numerical value as a string, so if the input is –1.25 it will be read as "-1.25". To read a string
consisting of the lowercase letters a to z, you could use the specification %[abcdefghijklmnopqrstuvwxyz].
This will read any sequence of the characters that appear between the square brackets as a string,
and the first character in the input that isn’t in the set between the square brackets marks the end of
the input. Although it isn’t required by the standard, many C library implementations support the
form %[a-z] to read a string consisting of any lowercase letters.
A specification using square brackets is also very useful for reading strings that are delimited by
characters other than whitespace. In this case, you can specify the characters that are not in the string by
using the ^ character as the first character in the set. Thus, the specification %[^,] will include every-
thing in the string except a comma, so this form will enable you to read a series of strings separated
by commas.
Table 10-3 shows a few examples of applying the various options.
Table 10-2. Conversion Characters and Their Meanings
Conversion
Character
Meaning
d Convert input to int.
i Convert input to int. If preceded by 0, then assume octal digits input. If
preceded by 0x or 0X, then assume hexadecimal digits input.
o Convert input to int and assume all digits are octal.
u Convert input to unsigned int.
x Convert to int and assume all digits are hexadecimal.
c Read the next character as char (including whitespace). If you want to
ignore whitespace when reading a single character, just precede the
format specification by a whitespace character.
s Input a string of successive nonwhitespace characters, starting with the
next nonwhitespace character.
e, f, or g Convert input to type float. A decimal point and an exponent in the
input are optional.
n No input is read but the number characters that have been read from the
input source up to this point are stored in the corresponding argument,
which should be of type int*.
Table 10-3. Examples of Options in Conversion Specifications
Specification Description
%lf Read the next value as type double
%*d Read the next integer value but don’t store it
%lc Read the next character as type wchar_t
%\nc Read the next character as type char ignoring whitespace characters
%10lld Reads the next ten characters as an integer value of type long long
Horton_735-4C10.fm Page 378 Wednesday, September 20, 2006 9:48 AM
剩余237页未读,继续阅读
资源评论
- Hugo智鹏2015-08-10不错,很基础的东西,很适合初学者
WZSDXS
- 粉丝: 10
- 资源: 21
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功