Unix, C, and C++
Function Reference
C Input and Output (stdio)
Although stdio.h has supposedly been replaced by iostream.h for C++ programs,
it is still much easier to use and control, and remains available. For the
vast majority of programming tasks stdio.h is the superior tool.
To use stdio, simply add the directive "#include <stdio.h>" at the beginning
of your program file.
Although stdio is compatible with other input/output libraries
(you do not have to remove other #includes), they should not be used
together. stdio.h, iostream, iostream.h, and library.h may use different buffering schemes, and using
more than one of them concurrently could result in inputs and outputs being processed
out of order, or possibly not at all.
(*) NOTE concerning ASCII codes: In the following descriptions, wherever
it is stated that ASCII codes are used, this is generally true, but not absolutely always. The
C and C++ standards permit alternate character encodings, and although these are very rare,
it is at least possible that you may come across one. On this computer, we definitely use ASCII.
Most useful stdio function prototypes
int putchar(int c);
int getchar(void);
int puts(char s[]);
char *gets(char s[]);
int printf(char format[], ...);
int scanf(char format[], ...);
int sprintf(char string[], char format[], ...);
int sscanf(char string[], char format[], ...);
int fprintf(FILE *fileref, char format[], ...);
int fscanf(FILE *fileref, char format[], ...);
FILE *fopen(char filename[], char access[]);
int fclose(FILE *fileref);
int fputc(int c, FILE *fileref);
int fgetc(FILE *fileref);
int ungetc(int c, FILE *fileref);
char *fgets(char str[], int length, FILE *fileref);
int fputs(char str[], FILE *fileref);
int putchar(int c)
include: <stdio.h>
Prints a single character on the standard output stream (stdout).
c = the ASCII code of the character to be printed.
returns <0 for error, otherwise the parameter c.
normally treated as returning void, as the real return result is not very useful.
All special control characters have their normal effects: putchar('\n') starts a new
line of output, putchar('\a') rings the keyboard bell (if there is one), etc. You
can not use putchar(EOF) to "write an end-of-file mark".
int getchar(void)
include: <stdio.h>
Reads a single character from the standard input stream (stdin).
returns the ASCII code(*) of the next available character.
If no characters are currently available, it waits until one is typed. (In fact, it
waits until a whole line (with ENTER at the end) is typed, otherwise the backspace
key would be useless). Returns the value EOF (which is -1) if end-of-file is reached.
Note is you store the result of this function in a char variable instead of an
int you may have trouble detecting end-of-file. To type end-of-file on the keyboard,
under unix (most shells) type control-D. Under DOS or windows or the Bourne shell for
unix, type control-Z.
Control characters are interpreted correctly: when newline/ENTER is typed, the return
value is '\n', which is 10. Backspace, Delete, and Control-C, etc, can not be read by
getchar, as they are processed by the operating system before the line of input is made
available to user programs.
int puts(char s[]);
include: <stdio.h>
Prints the entire string passed to it, followed by a newline character.
s = the string to be printed.
Note The string s should not have a '\n' at the end unless you want two to be printed.
char *gets(char s[]);
include: <stdio.h>
NOTE gets is an insecure function, its careless use can lead to errors. If you
want to use gets, consider using fgets instead, supplying stdin as
the file reference parameter.
The gets function waits until a line of input is available (unless one is already
available), and consumes the whole line including the ENTER/newline at the end.
The characters on the line are stored in the string parameter, except for the
ENTER/newline, which is discarded.
returns NULL on end-of-file, otherwise the parameter s.
The parameter given to gets must be an already allocated array of characters, not an
uninitialised char * pointer; gets will never allocate memory.
{ char a[100]; gets(line); // This is correct
{ char a[100]; char *s; s=a; gets(s); // This is correct
{ char *s; s=new char[100]; gets(s); // This is correct
{ char *s; gets(s); // This is WRONG
The array given to gets must be big enough to hold any line that could conceivably be
input. C++ and C are incapable of telling how long an array is. If it is not long enough
for the data that is read, other data (and perhaps program code) will be overwritten.
Thus gets is not a safe function for use in critical applications.
Notice that gets consumes the newline character typed at the end of the line, but does
not put it in the string: it is permanently discarded. The puts function always prints
an extra newline character after its string is printed. This makes puts and gets mutually
compatible, but frequently annoying.
int printf(char format[], ...)
include: <stdio.h>
returns the number of parameters (not including fmt) successfully printed.
errors can produce zero or negative results.
The printf function allows numeric and character data to be printed in (almost)
any desired format. printf must be given at least one parameter when it is called,
but there is no maximum. The first parameter is the format string. Printf works by
simply printing its format string character-by-character, except that whenever it
finds a '%' character, the next remaining parameter is printed in the format described
by the character(s) immediately following the '%'. The most commonly used formats are
%d which causes an integer parameter to be printed in the usual decimal style, and %s
which prints a C-style string (i.e. an array of characters). For example:
| printf("Hello, you."); prints | Hello, you.
| printf("6 times 9 is %d", 6*9); prints | 6 times 9 is 54
| printf("%d times %d is %d", a, b, a*b); prints | something like 12 times 102 is 1224
| printf("The %dth of %s", 22, "March"); prints | The 22th of March
| printf(s); prints | the string s, unless it contains a %
| | printf("one\ntwo\nthree"); prints |
| | | | | | | | | | |
Because printf gives complete control over the placement of newline characters, it is
generally preferred over puts for the output of strings. Beware: printf(s) is normally
thought of as equivalent to puts(s) (apart from the placement of the newline), but if
the string ever contains a % symbol, it will fail. printf("%s", s) should be used instead.
Printf Formats
%d: Integers in Decimal
The actual parameter corresponding to any variety of %d must be an int or char (signed and short are also accepted).
Between the % and the d, other characters may be added to control the
printing more exactly.
- Normally, numbers are printed using the smallest number of characters possible, no leading zeros or spaces.
putting a number between % and d (the number must not be written with a leading zero) specifies a minimum number
of characters to be used. Numbers that are not naturally big enough are padded out with leading spaces.
For example, with the format %4d numbers between 0 and 9 are preceeded by three spaces; numbers between
10 and 99, or between -1 and -9 are preceeded by two spaces (the minus sign is counted in the size); numbers
between 100 and 999 or between -10 and -99 are preceeded by a single space; all other numbers are printed as normal.
- An alternative form of padding is to use leading zeros instead of spaces. If the number between the % and the d
is itself written with a leading zero, the number printed will be padded with leading zeros instead of spaces.
For example, with the format %05d, numbers between 10 and 99 are printed with 3 leading zeros.
- If a - (a minus sign) appears between the % and the number, making it appear to be negative, padding is
added to the right of the output instead of to the left. This provides for left justification of numbers.
- If a + (a plus sign) appears between the % and the number, the sign of the number will always be printed.
Normally, negatives are printed with a - sign, but positives are printed without any sign.
- If a space appears between the % and the number (instead of a +), a space will be left in front of all positive
values printed.
- If a dot (or decimal point) appears, followed by a number, that provides the minimum number of digits to be printed.
The normal number described above specifies the minimum for the total number of characters to be used. %3d
will print 3 digits for positive numbers, but only two for negatives. %.3d prints at least 3 digits
regardless of the sign.
%u: Unsigned Integers in Decimal
The actual parameter corresponding to any variety of %u must be an int or char (unsigned, signed, and short are also accepted).
All numbers are interpreted as being unsigned. Between the % and the u, other characters may be added to control the
printing more exactly. These other characters are exactly as described above for the %d format.
%x and %X: Integers in Hexadecimal
The actual parameter corresponding to any variety of %x must be an int or char (unsigned, signed, and short are also accepted).
All numbers are interpreted as being unsigned. Between the % and the x, other characters may be added to control the
printing more exactly. These other characters are exactly as described above for the %d format.
%x prints a number in base 16, using the characters 0123456789abcdef for digits.
%X prints a number in base 16, using the characters 0123456789ABCDEF for digits.
A # character after the % forces the sequence 0x or 0X to appear in front of all non-zero values printed.
%o: Integers in Octal
The actual parameter corresponding to any variety of %o must be an int or char (unsigned, signed, and short are also accepted).
All numbers are interpreted as being unsigned. Between the % and the o, other characters may be added to control the
printing more exactly. These other characters are exactly as described above for the %d format.
%o prints a number in base 8, using the characters 01234567 for digits.
A # character after the % forces a leading zero to be printed.
%f: Floating Point Numbers
The actual parameter corresponding to any variety of %f must be a double or a float (NOT int: no automatic conversions are performed,
failure will ensue). BEWARE: some systems get this wrong, and only accept a float. To be safe, use %f only for floats,
and %lf only for doubles. (that is a lower case L, not the digit 1). The L appears immediately before the F if any extra
formatting characters are added (e.g. %15.9lf).
Between the % and the f, other characters may be added to control the
printing more exactly.
- Normally, numbers are printed in a default format which is not very pleasing to the eye.
- The most commonly used format specification follows the form %.6f (the 6 could be replaced by any number).
This specifies that the number should be printed with exactly 6 digits after the decimal point.
- The format %.0f printd a floating point value rounded to the nearest integer; no decimal point is printed.
- Another commonly used format specification follows the form %14.6f (the 14 and 6 could be replaced by any numbers).
This specifies that the number should be printed with exactly 6 digits after the decimal point, and should occupy
at least 14 characters in total; padding consists of spaces added to the left.
- Other format modifying characters as decribed above for the %d format are also allowed.
%e and %E: Floating Point Numbers Almost in Scientific Notation
The actual parameter corresponding to any variety of %e must be a double or a float (NOT int: no automatic conversions are performed,
failure will ensue). BEWARE: some systems get this wrong, and only accept a float. To be safe, use %e only for floats,
and %le only for doubles. (that is a lower case L, not the digit 1). The L appears immediately before the E if any extra
formatting characters are added (e.g. %15.9le).
Between the % and the e, other characters may be added to control the
printing more exactly.
%e and %E work in exactly the same way as %f, except that the number is always printed in scientific notation
using the letter e or E to stand for "times ten to the power of". The e or E is always followed
by a sign (+ or -) and some digits. The extra formatting characters described above for %f apply exactly to
%e and %E.
%g and %G: Floating Point Numbers in Scientific Notation
The actual parameter corresponding to any variety of %g must be a double or a float (NOT int: no automatic conversions are performed,
failure will ensue). BEWARE: some systems get this wrong, and only accept a float. To be safe, use %g only for floats,
and %lg only for doubles. (that is a lower case L, not the digit 1). The L appears immediately before the G if any extra
formatting characters are added (e.g. %15.9lg).
Between the % and the g, other characters may be added to control the
printing more exactly.
%g and %G work in exactly the same way as %e and %E, except that the number after the decimal point specifies
the number of significant digits to be printed, instead of the number of digits to be printed after the decimal point.
%c: Single Characters
The actual parameter corresponding to any variety of %c must be an int or char (unsigned, signed, and short are also accepted).
A single character (whose ascii code is equal to the parameter being printed) is printed.
printf("%c", x); is equivalent to putchar(x);
%s: Strings
The actual parameter corresponding to any variety of %s must be (a pointer to) an array of char. The array must be
properly terminated with a zero. All characters from the beginning of the array, up to but not including the zero marker,
are printed as with the %c format.
Between the % and the e, other characters may be added to control the
printing more exactly.
- A number, as used to specify the minimum size with %d, also specifies the minimum size for a string. If the string
is shorter than this minimum size, it is padded to the left with spaces. printf("%9s", "cat"); prints six
spaces before the letters cat. The size is a minimum not a maximum, long strings are not truncated.
- The number may be preceeded by a minus sign, in which case padding is added to the right instead.
- If a decimal point appears before the number, then the number becomes a maximum size. Strings longer than the maximum
are truncated, and do not need to be properly zero terminated.
- There may be two numbers with a decimal point between them: the first number gives the minimum size, and the second
gives the maximum. For example, printf("%-9.9s", xxx); prints the string xxx in exactly nine
characters. If it is longer, only the first 9 are printed; if it is shorter, spaces are added to the right (right
because of the minus sign).
*: Computed Sizes
Anywhere in the above descriptions where a number appears (e.g. in %5d and %10.3f), the number may be replaced
by a star (e.g. %*d, %10.*f, %*.3f, and %*.*f). When a star is encountered, it is replaced by the value of the next
unused parameter, which must be an integer. For example, the following code prints 3, 3.1, 3.14, 3.142,
3.1416: const float pi=3.141592654;
int i;
for (i=0; i<=3; i+=1)
printf("%10.*f\n", i, pi);
%n: Measuring the Output
When a %n format is encountered, it does not cause any additional printing. Instead, the total
number of characters printed by the current call to printf is calculated, and stored in the variable indicated
by the next unused parameter, which must be a pointer to an int. For
example: int len, x=123, y=98989;
printf("%d plus %d is %d%n\n", x, y, x+y, &len);
printf("That line was %d characters long\n", len);
%i and %p: Unnecessary Formats
%i is an obsolete equivalent to %d
%p is used for printing pointers in a "sensible" format; it is usually equivalent to %08X
int scanf(char format[], ...)
include <stdio.h>
Scanf is almost the opposite of printf. Its first parameter is a string of formats,
almost exactly the same as the formats used with printf, but instead of printing its
parameters according to the format, it scans input from the user, extracting data
from it according to the format. All of the parameters must be pointers to variables
of the appropriate type.
Note This means that when you wnt to read a value for any simple variable (i.e. not a
string), you must put an ampersand & in front of its name in the parameter list. All
of the examples below show this.
Inside a format string, % codes indicate the format for a value to be read; they may cause
any number of input characters to be consumed. spaces and other invisible characters simply
indicate that any amount of whitespace in the input stream should be consumed, so a single
space in the format could result in 97 spaces and 14 blank lines being read. Any other
character is expected to be exactly matched by the same character in the input.
Normally, it is not desirable to specify sizes and precisions with input formats: %d will read
an integer of any size, %f will read a float of any size and any precision. However, sizes
may be specified for special purposes. With input formats, sizes represent the maximum number
of characters that will be consumed.
Scanf Formats
Examples:
- scanf("%d", &x); (requires that x is an int variable), reads an integer consisting of
any number of digits from the input, and stores its value in the variable x. It is willing to skip any amount
of whitespace in the input stream.
- scanf("%d %d", &x, &y); reads two integers consisting of
any number of digits from the input, and stores their values in the variables x and y. The two
values do not need to be on the same line of input.
- scanf("%1d%1d%1d", &x, &y, &z); reads three single digit integers from the input.
It is assumed that the three digits will be run together without separation (i.e. they look like a single three-digit
number), but they will be read as separate numbers. When a size is specified, no separating spaces are needed.
- scanf("%d %s", &x, y); (assuming x is an int variable, and y is a char array; array
names are automatically treated as pointers) will skip any amount of space before reading an integer int x,
then skip any further amount of white space (including newlines) before reading a string into y. The string
may not contain any white space; %s stops reading as soon as it reaches a space or newline.
- scanf("%5s%5s",x, y); (assuming x and y are char arrays)
will read two strings of at most 5 characters into x and y. If a string of more than 5 characters
is encountered, the first 5 will be read into x, and the remainder up to a further 5 into y.
Separating spaces are not needed when a string size is specified.
- scanf("%s %d/%d/%d", day, &year, &month, &day); is suiable for reading dates in this format:
"sat 2000/12/02".
Important Notes
int sprintf(char string[], char format[], ...)
include <stdio.h>
returns the number of ... parameters successfully printed, <0 for error.
The sprintf function is absolutely identical to the printf function, except for its
extra first parameter. To understand sprintf, read it as printf, ignoring the
first parameter. Whatever output printf would would produce is instead stored in
the extra string that is provided to sprintf. For example, these two functions
produce identical output:
void main(void)
{ int x=3, y=12;
printf("%d x %d = %d\n", x, y, x*y); }
void main(void)
{ int x=3, y=12;
char sss[100];
sprintf(sss, "%d x %d = %d", x, y, x*y);
puts(sss); }
int sscanf(char string[], char format[], ...)
include <stdio.h>
returns the number of ... parameters successfully assigned to, <0 for error.
The relationship between sscanf and scanf is the same as the relationship between sprintf
and printf. To understand sscanf, read it as scanf and ignore the extra first argument.
Whatever scanf would attempt to read from the input stream, sscanf instead attempts
to read out of the string it is given. Once sscanf has finished, it does not remember
its position in the string: subsequent calls to sscanf with the same first parameter
will start again from the beginning.
sscanf will never read any input for itself, it can only read from the string it is given.
Because of this, a combinations of gets and sscanf is very often preferable to scanf
alone; the programmer gains complete control over the reading of input lines.
For example:
char line[100];
int x, y;
gets(line);
sscanf(line, "%d %d", &x, &y);
reads two integers from the user, so long as they are both entered on the same line.
If the line does not contain two integers, it will not consume any further input.
int fprintf(FILE *fileref, char format[], ...)
include <stdio.h>
returns the number of ... parameters successfully printed, <0 for error.
Once you know how to print things normally using printf, there is almost nothing new
to learn about writing data to a file. The fprintf function works exactly the same
way (yes, exactly) as printf, except that it takes an extra parameter that describes
a file. The output that fprintf produces is written to that file instead of to your
terminal.
Before fprintf can be used on a file, a program must open that file, so that
it is ready for use. See fopen for details. The result of fopen
is passed to fprintf as its first parameter.
int fscanf(FILE *fileref, char format[], ...)
include <stdio.h>
returns the number of ... parameters successfully assigned to, <0 for error.
Once you know how to print things to a file, reading things
from a file is trivial. Just as there is an fprintf function that works exactly
like printf except that it writes to a file, there is an fscanf function that works
exactly like scanf, except that it reads things from a file.
The use of scanf follows the pattern of the use of printf exactly. First you must use
fopen to open the file (or possibly use an already open file).
The result of fopen is passed as the first parameter to fscanf.
FILE *fopen(char filename[], char access[])
include <stdio.h>
returns NULL for error, otherwise a reference to the open file.
A file must be opened before a program can read or write its contents. The
file's name alone is not enough, all of the stdio functions that operate on files
must be provided with a File Reference as an additional parameter. fopen
opens a file, prepares it for processing, and returns just such a file reference.
The result of fopen must be kept in a variable of type FILE * and passed to any
function that needs to access that file.
fopen takes two parameters, both strings. The first is simply the name of the file,
or possibly its entire path. The second parameter describes the kind of access that
you want. If you specify read-only access when opening a file, the program will
be unable to write to that file, and vice-versa.
The common strings that may be used to specify access types are:
"r": read only. The file must already exist.
"w": write only. If the file does not exist, it is created; if it does already
exist, its contents are lost.
"a": (append) write only. If the file does not exist, it is created; if it does
already exist, the contents are kept, the first thing written by this program
is added to the end of the file.
"r+": reading and writing are both allowed, but beware: writing overwrites
anything already in the file. The file must already exist.
"w+": same as "r+" except that the file is created if it does not exist, and all
contents of already existing files are lost.
"a+": same as "r+", except that the contents of an existing file are not lost,
and the file will be created if it does not already exist. The first write adds
data to the end of the file.
If the fopen operation fails (the file does not exist, or is protected, or whatever),
the function returns the special value NULL, which is easy to test for.
int fclose(FILE *fileref)
include <stdio.h>
returns <0 for error (rare), 0 for success.
Every file that is opened by a program should, at some point, be closed by that program.
Once a file is closed, it can no longer be accessed. However, after closing a file
it is always possible to open it again. If a program is to write data to a file then
read that same data back, it is usually best to open the file for writing only, then
write the data, then close the file, then open it again for reading only, then read
the data, then close it again.
The parameter given to fclose is the file reference produced by fopen when the file was
opened.
The result returned by fclose is normally ignored, but is in fact an error signal. If
the result is zero, that means that the close operation was successful. A negative
result means something went wrong. It is difficult to deal with a failure to close
a file, so the result is usually completely ignored.
int fputc(int c, FILE *fileref)
include <stdio.h>
returns <0 for error, the parameter c otherwise.
The fputc function works in exactly the same was as putchar, except
that it writes the character to a file instead of to the standard output stream. The
first parameter, int integer, must be the ASCII code(*) for the
character to be printed, the second is the file reference for the file, as returned by
fopen.
int fgetc(FILE *fileref)
include <stdio.h>
returns the character read, EOF (which is -1) if at end-of-file or error.
The fgetc function works in exactly the same was as getchar, except
that it reads a character from a file instead of from the standard input stream. The
parameter is the file reference for the file, as returned by fopen.
The value returned by fgetc is an int, not a char. This is important. If there are no more
characters in the file to bre read, fgetc returns the special constant EOF, which is
defined to be -1. Normal char variables may not be capable of storing -1 (sometimes
char is an unsigned type), and using a char may result in being unable to detect
end-of-file.
Example: this program copies the file "in.txt" to the file "out.txt" exactly:
FILE *infile = fopen("in.txt", "r");
FILE *outfile = fopen("out.txt", "w");
if (infile==NULL)
{ printf("Error: Could not read in.txt!\n");
return; }
if (outfile==NULL)
{ printf("Error: Could not create out.txt!\n");
return; }
while (1)
{ int c=fgetc(infile);
if (c==EOF) break;
fputc(c, outfile); }
fclose(infile);
fclose(outfile);
int ungetc(int c, FILE *fileref)
include <stdio.h>
returns <0 for error, the parameter c otherwise.
The ungetc reverses the effect of a single call to fgetc or getchar (to reverse
getchar use stdin as the second parameter). After reading a character, ungetc
can be used to un-read it. After using ungetc, the next call to getc
(from the same file) will re-read the character that ungetc un-read.
Remember that getc is the one fundamental inout function: scanf and all the others
are defined in terms of getc, so ungetc can also un-read the last character
read by any input function.
Example: A program is to read a file that contains a mixture of words (strings) and
numbers (ints). The words are to be ignored, but all the numbers are to be
processed (perhaps added up). The simplest way is to read one character at a time,
and look at that character. If it is not a digit just continue reading the file.
If it is a digit, use fscanf with the "%d" format to read the number. But, after
reading the first character and seeing that it is a digit, you have ruined the number;
if the file contains "123", after reading the "1" the program would realise that
there is a number, but then only the "23" would be left for scanf to process.
Ungetc solves the problem.
int total=0;
while (1)
{ int c, n;
c==fgetc(infile);
if (c==EOF) break;
if (c<'0' || c>'9') continue;
ungetc(c, infile);
fscanf(infile, "%d", &n);
total+=n; }
char *fgets(char str[], int length, FILE *fileref)
include <stdio.h>
Reads a whole line of input from a file into an array of characters.
returns <0 for error, the parameter c otherwise.
str = the aray of characters to receive the line of input
length = the size of that array (i.e. maximum number of chars to read)
fileref = the file to read from (may be stdin)
fgets reads an entire line (up to a maxiumum length) from a file into a string
(i.e. into an array of char). The three parameters are: the array of characters
to be read into, the maximum number of characters to read, and the file reference
(as returned by fopen for the file. If you want to read from
the terminal (standard input), the pre-defined value stdin should be used as the
file reference.
The array should be at least 2 characters longer than the longest line that is
expected as a possible input. This is because one extra character is always
required to mark the end of a string, and because fgets reads the whole line
including the "newline" or "enter" character at the end. The second parameter
should be one less than the actual size of the array, because the end-of-string
character is not counted.
Always remember that fgets reads the "newline" character '\n' and puts it at the
end of the string as an extra character, unlike gets. If the file being
read contains the three character line "CAT", fgets will read it as a four
character string 'C', 'A', 'T', '\n'. It will need a five character array to
store it: 'C', 'A', 'T', '\n', '\0'. Normally the first thing a program does
after reading a line is to check for the '\n' at the end and remove it. The
strlen function counts the number of characters in a char array, and can be
used for this purpose.
Example: reading a file line-by-line:
char line[1000];
for (int n=1; 1; n+=1)
{ char *s = fgets(line, 999, infile);
if (s==NULL) break;
int len = strlen(line);
if (line[len-1] != '\n')
{ printf("file contains a line >999 chacaters long\n");
return; }
line[len-1] = '\0';
printf("line %d: '%s'\n", n, line); }
Important note: If the line is too long to fit in the array size specified, fgets
will read as much of it as will fit. When this happens, there is no "newline"
'\n' at the end of the string. The "newlines" are not imagined by the system,
they are only put into the array to represent a real end-of-line. So, a
too-long line can be detected by finding that there is no '\n' at the end. In
this case, the next fgets will attempt to read the rest of that line; it does
not just skip to the beginning of the next line.
int fputs(char str[], FILE *fileref)
include <stdio.h>
Writes a whole line of output from an array of characters to a file.
returns <0 for error, 0 for success.
fputs is the counterpart of fgets; it is used for writing whole lines that already
have a newline character '\n' at the end (as produced by fgets). fputs
does not automatically start a new line.
Example: reading a file line-by-line and displaying it on the user's terminal:
char line[1000];
while (1)
{ char *s = fgets(line, 999, infile);
if (s==NULL) break;
fputs(line, stdout); }
Note that in this example, it doesn't matter if a line in the file is too long, it
will simply be read by multiple successive calls to fgets; only the last will
provide a '\n' at the end and thus start a new line of output.