C Programming Lesson 3 – Command Line Input/Output, Documentation and Variables

By Kosmas Raptis on November 18, 2021

Prologue

In C, one of the most common things you will be using in your program (given that you don’t use graphics for it) is the command line. Another thing you’ll always be using, however, is variables. So, let’s check out how to use the command line for showing but also receiving data to/from the user and how to use variables to store data.

Using the printf() function

The C standard library (which comes with every C installation) provides us with a few functions related to input and output through various things, including a command line. These are available via the stdio.h header. One of those functions is the printf() function (print formatted). It allows us to write text to the command line following any format we want. It’s also one of the easiest ways to use formatted text output (if not the easiest). However, to see how it works, I will not write it all here. Instead, we’re going to use the work that the people who made it have done for us explaining how it works. In other words, we’re going to take a look at its documentation.

Introducing Documentation

Documentation plays a very crucial part in programming. I’d even say, it’s one of the core things the world of programming revolves around. Documentation of a library is basically a piece of text describing to the programmer that wants to use it how it works. When you use a library, it most likely has its documentation somewhere, either packed with its header files or on the internet, else it will be very difficult to use. Storing documentation on the internet seems to be the most common thing to do. For example, the SDL2 library (a very useful C library designed to provide easy multimedia handling and can also make game programming easier) has all its documentation on its website (but also packed with its header files).

Using documentation to figure out how printf() works

Of course, the C standard library also has documentation for every single one of its header files and functions available publicly, including our little printf() function. In fact, it is both packed with the header files themselves (and, actually, an IDE that can show you the documentation of something while you code, like CLion or Visual Studio Code which we set up back in tutorial 1 will show it to you) but also available through various websites on the internet. For now we’re going to use the cplusplus website (it provides both C and C++ documentation), more specifically this link. From it, we see that printf() is defined as follows:

int printf ( const char * format, ... );

From this, we can figure out the following:

1) It returns an int (we won’t be needing it right now, however feel free to read about what the integer it returns is from the website)

2) It first takes a string that defines the format (Strings in C are represented as char* or char[], more details when we talk about them in a future tutorial)

3) After that, it can take any number and type of arguments we want (That’s what the ... is supposed to represent). The arguments here are values that we can use with the formatted string, like numbers.

Well, that seems fairly simple. Let’s see it in action.

First, we create the main entry point where execution will start:

int main(int argc, char **argv) {
   return 0;
}

Remember, printf() is part of stdio.h, so let’s include that as well:

#include <stdio.h>

int main(int argc, char **argv) {
   return 0;
}

Finally, let’s use it to print the string “Hello!” to the user:

#include <stdio.h>

int main(int argc, char **argv) {
   printf("Hello!\n");
   return 0;
}

Note that, despite using printf() here, we are not actually using any format, we are just using a regular old string. The only weird thing you might notice is the \n character before we end the string and after Hello!. That is called a special character. It allows us to change how the string is displayed. All special characters start with \, however it’s not considered a part of the character itself and is just a marker to tell the computer “hey I’m giving you a special character!”. The letter next to the \ indicates the special character (\n stands for newline, basically telling the computer to move to the next line to print things after the character).

Special characters are not considered formatting, and thus aren’t only available for use with printf(). Every string in C can use special characters, and that also goes for every function in C that can work with strings, including printf() and puts(), which is another standard library function used for printing strings (doesn’t allow for formatting, though). In case you’re curious about puts(), go ahead and look up its documentation!

Pretty simple, right? Let’s make printf() print something a little more… real-world, like “Hello!” followed by a given name.

Introducing scanf(): Read user input

The C standard library provides a function for reading things the user gives our programs, like numbers and text (the user input). This function is called scanf() (scan formatted). This is the most common way of reading what the user has typed in C, and, as the name suggests, also allows for formatting how the user’s input is read. This function is also in the stdio.h header, so we don’t need to include anything else. Here’s the documentation!

Using the scanf() documentation

From the documentation, we can see that scanf() is used like this:

int scanf ( const char * format, ... );

Similarly to printf(), it takes a string that determines the used format first, and then can take any number of arguments we want (In the case of scanf(), the arguments are the variables that the input will be read to). It also returns an integer that says how many arguments were succesfully written to. We won’t be using its return value right now.

Taking the above program, let’s make it so that it also reads a name from the user and prints it:

#include <stdio.h>

int main(int argc, char **argv) {
   // This is where we will hold the name
   char userName[10] = {'\0'};

   scanf("%s", userName);

   printf("Hello, %s!\n", userName);
   return 0;
}

Woah, what happened here? Let’s take a look at the new code:

char userName[10] = {'\0'};

This here is an array of characters. Arrays will be covered in a later tutorial, but here’s a quick summary: An array, as its name suggests, lets us store an array of values of the same data type (like int, char, float etc.) consecutively, meaning each value is located right after the previous one. This array here allows us to hold 10 characters. We’re storing a series of 10 characters in sequence. Does this remind you of something? Well, if it’s not, let me just tell you that what we created right here is a string. Specifically, a string that can be up to 9 characters long (The 10th character is a special NULL character terminator, which is put there by default scanf behavior to indicate the end of the string). You will also notice {'\0'} there. This tells the compiler to initialize every element of the array to the special NULL character. This is done for safety purposes as certain compilers don’t initialize the array when it’s declared but rather when it’s first used and this might later lead to an unsafe allocation (though this is only a problem if you’re developing safety-critical code like an operating system). Moving on to the next line:

scanf("%s", userName);

This here calls scanf to read user input into userName as a string. If you haven’t ran the program already, then let me note that here your program will hang until you type something and press Enter.

You might notice something weird inside the format string. %s is a format specifier. This is what actually does all the formatting in printf and scanf. Format specifiers define how data should be formatted (hence the name). In our case, %s tells scanf that it should interpret the data it gets as a string of characters, or, more simply, as text. Here’s a list of the most common format specifiers:

  • %s – String
  • %c – Character
  • %d – Decimal integer
  • %x – Hexadecimal integer
  • %f – Floating point value

And here’s a complete list.

Let’s move on to the next line:

printf("Hello, %s!\n", userName);

Here, we print Hello, use the %s format specifier to give printf a string, and then add a newline. Just like with scanf, the data we want to format is given after the format string, separated by a comma.

Lastly, we return 0 to the operating system to tell it we ran succesfully.

Pretty easy, right? Go ahead and compile it by using the command

clang <sourcefilenamehere>.c -o <outputfilenamehere>

And then run it by executing the resulting binary called <outputfilenamehere>.

Let’s move on to something a bit more sophisticated. Let’s make a program that takes and prints back a string and a number. Specifically, it will ask for a name and an age in years.

Let’s look at the code:

#include <stdio.h>

int main (int argc, char **argv) {
   char name[10] = {'\0'};
   int age = 0;

   printf("Please enter your name below\n");
   scanf("%s", name);
   printf("Now please enter your age below (in years)\n");
   scanf("%d", &age);
   
   printf("Your name is %s and you are %d years old!\n", name, age);

   return 0;

}

Notice how printf has multiple format specifiers in its format string. We can do that to use more than 1 value in strings. We can use as many format specifiers as we want in a format string. The function we’re using is going to replace them with the values we told it to use, in the order that we give them. Reading the documentation will tell you likewise. Specifically:

If format includes format specifiers (subsequences beginning with %), the additional arguments following format are formatted and inserted in the resulting string replacing their respective specifiers.

cplusplus.com

With format in this case being the format string. This is basically the same thing, just said more formally.


Given the above small list of format specifiers and the order of the values we gave to printf, you can tell that it’s going to print the name as a string and the age as a decimal number. Just like we wanted.

You might have also noticed a & before age when using it in scanf. This is because, in order to modify a variable, scanf requires a pointer to that variable. The details of why will be covered in the tutorial about functions. However, if you’re curious and think you’re ready to understand that, I’ll have a link below in the additional resources section about it.

In the case of name, we didn’t have to use that because an array is basically a pointer to its first element, so scanf got a pointer straight out of the box. However, int is not a pointer, it’s just a good old integer. Just a number. So the & is used to create a pointer to it in order to pass it into scanf. Note this is not necessary for printf, as it does not need to modify the value of age and doesn’t require a pointer. The %s specifier does require a pointer even when using with printf, which is also why name is used the exact same way as with scanf here.

Pretty straightforward. Run that and see if it works.

Now, here’s an exercise. Make a program that accepts 2 numbers and prints their sum. Here’s a tip on how to do it:

The sum of the numbers is calculated by doing number1 + number2. You can give that to printf as well in place of what would normally be an int value, or you can just create an int to hold that and then give that to printf. Both are correct and will have the same result. The choice is yours. DON’T LOOK ANY FURTHER THAN THIS VERY SENTENCE UNTIL YOU’RE DONE IF YOU WANT TO GIVE THIS CHALLENGE A GO!!!

Done? Here’s the code:

#include <stdio.h>

int main (int argc, char **argv) {
   int number1 = 0;
   int number2 = 0;

   printf("Please enter a number below\n");
   scanf("%d", &number1);
   printf("Now please enter another number below\n");
   scanf("%d", &number2);
   
   printf("The sum of %d and %d is %d\n", number1, number2, number1 + number2);

   return 0;

}

Pretty easy. Create 2 int variables, scanf them, add them and printf that.

scanf can be used this way for every primitive data type in C. Primitive data types are the basic types that are provided by the language itself. For example, int is a primitive data type. So is char.

Here’s a complete list of primitive data types in C.

Summary

Documentation is very useful when programming. Never forget that.

A variable is specified with the following body:

dataType name = value;

printf and scanf are used for formatted input and output for our command line.

printf and scanf both use format strings to determine how your input/output will be formatted.

Format strings contain format specifiers, like %d, that tell the computer how to interpret the data we’re about to give it.

Additional resources

cplusplus.com – C standard library documentation

Article on pass by value vs pass by reference – Why scanf needs a pointer, pediaa.com

Variables in C, tutorialspoint.com

Source code for all programs in this tutorial, github.com

Happy to see you here, hope you enjoyed today’s tutorial! I’ll see you next time!

Leave a comment

Design a site like this with WordPress.com
Get started