Basic I/O in C

The C programming language contains no input or output commands per se. Input and output is instead handled by functions contained in the stdio library. The scanf() and printf() functions are often used in beginner C texts, but there are other input/output functions as well. It’s worth remembering as well that scanf() isn’t exactly the safest function to use.

In C, all input an output is viewed as streams of characters. Whether the program gets input from the keyboard, a file, an Internet connection, or a mouse, C only sees a stream of characters.

The two most basic input/output functions are getc() and putc(). The getc() function retrieves a single character from the standard input device, and the putc() function outputs a single character to the standard output device.

#include <stdio.h>

int main(void){

    int intVal;
    
    char charVal01, charVal02;
    
    printf("Enter a letter: ");
    
    intVal = getc(stdin);
    
    charVal01 = intVal;
    
    printf("Enter another letter: ");
    
    intVal = getc(stdin);
    
    charVal02 = intVal;
    
}

When we compile and run the program above we’ll notice a glaring problem right away: the carriage return counts as a character as well, which means that we never get a chance to enter in the second value. When we answer a getc() prompt by typing a character and hitting Enter, the program sees that input as a stream of two characters. Let’s try the program again, this time defining a macro for clearing the input buffer.

#include <stdio.h>
#define CLEAR_BUFFER while((getc(stdin))!='\n'){}

int main(void){

int returnVal;

char charVal01, charVal02;

printf("What is the first letter?\t");

returnVal = getc(stdin);

CLEAR_BUFFER

charVal01 = returnVal;

printf("What is the second letter?\t");

returnVal = getc(stdin);

CLEAR_BUFFER

charVal02 = returnVal;

//output char values
//to the screen
putc(charVal01, stdout);
putc(charVal02, stdout);

}

Note that the program must call two getc()  functions, one for each value desired.

The print() and scanf() functions are called formatted I/O functions because they give us formatting control via conversion and escape characters. Functions like putc() and getc() are character I/0 functions, since they only handle one character at a time. We can still, however,  use the escape characters to add some basic formatting to our output.

#include <stdio.h>
#define CLEAR_BUFFER while((getc(stdin))!='\n'){}
#define NEWLINE putc('\n', stdout);



int main(void){

    int intVal;
    
    char charVal01, charVal02;
    
    printf("Input a number:\t");
    
    intVal = getc(stdin);
    
    CLEAR_BUFFER;
    
    charVal02 = intVal;
    
    putc(charVal02, stdout);
    
    NEWLINE
    
    printf("Input another number:\t");
    
    intVal = getc(stdin);
    
    charVal01 = intVal;
    
    putc(charVal01, stdout);
    
    NEWLINE
    
    
    //converting from ASCII to decimal values
    //can get tricky
    printf("%c + %c = %d\n", charVal01, charVal02, charVal01 + charVal02);
    
    printf("errr...wait\n");
    
    //change ASCII value of number
    //to its decimal value
    charVal01 -= '0';
    charVal02 -= '0';
    
    printf("%d + %d = %d\n", charVal01, charVal02, charVal01 + charVal02);
    
}

The getchar() and putchar() functions do not specify a device because they assume stdin and stdout. They, like getc() and putc(), are called mirrored functions, because they perform complementary actions.

#include <stdio.h>

#define BUFFER_SIZE 50

//use getchar() and putchar() in macros
#define CLEAR_BUFFER while((getchar())!='\n'){}
#define NEWLINE putchar('\n');

//function prototype
int getString(char *string, int buffer);

int main(void){

    char string[BUFFER_SIZE];
    
    printf("Enter a string, %d characters max\n", BUFFER_SIZE);
    getString(string, BUFFER_SIZE);
    
    printf("%s\n", string);
    
    printf("Enter another string, %d characters max", 10);
    
    if((getString(string, 10))==1){
        printf("Please note that this string has been truncated...\n");
    }
    
    printf("%s\n", string);
    
    return 0;
} // end main()

int getString(char *string, int buffer){
    int i = 0;
    
    //*(string+i) equivalent to string[i++]
    do{
        *(string+i)=getchar();
    }while((*(string+i++)!='\n')&&(i<buffer));
    
    //make the char array into a string
    //note i was incremented once at end of
    //dow while loop, thus we must subtract one
    //to eliminate the newline character
    *(string+(i-1))='';
    
    //buffer length exceeded?
    if(i==buffer){
        //clear buffer of excess characters
        CLEAR_BUFFER
        //return error warning value
        return 1;
    }
    return 0;
}

It’s worth mentioning that the getchar() function can be inserted directly into the while() test expression; this actually is standard practice and does deliver a small performance gain. I myself am not a huge fan of micro-optimization in higher languages such as C# or Java; but, optimization is the whole point of C.  Note that in this case we must include an extra set of parentheses around the function since we will be evaluating a side effect of the getchar() function.

Please buy my book it makes me happy: http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M/