Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Objectives:
The overall effect is to provide sequential reads or writes unless the stream was opened in
append mode, or the file position indicator is explicitly moved.
There are two types of file, text files and binary files, which when once opened for I/O within a
program, are processed as text streams and binary streams. The stdio package restricts the
processing of the contents in a file directly as it process data in form of streams.
The stdio package process three kinds of data streams:
• stdin - standard input
• stdout - standard output
• stderr - standard error
For instance -
FILE *stdin;
FILE *stdout;
FILE *stderr;
#include <stdio.h>
By default, standard input (stdin) is for the input supplied by user from the keyboard, while
standard output and standard error are for regular and error output respectively to be printed
on the screen. These pointers can be passed as arguments to functions like getchar and
putchar that make dynamic use of stdin and stdout. These pointers are predefined, and
Thinking Questions
Formatted I/O uses a number of associated functions to resolve the format of the I/O from a
format string. In case of output, the format string includes plain text, which is copied to the
output stream, and embedded format specifications which require some special processing
and conversion of the arguments supplied.
Each format specification starts with a % character, and is followed by the rest of the
specification.
The output function printf converts, formats, and prints its arguments on the output screen as
per the controlled specifications.
Syntax:
int printf(char *format, arg1, arg2, ...);
The format string includes two types of elements: ordinary characters, which are copied to the
output stream, and conversion specifications, each of which initiates processing and printing
of the next consecutive argument to printf. Each conversion specification should begin with a
‘%’ and terminate with a conversion character. Between the % and the conversion character
there may be, some required fields which include:
%<flags><field width><precision><length>conversion char
The format specification takes the form provided above for the functions performing
conversions, along with the optional parts that are enclosed in brackets for which the
explanation is provided below:
Flags:
• (-) justifies the adjustment of the converted argument towards left
• (+) justifies the adjustment of the converted argument towards right (by default)
• A signed conversion must start with a plus or minus sign
• Space replaces the first character of the signed conversion with a blank-space, if it is not
a sign. Overridden by (+) if present. .
Field-width
• A decimal integer is used to supply the field width required to hold the output that can be
changed as per the need.
• When supplied with an asterisk, the consequent argument is converted into an integer
and is then taken as a value for the field width;
• When the value is negative it is taken as a (–) flag followed by a positive field width value.
• When the output would acquire less space than the specified value, the field width is
padded with spaces if the supplied value starts with spaces and zeros if it starts with a
zero, to fit the allocated size.
• The padding is performed on the left unless provided with the left-adjustment flag.
Precision
It starts with a period (.). It indicates the number of characters to be printed from a string for s
conversion.
Length
Here ‘h’ indicates that the integer is required to be printed as short. Whereas ‘l’ indicates that
the integer is required to be printed as long and is only applied to the floating-point integers.
Conversion
The table below shows the effect of conversion on several specifiers:
Default
Specifier Effect
precision
d signed decimal 1
i signed decimal 1
u unsigned decimal 1
o unsigned octal 1
% A% —
Table: Conversions
The functions that use these formats are described in the next Table.
All the above conversions require <stdio.h> as shown below:
#include <stdio.h>
int fprintf(FILE *stream, const char *format, ...);
int printf(const char *format, ...);
int sprintf(char *s, const char *format, ...);
Similar to fprintf except that the output is not printed to a file, but printed into
sprintf
the array of characters pointed to by s.
All the above functions pass number of characters as output or a (-) value on error. The
trailing null is ignored by sprintf. Implementations should allow a minimum of 509 characters to
be returned by any single conversion.
All of the functions we have discussed until now were able to accept only a fixed number of
arguments, and we have always been cautious while calling functions by supplying them the
exact number of arguments. We have also been using explicit function prototype declarations
to let the compiler verify that the functions we call include exact number of arguments. But we
don’t apply such hard and fast rules in case of printf, as sometimes we call it with single
argument and sometimes we pass several arguments to it.
Now the question is, why is this ignored by the compiler? How printf is able to access the
additional arguments passed to it, without being aware of the quantity and types of those
arguments?
Here we'll discuss the variable-length argument list, which is often employed under the
shorthand term "varargs" and which permits functions such as printf to be executed.
Declaring "varargs" Functions
According to the ANSI/ISO C Standard whenever a varargs function is called, all the functions
that takes a variable number of arguments should be defined explicitly, and also the function
prototype should be available. The reason for the prototypes to be strictly included is that the
varargs functions may use special calling sequences for which the compiler might have to
generate some special code.
A variable-length argument list is identified by an ellipsis in the prototype. For instance, the
prototype for printf in <stdio.h>, looks like:
extern int printf(const char *, ...);
The three dots ... printed above are the ellipsis notation. This syntax indicates the presence of
a variable-length argument list. This prototype indicates that the first argument accepted by
printf's is of type const char *, and that it takes a variable number of additional arguments.
Declaring a "varargs" Function
Syntax: showing the outline of the function
#include <stdio.h>
#include<conio.h>
In the example above, the myprintf function takes the first argument of type const char *. In the
statement for(p = fmt; *p != '\0'; p++), a loop is created where each argument is taken one by
one until the pointer reaches null.
A number of functions exist for the purpose of accepting input from the user, and are
equivalent to the printf community. The most proper difference between the two function
groups is that the scanf group requires pointers to be passed to their arguments, so that the
values can be accepted and allocated to the appropriate targets. A very common error occurs
while implementing such function, which even the compiler cannot detect, is when we forget to
pass a pointer. This error is prevented by the variable argument list.
Interpretation of a stream of input data is controlled by using the format string, which consists
of values to be allocated to the objects pointed to by the remaining arguments to scanf. The
format string may include:
White space:
This enables the input stream to be processed up to the next non-white-space character.
Ordinary character:
It can be anything excluding white-space or % characters. The next character in the input
stream must come under this group of character.
An input field is a series of non-spaced characters starting right from the first non-spaced
character in the input, excluding the conversion specifiers c, n and [. It ends at the first odd
character or when the input field width is achieved.
The result is supplied to the place pointed by the corresponding argument, unless the
conversion is concealed using the *, as discussed before. The conversion specifiers which
could be used include:
dioux
Convert a signed integer, a signed integer in a form supported by strtol, an octal integer, an
unsigned integer and a hexadecimal integer respectively.
efg
Convert a float (not a double).
s
Takes string as input, and attaches null at the end. The string gets terminated when a white-
space is received as input that is not taken as a part of the string.
c
Reads a single character; white space is important here. To read the first non-white spaced
character, use %1s. A field width specifies that an array of characters is to be processed.
p
Reads a (void *) pointer printed out earlier using the %p of one of the printfs.
%
A % is necessary in the input, no allocation is made.
n
Returns the number of characters read by this call to this point in form of integers.
The Table below shows the size of specifiers:
l ef double
L ef long double
File Access
This program opens a binary file and then writes a char * (string) into it. The FILE * variable is
returned from the fopen() call. If this fails it returns 0.
The fopen() command tries to access the mentioned file. Here it is test.txt in the same folder
as the application. If you can remember, when the file includes a path then all the back spaces
should be doubled up. i.e., "c:\file\test.txt" is not correct; it should be "c:\\file\\test.txt".
The filemode "wb" indicates that we are writing to a binary file. If the file doesn't exist it will be
created, and if it does then whatever it includes would be automatically deleted. If the call to
fopen fails due to any reason, the fopen returns the value 0.
fwrite(mytext,sizeof(char),strlen(mytext), ft);
The fwrite() function returns the specified text. The second and third parameters represent the
size of the characters and the length of the string, respectively. Both are declared as size_t
which is unsigned integer. The resultant of this call write count items of the specified size.
Note
With binary files, even if you are writing a string (char *) it does not adds any carriage
return or line feed characters. If it is required, then it must be explicitly included in the
string.
The processing of errors in cat is not perfect. The problem is that if any of the files encounters
some problem while accessing, an analytical report is received at the end of the concatenated
The standard library supports an input and output routine fgets, which is eqivalent to the
getline function:
Here, fgets takes the next line including a new line as input from file fp into the character array
line. It would continue reading the characters upto maxline-1. The resultant line ends with '\0'.
Generally fgets outputs line but when the file ends or produces error, it returns NULL.
For output, the function fputs prints a string to a file that does not need to include a newline
For instance:
int fputs(char *line, FILE *fp)
#include<stdio.h>
#include<conio.h>
void main()
{
char *fgets(char *h, int n, FILE *ccp)
{
register int i;
register char *rs;
rs = h;
while (--n > 0 && (i = getc(ccp)) != EOF)
if ((*rs++ = i) == '\n')
break;
*rs = '\0';
return (i == EOF && rs == h) ? NULL: h;
}
while (i = *h++)
putc(i, ccp);
return ferror(ccp) ? EOF: 0;
}
}
The standard library produces different outputs for ferror and fputs
for no exact reason.
The example given above shows the use of fgets in receiving input from users and fputs in
printing output on the screen. The fgets function takes input until EOF (end of file is
encountered). In explanation for the later program a function getline is implemented using
fgets.
If input is equal to null it returns 0, else returns the next line.
Thinking Questions
Solved Examples
Ex 1: Reading in a character entered by the user.
main()
{
int ch;
printf("Please type in one character:\n");
Explanation:
In line 4, an integer variable, ch, is defined; later in line 6 it is allocated the return value from the
getc() function.
Line 5 requests the user to enter one character.
The printf() function in line 7 uses the default standard output stdout to print output on the
screen.
In line 8, the standard input stdin is passed to the getc() function. When user inputs a character,
the getc() function returns the integer value of the character.
#include <stdio.h>
main()
{
int n1, n2;
n1 = 66;
n2 = 66666;
printf("%d\n", n1);
printf("%d\n", n2);
printf("%5d\n", n1);
printf("%05d\n", n1);
printf("%2d\n", n2);
return 0;
}
Explanation:
In the program above, two integer variables n1 and n2 are declared and assigned 6 and 66666
respectively.
Without using any minimum field width specifiers, the printf () function prints out the two
integers.
The statement takes two character spaces in the statement printf("%2d\n", n2), but you still see
the full-size output of 66666 that means that when the minimum field width is shorter than the
width of the output, the latter is taken.
while the output of the statement printf("%05d\n", n1) takes five character spaces, with three
blank spaces plus two character spaces of 66
In line 12, a minimum field width, 5, is specified by %5d. The output from line 12 therefore
takes five character spaces.
Practical(s)