PowerPoint Presentation
CSE 2421
The C Language – Part 3 – I/O
Required Reading:
Pointers on C, Section 15.8, 15.8.1,15.10 through 15.10.4 inclusive
Linux/Unix systems use the ASCII character encoding format
Most IBM products use the EBCDIC character encoding format
There is also a character encoding format called Unicode
For this class we will only work with ASCII
Character value encodings
Reminder: Before a function in a C program is invoked, or called, it must be declared. Otherwise, the compiler will output an error message when you compile. Remember also that a definition of a function includes a declaration.
When we want to use I/O functions in the C standard library, we will include stdio.h in our source file, which contains declarations of these library functions, so that the compiler can do type-checking of our calls to these functions.
We will only look at some of the most commonly used of these functions here.
They are all you need for the labs in this course (and all you are allowed to use).
C functions and I/O
3
There is no input or output defined in C itself; functions have been written and incorporated into the standard library for input and output (stdio).
Two basic types of I/O:
Character based (no format specifiers) – character by character I/O
int getchar() – input
int putchar(c) – output
Formatted – zero or more characters, with a requirement to specify the format of the input or output (how the sequence of characters read or written is to be interpreted):
int scanf(parameters go in here) – input – white space is important!!!
int printf(parameters go in here) – output
These functions use format strings to specify interpretation (% before string)
Two functions of a very few in C that can have a differing number of parameters each time they are called.
Example:
#include
int main()
{ /* check1.c – shows calls to scanf() and printf() */
int x;
scanf(“%d\n”, &x); /* Notice address operator & */
printf(“x=%d\n”, x);
}
Basic I/O
These functions can be used to input and output one character at a time.
Declarations (interfaces):
int getchar(void);
int putchar(int); /* the int value returned can be ignored */
Notice that both of these functions use the integer values which correspond to a given ASCII character. The integer must be cast before being assigned to a char variable, or must be printed with a %c format code to be output as a char.
An integer is returned, rather than a char, because certain text file control values (EOF, or end of file, for example) do not have one byte ASCII encodings.
getchar() and putchar()
/* assume #include
…
int code;
…
printf(“Please enter the appropriate single letter code, followed by enter: \n”);
code = getchar();
printf(“The code entered was: %c \n”, code); /* outputs int as a char */
——————————————————————
/* another way to do it – again, assume #include
…
char code;
…
printf(“Please enter the appropriate single letter code, followed by enter: \n”);
code = (char) getchar(); /* cast int value read from input to char */
printf(“The code entered was: %c \n”, code);
Example with getchar()
Both format I/O
Both manipulate “standard I/O” location – the keyboard for input, and the terminal display for output (although we can use something called redirection on the command line to change this – more below)
printf – output
Converts values to a character form, according to the format string, and prints them to “standard out” (stdout)
scanf – input
Converts characters from “standard in” (stdin), according to the format string, and followed by pointer arguments (i.e., addresses), indicating where the resulting values are to be stored
Formatted I/O: printf vs scanf
Input:
scanf(“format specification string”, ¶m1, ¶m2, ¶m3, …);
A format specification string is a string literal defining the format from which input should be read
scanf can have an indeterminate number of parameters. The 2nd through the nth parameters are the addresses of variables into which values are placed (pass by reference)
There is a % format substring within the first parameter that represents the format to be used for each of the next n-1 parameters
Output:
printf(“format specification string”, param1, param2, param3, …);
A format specification string is a string literal defining the format in which output should be formatted
printf can have an indeterminate number of parameters. The 2nd through the nth parameters are values to be printed (pass by value)
There is a % format substring within the first parameter that represents the format to be used for each of the next n-1 parameters
ANSI C Formatted I/O
When programming in C, you use format strings — the percentage sign and a conversion code, for the most part (although some other characters between % and the conversion character are optional – see below) — as placeholders for variables you want to read from input or display. The above table shows the format strings and what they display…
Format Strings
Conversion Character Displays Argument (Variable’s Contents) As
%c Single character
%d, %i Signed decimal integer (int)
%e Signed floating-point value in E notation
%f Signed floating-point value (float)
%g Signed value in %e or %f format, whichever is shorter
%o Unsigned octal (base 8) integer (int)
%s String of text (NULL terminated)
%u Unsigned decimal integer (int)
%x Unsigned hexadecimal (base 16) integer (int)
%% (percent character)
What is the difference between %i and %d? The table says they both print signed decimal integers.
https://www.geeksforgeeks.org/difference-d-format-specifier-c-language/
printf: There is no difference between the %i and %d format specifiers
scanf: %d and %i behavior is different
%d assume base 10 while %i auto detects the base.
For example, 012 would be 10 with %i but 12 with %d.
It assumes 012 is in octal => 10 in decimal
It assumes 12 is in decimal = > 12
%i vs %d
/* NOTE: The codes for formatted I/O from above are used */
printf(“%d\t%d\n”, fahr, celsius);
Causes the values of the two integers fahr and celsius to be printed, with a tab (\t) between them, and followed by a newline.
printf(“%3d\t%6d\n”, fahr, celsius);
To print the first number to three digits wide, and the second to six digits wide
NOTE: Each % construction in the first argument of printf is paired with the corresponding second argument, third argument, etc.; they must match up properly by number and type, or you will get wrong answers or a compile time error.
printf(“\na=%f\nb=%f\nc=%f\nd=%f”,a,b,c,d);
What does this statement print?
6
Formatted output – printf examples
printf(“\na=%f\nb=%f\nc=%f\nd=%f\n”,a,b,c,d);
If a=6.2, b=5.455, c=3.1415, d=6.0, then output is:
a=6.200000
b=5.455000
c=3.141500
d=6.000000
printf(“\na=%4.2f\nb=%6.4f\nc=%5f\nd=%3f\n”,a,b,c,d);
If a=6.2, b=5.455, c=3.1415, d=6.0, then output is:
a=6.20
b=5.4550
c=3.141500
d=6.000000
Example
float x = 3.14159;
printf(“output:”);
printf(“%4.3f\n”, x);
printf(“%4f\n”, x);
printf(“%.3f\n”, x);
output:
3.142
3.141590
3.142
printf examples
minimum field width is 4! Notice it rounds up.
minimum field width is 4, but no precision specified – 6 digits is default
Explicitly says 3 numerals after decimal point
14
int y = 25;
printf(“%d\n”, y);
printf(“%i\n”, y);
printf(“%4d\n”, y);
printf(“%1d\n”, y);
printf(“%05d\n”, y);
output:
25
25
25
00025
printf example
two spaces before two-digit value
minimum field width specified is too small to print the value of the data, so printf ignores it!
leading zeroes used to fill minimum field width
15
int day, month, year;
scanf(“%d/%d/%d”, &month, &day, &year);
Input:
01/29/13
Month has the value 1
Day has the value 29
Year has the value 13
The / characters are not saved.
Input:
111/222/2018
Month has the value 111
Day has the value 222
Year has the value 2018
The / characters are not saved.
int anInt;
scanf(“%i%%”, &anInt);
Input:
23%
anInt has the value 23
The % character is not saved.
Input:
152%
anInt has the value 152
The % character is not saved.
scanf examples
int int_1; long long_1;
scanf(“%d %ld”, &int_1, &long_1);
Input:
-23 200
int_1 has the value -23 /*stored as 4 bytes */
/*on stdlinux*/
long_1 has the value 200 /*stored as 8 bytes */
/*on stdlinux*/
double d;
scanf(“%lf”, &d);
Input:
3.14
d has the value 3.14 /*stored as 8 bytes */
/*on stdlinux*/
More scanf examples
IMPORTANT: scanf ignores leading (but not following) white space characters when it reads numeric values from input:
int i;
printf(“Enter an integer:\n”);
scanf(“%d”, &i);
/*scanf will ignore any leading white space characters */
More scanf examples
char string1[10]; /* IMPORTANT: string must hold 9 chars + null */
scanf(“%9s”, string1); /*array identifier is */ /*address of 1st element*/
Input:
VeryLongString
string1==“VeryLongS”
int int1;
scanf(“%*s %i”, &int1); /*read arbitrary length*/
/*string of non-numeric*/ /*chars before int1 */
Input:
Age: 29
int1 has the value 29
“Age: “ is not saved
NOTE: pressing the enter key causes characters that are being held in the input buffer to be transferred to standard in (stdin)
More scanf examples
int int1, int2;
scanf(“%2i”, &int1);
scanf(“%2i”, &int2);
Input:
2345
Then:
int1 has the value 23
int2 has the value 45
NOTE: pressing the enter key causes characters being held in the input buffer to be transferred to standard in (stdin)
More scanf examples
Scanf format examples
Letter Type of Matching Argument Auto-skip; Leading
White-Space Example Sample Matching Input
% % (a literal, matched but not converted or assigned) no int anInt;
scanf(“%i%%”, &anInt); 23%
d int yes int anInt; long l;
scanf(“%d %ld”, &anInt, &l); -23 200
i int yes int anInt;
scanf(“%i”, &anInt); 0x23
o unsigned int yes unsigned int aUInt;
scanf(“%o”, &aUInt); 023
u unsigned int yes unsigned int aUInt;
scanf(“%u”, &aUInt); 23
x unsigned int yes unsigned int aUInt;
scanf(“%x”, &aUInt); 1A
a, e, f, g float or double yes float f; double d;
scanf(“%f %lf”, &f, &d); 1.2 3.4
c char no char ch;
scanf(” %c”, &ch); Q
s array of char yes char s[30];
scanf(“%29s”, s); hello
n int no int x, cnt;
scanf(“X: %d%n”, &x, &cnt); X: 123 (cnt==6)
[ array of char no char s1[64], s2[64];
scanf(” %[^\n]”, s1);
scanf(“%[^\t] %[^\t]”, s1, s2);
Hello World
field1 field2
CSE 2421
The C Language – Part 3 – I/O
Required Reading:
Pointers on C, Section 15.4.2
In Unix/Linux, there are 3 file descriptors that are explicitly defined to represent 3 distinct data streams: stdin (0), stdout (1) and stderr(2).
IMPORTANT: By default, in Unix/Linux, C programs read input from “standard input (stdin)” (usually, the keyboard) and write output to “standard output (stdout)” (usually, the screen). Unix/Linux error messages go to “standard error” (stderr) (also the screen).
We can change the destination of each of these data streams from the Unix/Linux command line using what is called redirection:
< redirects the input, and
> redirects the output,
2> redirects errors
You can redirect just the input or just the output or just errors (that is, you do not have to redirect all of them, but you could).
For labs, from time to time it will be convenient to redirect input and allow output to go to standard out (the screen).
23
Redirection of stdin, stdout and stderr
It is important to make sure that the input file has an end of file (EOF) at the end. So, when you are creating/editing your input file, be sure you hit enter at the end of the last line of the file.
Example:
prog1 < prog1.input
This example runs program, prog1, and, rather than looking for input from the keyboard, gets its input from the file prog1.input
You used this mechanism within gdb when you did lab1
The file prog1.input is expected to be in the same directory in which prog1 is executing. The program will not look for the file anywhere else unless a full pathname is specified for the input file.
If you redirect stdin, the program will expect all input that it requires (until the program terminates) to come from the specified file (i.e. you can’t put part of the input to the program in a file and then when the data in the file runs out, input the rest of it from the command line).
Any output to stdout or any Unix/Linux errors messages to stderr would go to the screen.
24
Redirecting Standard input
Example 1:
% prog1 > output.file
This will run prog1 and write output to output.file
If output.file does not exist, it will create one.
If output.file does exist, any data currently in the file will be erased and only data from the most current run of prog1 will be in the file.
If you do not use a full pathname for the output file, it will only look for the file in the current directory
Example 2:
% prog1 >> output.file
This will run prog1 and write output to output.file
If output.file does not exist, it will create one.
If output.file does exist, output from the current run of the program will be appended to the end of the file.
If you use this option, be very careful not confuse yourself with respect to what output came from which execution of your program.
Both of these examples would expect input to come from the keyboard and any Unix/Linux errors would be sent to the screen
25
Redirecting standard output
In most instances, it’s not a good idea to redirect stderr, but from time to time…
Example 1:
% prog1 2> error.file
This will run prog1 and write any Unix/Linux error messages to error.file
If error.file does not exist, it will create one.
If error.file does exist, any data currently in the file will be erased and only error messages from the most current run of prog1 will be in the file.
If you do not use a full pathname for the error file, it will look for the file in the current directory
Example 2:
% prog1 2>> error.file
This will run prog1 and write any Unix/Linux errors to error.file
If error.file does not exist, it will create one.
If error.file does exist, output from the current run of the program will be appended to the end of the file.
If you use this option, be very careful not confuse yourself with respect to what errors came from which execution of your program. It would be sad to find out that you stayed up all night looking for an error you see in error.file that you fixed before midnight.
Both of these examples would expect input to come from the keyboard and stdout would be sent to the screen
26
Redirecting standard stderr
What if I want to redirect stdout and stderr to the same file?
prog1 > stdout.file 2>&1
Do
prog1 > stdout_stderr.file 2>&1
and
prog1 2>&1 >stdout_stderr.file
Do the same thing?? What does 2>&1 do???
Combinations
What if I want to redirect stdout and stderr to the same file?
prog1 > stdout.file 2>&1
Do
prog1 > stdout_stderr.file 2>&1
and
prog1 2>&1 >stdout_stderr.file
Do the same thing??
No! Order matters!
prog1 > /home/user/stdout_stderr.file 2>&1
This will send both stdout and stderr to stdout_stderr.file
prog1 2>&1 > stdout_stderr.file
This will send stdout to stdout_stderr.file, and stderr to what was previously stdout.
When you perform a shell redirection, the left side of the redirection goes to where the right side of the redirection currently goes. Meaning in 2>&1, it sends stderr (2) to wherever stdout (1) currently goes.
But if you, afterwards, redirect stdout somewhere else, stderr doesn’t go with it. It continues to go wherever stdout was previously going. This is why in the first example, both stdout and stderr will go to the same place, but in the second they won’t.
Combinations
For each of these examples, specify the destination of stdin, stdout and stderr (keyboard, screen, or a specific filename) based on the command line:
Redirection in-class exercise
Command Line Says stdin stdout stderr
1 hello >hello.out 2>hello.error
2 lab1 < lab1.input >lab1.output 2>lab1.error
3 lab2
5 lab4
6 lab4 > lab4.output 2>&1
7 prog1 2>&1 > prog1.output
For each of these examples, specify the destination of stdin, stdout and stderr (keyboard, screen, or a specific filename):
Redirection in-class exercise
Command Line Says stdin stdout stderr
1 hello >hello.out 2>hello.error keyboard hello.out hello.error
2 lab1 < lab1.input >lab1.output 2>lab1.error lab1.input lab1.output lab1.error
3 lab2
5 lab4
lab4.error
6 lab4 > lab4.output 2>&1 keyboard lab4.output lab4.output
7 prog1 2>&1 > prog1.output keyboard prog1.output screen
/docProps/thumbnail.jpeg