390 likes | 483 Views
Advanced UNIX. 240-491 Special Topics in Comp. Eng. 1 Semester 2, 2000-2001. Objectives of these slides: look in some detail at standard input and output in C. 9. Standard I/O in C. Overview. 1. Background 2. Formatted Output: printf() 3. Formatted Input: scanf()
E N D
Advanced UNIX 240-491 Special Topics in Comp. Eng. 1Semester 2, 2000-2001 • Objectives of these slides: • look in some detail at standard input and output in C 9. Standard I/O in C
Overview 1. Background 2. Formatted Output: printf() 3. Formatted Input: scanf() 4. Line I/O: gets(), puts() 5. Character I/O: getchar(), putchar()
1. Background • Most I/O library functions are in stdio.h • Basic methods: • 1. Formatted I/O • 2. Line by line • 3. Character by character
2. Formatted Output: printf() • int i = 2, j = 7;printf(“i = %d, j = %d\n”, i, j); • float, double printed with %f, %e, %g: double x = 3.14;printf(“%f, %e, %g\n”, x, x, x);3.140000, 3.140000e+00, 3.14 6 dp is the default
Character Strings • char name[SIZE], ch; :printf(“Hi, there, %s\n”, name);printf(“The letter is %c \n”, ch); See man ascii for some unusual chars, e.g. '\a' '\b' '\r'
Less Used printf() Format Specifiers • Specifier Meaning%% % character%u Decimal unsigned integer%o Octal integer%x Hexadecimal integer%p Pointer (decimal or hex)%n Store the number of chars written so far useful for printing unusual chars, see man ascii continued
Examples upper case hex letters • int i = 125, num;int *p = &i;printf(“%d, %o, %x, %X, %p%n\n”, i, i, i, i, p, &num);printf(“num = %d\n”, num);125, 175, 7d, 7D, 7fffbe48num = 31 the decimal is converted
Four Types of Format Modifiers printf(".....", x, y, z); 1. Flags • e.g. "%+d" 2. Field Widths • e.g. "%10d" 3. Precision • e.g. "%.4d" 4. Type Modifiers • e.g. "%ld" format string
2.1. Flags • Flag Meaning+ Prefix positive numbers with a + signspace Prefix positive numbers with a space0 Pad with leading zeros# Alternate output form
Examples • printf(“%+d\n%+d\n”, 786, -786);+786-786 • printf(“% d\n% d\n”, 547, -547); 547-547 • printf(“%+09d\n%09d\n”, 452, 452);+00000452000000452 useful for tidy columns
Meaning of # • Prefix 0 is added to octal output (%#o). • Prefix 0x or 0X is added to hexadecimal output (%#x or %#X). • %#e, %#f, %#g have a decimal point, even when there are no digits after it. • %#g does not remove trailing zeros.
# Examples • int c = 1427;float p = 1427.0;printf(“%#o, %#x, %#X, %g, %#g\n”, c, c, c, p, p);02623, 0x593, 0X593, 1427, 1427.00 hex do notremove '.' and 0's octal hex remove '.' and 0's
2.2. Field Widths • Specify minimum number of characters printed: • if too few characters, right justify output • if too many, ignore field width
Example char *s = “hello”;int x = 23;printf(“%10d%10s\n”, x, s);printf(“%-10d%-10s\n”, x, s); 23 hello23 hello width - = left justify 10 10
Field Width (*) in printf() • Calculate field width based on the next printf() argument: #define FIELD_WIDTH 10printf(“%*d\n”, FIELD_WIDTH, val); uses FIELD_WIDTH
2.3. Precision (.) in printf() • Specifier Effect%d Min. no. of digits (pad with leading zeros)%e, %f No. of digits after the decimal point%g No. of significant digits%s Min. no. of characters from a string
Example int i = 873;float f = 123.94536;char s[] = “Happy Birthday”;printf(“%.4d\n%.9d\n”, i, i);printf(“%.3f\n%.3e\n%.3g\n”, f, f, f);printf(“%.11s\n”, s);0873000000873123.9451.293e+02124Happy Birth
Meaning of *.* • Calculate field width and precision from the next arguments of the printf() printf(“%*.*s\n”, field_width, precision, str);
2.4. Type Modifiers • Place h or l before d, o, x, or u • Place L before e, f, or g • Letter Effecth Specify shorttypel Specify long typeL Specify long double type
3. Formatted Input: scanf() 23 2.3hi -5 62 • int i, x, y;float val;char str[100];scanf(“%d”, &i); /* read in integer */scanf(“%f”, &val); /* read in float */scanf(“%s”, str); /* read in string */scanf(“%d%d”, &x, &y); /* read space-separated integers */
Notes • %d will read a sign (e.g. -27) • %f will accept a float in fractional or exponential form (e.g. 2.3, 1.2e+02) • scanf() will ignore whitespace to get to a number • scanf("%d", &x); • whitespace includes new lines -27 continued
hello andy • %s only reads non-whitespace characters • scanf("%s %s", str1, str2); • skips whitespace to start of text • stops reading in text when it gets to a whitespace • adds ‘\0’ • the string variable (e.g. str1) must have enough memory continued
scanf("%d%d", &x, &y); same as • scanf(“%d”, &x);scanf(“%d”, &y);scanf() will read x and y values from the same line, or any distance apart, so long as the values are separated by whitespace. 27 13 continued
%c will read any character (even whitespace): scanf(“%c”, &ch); • Other characters in the scanf() format string are used for input matching: scanf(“%d-%d %d”, &x, &y, &z); 27-13 5 continued
scanf() leaves non-matching characters on the input stream scanf("%d", &x);scanf("%s", str); • scanf()returns the number of bound variables, or EOF at end-of-file. int num;num = scanf("%d %d", &x, &y); hello 27 13 continued
scanf() uses line buffering • when scanf() is reading from the keyboard, it only gets a line to process when a RETURN is pressed
3.1. Assignment Supression (*) int month, day, year;printf(“Enter date as mm-dd-yy: “);scanf(“%d%*c%d%*c%d”, &month, &day, &year);printf(“month = %d day = %d year = %d\n”, month, day, year);Enter date as mm-dd-yy: 11-18_97month = 11 day = 18 year = 97
3.2. Field Widths • A field width specifies the maximum number of input characters to process (ignoring whitespace before the start). • int x, y;scanf(“%2d%d”, &x, &y);printf(“Integers are: %d, %d\n”, x, y);123456Integers are: 12, 3456
3.3. Scan Sets [...] • Specify characters that can be read. • char z[9];printf(“Enter String: “);scanf(“%[aeiou]”, z);printf(“The input was \”%s\”\n”, z);Enter String: ooeeooahahThe input was “ooeeooa”
Inverted Scan Sets [^...] • Specify characters not to be read. • char z[9];printf(“Enter String: “);scanf(“%[^aeiou]”, z);printf(“The input was \”%s\”\n”, z);Enter String: PhreakThe input was “Phr”
3.4. Handling Incorrect Input • Things to remember: • scanf() returns when it sees a character that it does not want. It leaves the character on the input stream; • scanf()returns the number of variables it has bound continued
* supresses assign; [^\n] matches upto newline (whitespace) /* Try to read two integers */#include <stdio.h>int main(){ int i, j, count; do { printf(“Enter two integers: “);count = scanf(“%d %d, &i, &j); if (count < 2) { /* somthing wrong */ scanf(“%*[^\n]”); /* skip to end of line */ printf(“Incorrect. Try again: “); } } while (count < 2); /* until valid input */ :}
4. Line I/O • int puts(char *line); • e.g. puts(“Hello World”); • Adds a newline to its output. • If there is an error it returns EOF; If okay it returns a non-negative integer.
Bad style: avoid gets() • char *gets(char *line); • e.g: gets(str); • Reads to a newline in stdin; replaces newline by ‘\0’ in input argument • gets() returns a NULL when EOF or an error occurs. • Main problem: gets() may read in a bigger string than can be stored in the variable; use fgets() instead.
char *fgets(char *line, int n, FILE *stream); • e.g: fgets(str, 80, stdin); • Reads at most n-1 chars into line, stopping if a newline is encountered; • the newline is included in line, and a ‘\0’ is added • fgets() returns a NULL when EOF or an error occurs.
sscanf() Very useful for separating reading from processing in code. • int sscanf(char *s, const char *format, ...); • Same as scanf() but its input comes from the string argument (s) not from stdin.
Read then Process • #include <stdio.h>int main(){ char str[120]; /* magic number: poor style! */ int i, j; while (fgets(str,120,stdin) != NULL) { /* read */ /* process */ if (sscanf(str, “%d %d”, &i, &j) == 2) printf(“i = %d j = %d\n”, i, j); else if (sscanf(str, “%d”, &i) == 1) printf(“i = %d j = ??\n”, i); else printf(“Could not understand anything!\n”); :}
5. Character I/O • int putchar(int c); • e.g.:putchar(‘\n’); putchar(32); • int getchar(void); • e.g.: int ch; ch = getchar(); while ((ch = getchar()) != EOF) ... Remember the brackets.
Cannot “Press any key” #include <stdio.h>int main(){ char ch; printf(“Press any key to go on...”); ch = getchar(); /* type conversion */ printf(“You pressed ‘%c’\n”, ch); :} • Problem: UNIX line buffering • Quick fix: say “Press RETURN”