Input and Output in C programming

The purpose of output and input is for the program to be able to communicate with the user. The user supplies the program with raw information (input) and the program gives back the user the processed information (output).

Printing output using printf()

To understand how to print to console using printf() function, let us take a look at the program below:

#include <stdio.h>

int main(){
	
	printf("This is my first printout");
	
	return 0;
	
	}

If you run the program above you get the output:

//> This is my first printout

We are using the printf() function in the example. A function is a block of code that can be called to do a certain task. For example, printf() is called to print the string in the parenthesis to screen.

Printing numbers using printf()

One thing you are going to realise is that printf() only prints strings which means if you try to run the code below you will get a compilation error:

#include <stdio.h>

int main(){
	
	printf(1987);
	
	return 0;
	
	}

The typical output will be a compilation error:

/storage/emulated/0/MyProjects/c prog/output.c:5:9: warning: 
      incompatible integer to pointer conversion passing 'int' to
      parameter of type 'const char *' [-Wint-conversion]
        printf(1987);
               ^~~~
~R/ENG/CPP/Headers/Platforms/Android/usr/include/stdio.h:129:24: note: 
      passing argument to parameter '__fmt' here
int printf(const char* __fmt, ...) __printflike(1, 2);
                       ^
/storage/emulated/0/MyProjects/c prog/output.c:5:9: warning: format
      string is not a string literal (potentially insecure)
      [-Wformat-security]
        printf(1987);
               ^~~~
/storage/emulated/0/MyProjects/c prog/output.c:5:9: note: treat the
      string as an argument to avoid this
        printf(1987);
               ^
               "%s", 
2 warnings generated.
SIGSEGV on thread : -1613402112

The exact wording of the error message you are going to get depends on your machine and on your compiler.

One way of solving that error is to treat the number as a string, such as by wrapping the number in quotes. For example:

#include <stdio.h>

int main(){
	
	printf("1987");
	
	return 0;
	
	}

The output is now:

//> 1987

However the limitation of that solution is that our number effectively becomes a string and number operations wont work within the printf() function. For example:

#include <stdio.h>

int main(){
	
	printf("2 + 3");  //> 2 + 3
	
	return 0;
	
	}

The output is "2 + 3" because its a string and it is printed as it it is.


Using placeholder format specifiers in printf()

To preserve number operations within the printf() function we use format specifiers to insert the result of a number operation into the output string. For example:

#include <stdio.h>

int main(){
	
	printf("%d", 2 + 3); //> 5
	
	return 0;
	
	}

The output is 5 because the format specifier %d is a placeholder for the result of the number operation 2 + 5.

Let us look at another example:

#include <stdio.h>

int main(){
	
	int currentYear = 2021;
	int birthYear = 1987;
	
	printf("I am %d years old",  currentYear - birthYear); //> I am 34 years old 
	
	return 0;
	
	}

As you can see, the output will be "I am 34 years old". This is because the %d placeholder is replaced by the result of currentYear - birthYear.

There is virtually no limit to the number of placeholder you can use in your output. For example:

#include <stdio.h>

int main(){
	
	int currentYear = 2021;
	int birthYear = 1987;
	
	printf(" This is the year %d. I was born in %d, so I am %d years old.",   currentYear, birthYear, currentYear - birthYear); //> This is the year 2021. I was born in 1987, so I am 34 years old.
	
	return 0;
	
	}

These placeholders are called format specifiers. There are many other format specifiers that work with printf() depending on the data type we are outputting.

Other format specifiers are:

Format specifierData type
%d or %iint
%ld or %lilong int
%ffloat
%lfdouble. "%f prints doubles as well"
%cchar
%sstring
%xhexadecimal

The example below demonstrate the use of format specifiers:

#include <stdio.h>

int main(){
	
	printf("My age is %d", 23);       //> My age is 23
	printf("\nMy height is %f m", 1.78);   //> My height is 1.780000 m
	printf("\nThe speed of light is %lf m/s", 3e+8f);  //> The speed of light is 300000000.000000 m/s	
	printf("\nMy grade in Physics is %c", 'A');   //> My grade in Physics is A
	printf("\nThe approximate value of pi is %lf", 22.0/7);  //> The approximate value of pi is 3.142857
	printf("\nMy name is %s", "Sydney"); //> My name is Sydney
	
	return 0;
	
	}

Format specifiers are also used to specify the width and precision of numbers and strings when they are inserted.

For example:

#include <stdio.h>

int main(){
	
	printf("The answer is %lf", 1987.03/2.3);
	
	printf("\nThe answer is %.1lf to 1 decimal place", 1987.03/2.3);
	
	printf("\nThe answer is %.2lf to 2 decimal places", 1987.03/2.3);
	
	printf("\nThe answer is %.3lf to 3 decimal places", 1987.03/2.3);
	
	printf("\nThe answer is %.4lf to 4 decimal places", 1987.03/2.3);
	
	printf("\nThe answer is %.5lf to 5 decimal places", 1987.03/2.3);
	
	return 0;
	
	}
	
/*** OUTPUT ***

The answer is 863.926087
The answer is 863.9 to 1 decimal place
The answer is 863.93 to 2 decimal places
The answer is 863.926 to 3 decimal places
The answer is 863.9261 to 4 decimal places
The answer is 863.92609 to 5 decimal places

***/

Printing tabs and newlines using printf()

Tabs and newlines are usually used to make the output neat and readable. For example, using the newline character (\n) we can format the output as follows:

#include <stdio.h>

int main(){
	printf("    2303\n");
	printf("+ 1987 \n");
	printf("---------\n");
	printf("    %d \n", 2303+1987);
	printf("---------");
	return 0;
}

And the output will be:

    2303
+ 1987 
---------
    4290 
---------

The printf() function does not put line breaks in at the end of each printed statement. We must do it ourselves using the newline escape character ("\n").

The example below shows an example of formatting the output to make it more readable using tabs:

#include <stdio.h>

int main(){
	
	printf(" %s\t\t\t\t\t %s\t\t %s\t\t\n", "Aleck", "23", "Male");
	printf(" %s\t\t\t\t\t %s\t\t %s\t\t\n", "Betty", "24", "Female");
	printf(" %s\t\t\t\t\t %s\t\t %s\t\t\n", "Carren", "25", "Female");
	printf(" %s\t\t\t\t\t %s\t\t %s\t\t\n", "Dennis", "26", "Male");
	printf(" %s\t\t\t\t\t %s\t\t %s\t\t\n", "Esther", "27", "Female");
	
	return 0;
	
	} 

Output:

Aleck					 23		 Male		
Betty					 24		 Female		
Carren					25		 Female		
Dennis					26		 Male		
Esther					27		 Female		

Printing output using puts()

The puts() function is a very simple way to printing a string to the screen if the string has no placeholders. Unlike printf(), puts() function appends a newline character to the output.

#include <stdio.h>

int main(){
	
	puts("First line");   //> First line
	puts("Second line");  //> Second line
	
	printf("First line");
	printf("Second line"); //> First lineSecond line
	
	return 0;
	
	}

Printing output using putchar()

putchar() writes one character to the screen.

#include <stdio.h>

int main(){
	
	putchar('a');    //> a
	putchar('\n');
	putchar(100);    //> d
	
	//100 is the ASCII code for d
	
	return 0;
	}

Input using scanf()

The scanf() function is the input counterpart of the printf() output function. The scanf() function accepts placeholder representing the type of value that will be entered by the user. These scanf() placeholders formats are mostly the same as for the printf() function.

Format specifierData type
%d or %iint
%ld or %lilong int
%ffloat
%lfdouble
%cchar
%sstring
%xhexadecimal

The second parameter of the scanf() function is the memory address of the variable to which you want to save the input value. For example:

#include <stdio.h>

int main(){
	
	// declare the variable to hold the input integer value
	int a;
	
	// prompt the user to enter the input
	printf("Please input an integer value: ");
	
	// accept the input value using scanf
	// &a is the memory address of variable a
	// %d is the placeholder for accepting an integer
	scanf("%d", &a);
	
	/*** for example enter 23 at the prompt ***/
	
	// print out the input value
	printf("You entered: %d\n", a);  //> You have entered 23
	
	
	return 0;
}

Pointers are a topic of discussion on their own and I will address them as a topic on their on. However you should know that the & is an address pointer when prepended to a variable identifier. For example, &a means the "memory address of a". Therefore scanf("%d", &a); means "Read in an integer from the user and store it at the address of variable a."

To obtain an input string using scanf, you do not include the & operator for the variable address.

For strings it is wrong to say scanf("%s", &a);. The correct usage is scanf("%s", a);. The reason is because whenever you use a format specifier for a string (%s), the data type stored will be an array of characters. A string is an array of characters. In C, an array name itself is an address pointer, hence, the address of operator & is not required.

#include <stdio.h>

int main(){
	
	// declare the variable to hold the input string (e.g. a char array of size 20)
	char a[20];
	
	// prompt the user to enter the input
	printf("Please input your name: ");
	
	// accept the input value using scanf
	// with string we dont use &a but we use a for the memory address of array a
	// %s is the placeholder for accepting a string
	scanf("%s", a);
	
	/*** for example enter Tanaka at the prompt ***/
	
	// print out the input value
	printf("Your name is %s\n", a);  //> Your name is Tanaka
	
	
	return 0;
}

Input using getchar()

Another way of reading input is by calling the getchar() function. It is the input counterpart of the putchar() output function.

#include <stdio.h>

int main(){
	
	printf("Please enter your grade : \n");
	
	// get input character
	char grade = getchar();
	
	printf("Your grade is %c", grade);
	
	return 0;
	
	}

getchar() reads one character from the standard input (usually the user’s keyboard) and returns the character it reads.