The C Programming Language - Input and Output

Edusagar - notes - Input and Output
  • Input and output are not part of C language itself, but there are few standard libraries that make our job of handling input and outstream easier with portability in mind.

  • int getchar(void) returns the next input character from standard input(e.g. keyboard) each time it is called, or EOF if there are no more characters to read. EOF is defined as -1 in <stdio.h>, but we should use symbolic constant only.

  • oneprogram | secondprogram

    here standard output of oneprogram is piped into standard input of secondprogram (which can be read by getchar).

  • int puchar(int) is used for output: putchar(c) puts the character 'c' to the standard output(usually display screen). Output produced by printf also finds its way to the standard output. Calls to putchar and printf may be interleaved - output happens in the order in which the calls are made.

  • Functions defined in standard library shields the program using them from the knowledge of character set.

    int printf(char *format, arg1, arg2, ...);

    printf converts, formats and prints its arguments on standard output under control of the format. It returns the number of characters printed.

  • Some of the conversion specifiers between '%' and the conversion character are:

    minus sign (%-)which specifies left adjustment of the converted argument.
    number (%2)number specifies miminum field width. The converted argument will be printed in a field at least this wide. If necessary it will be padded on the left (or right, if left adjustment is called for) to make up the field width.
    period (%.)which separates the field width from the precision.
    precision (%.2)specifies the maximum number of characters to be printed from a string, or the number of digits after the decimal point of a floating-point value, or the minimum number of digits for an integer.
    h (%h)if the integer is to be printed as a short
    l (%l)(letter ell) if the integer is to be printed as a long
  • printf("%.*s", max, s);

    '*' specifies the width, which is picked up from the next argument which must be an int(max in this case).

    printf(s); /* FAILS if s contains % */

    printf("%s", s); /* SAFE */

  • The function sprintf does the same conversions as printf does, but stores the output in a string:

    int sprintf(char *string, char *format, arg1, arg2, ...);

  • printf uses variable argument list depicted in its prototype as '...'(ellipsis). <stdarg.h> contains a set of macros that define how to step through an argument list. For variable argument syntax to work, atleast one named argument should be there.

  • va_list is used to declare a variable that will refer to each argument in turn.

    va_arg returns one argument value based on the data type passed to it and steps forward to the next in the list.

    va_start initializes a pointer to point to the first unnamed argument in the list.

    va_end cleans up whatever is neccessary.

  • /* minprintf: minimal printf with variable argument list */
    void minprintf(char *fmt, ...)
    	va_list ap;  /* points to each unnamed argument in turn */
    	char *p, *sval;
    	int ival;
    	double dval;
    	va_start(ap, fmt); /* make ap point to first unnamed arg */
    	for (p=fmt; *p; p++) {
    		if (*p != '%') {
    		switch(*++p) {
    			case 'd':
    				ival = va_arg(ap, int);	
    				printf("%d", ival);
    			case 'f':
    				dval = va_arg(ap, double);
    				printf("%f", dval);
    			case 's':
    				for(sval = va_arg(ap, char *); *sval; sval++)
  • All the arguments to scanf() other than the format string must be pointers. scanf stops when it exhausts its format string, or when some input fails to match the control specification. It returns as its value the number of successfully matched and assigned input items. This can be used to decide how many items were found.

  • The format string usually contains conversion specifications, which are used to control conversion of input. The format string may contain:

    • Blanks or tabs, which are not ignored.
    • Ordinary characters (not %), which are expected to match the next non-white space character of the input stream.
    • Conversion specifications, consisting of the character %, an optional assignment suppression character *, an optional number specifying a maximum field width, an optional h, l or L indicating the width of the target, and a conversion character.
  • Parse a date string

    int day, year;
    char monthname[20];
    if (sscanf(line, "%d %s %d", &day, monthname, &year) == 3)
    	printf("valid: %s\n", line); /* 25 Dec 1988 form */
    else if (sscanf(line, "%d/%d/%d", &month, &day, &year) == 3)
    	printf("valid: %s\n", line); /* mm/dd/yy form */
    	printf("invalid: %s\n", line); /* invalid form */
  • fopen() returns a pointer of type FILE defined in <stdio.h>, called the file pointer which points to a structure that contains meta information about the file, such as the location of a buffer, the current character position in the buffer, whether the file is being read or written, and whether errors or end of file have occurred.

    FILE *fp;
    fp = fopen("myfile.c"/*filename*/, "w"/*mode*/);

    Opening an existing file in write mode, discards the existing contents, while append mode preserves them.

  • int getc(FILE *fp) returns the next character from the stream referred by fp; it returns EOF for end of file or error.

    int putc(int c, FILE *fp) writes character 'c' to the file stream pointed by fp and returns the character written if successful, or EOF if an error occurred.

  • When a C program starts executing, operating system always opens three file and provides pointer to them. These are stdin(standard input), stdout(standard output) and stderr(standard error).

  • For formatted read / write to files fprintf() and fscanf() may be used.

    int fprintf(FILE *fp, char *format, ...);

    int fscanf(FILE *fp, char *format, ...);

  • Since most operating systems have some limit on the number of files that a program may have open simultaneously, it's a good idea to free the file pointers when they are no longer needed using:

    int fclose(FILE *fp);

    fclose() also flushes out the buffers in which putc() is collecting output. fclose() is called automatically for each open file when a program terminates normally.

  • int ferror(FILE *fp)

    The function ferror returns non-zero if an error occurred on the stream fp.

  • Although output errors are rare, they do occur (for example, if a disk fills up), so a production program should check this as well.

  • The function feof(FILE *) is analogous to ferror; it returns non-zero if end of file has occurred on the specified file.

    int feof(FILE *fp)

  • char *fgets(char *line, int maxline, FILE *fp)

    fgets reads the next input line (including the newline) from file fp into the character array line; at most maxline-1 characters will be read. The resulting line is terminated with '\0'. Normally fgets returns line; on end of file or error it returns NULL.

  • int fputs(char *line, FILE *fp)

    fputs writes a string to file fp, it returns EOF if an error occurs, and non-negative otherwise.

  • /* fgets: get at most n chars from iop */
    char *fgets(char *s, int n, FILE *iop)
    	register int c;
    	register char *cs;
    	cs = s;
    	while (--n > 0 && (c = getc(iop)) != EOF)
    		if ((*cs++ = c) == '\n')
    	*cs = '\0';
    	return (c == EOF && cs == s) ? NULL : s;
    /* fputs: put string s on file iop */
    int fputs(char *s, FILE *iop)
    	int c;
    	while (c = *s++)
    		putc(c, iop);
    	return ferror(iop) ? EOF : 0;
  • The library functions gets and puts are similar to fgets and fputs, but operate on stdin and stdout. Confusingly, gets deletes the terminating '\n', and puts adds it.

  • int ungetc(int c, FILE *fp) pushes the character c back onto file fp, and returns either c, or EOF for an error. Only one character of pushback is guaranteed per file. ungetc may be used with any of the input functions like scanf, getc, or getchar.

  • void *calloc(size_t n, size_t size)

    returns a pointer to enough free space for an array of n objects of the specified size, or NULL if the request cannot be satisfied. The storage is initialized to zero.

  • The function rand() computes a sequence of pseudo-random integers in the range zero to RAND_MAX, which is defined in <stdlib.h>. One way to produce random floating-point numbers greater than or equal to zero but less than one is

    #define frand() ((double) rand() / (RAND_MAX+1.0))

    The function srand(unsigned) sets the seed for rand.

comments powered by Disqus