260 likes | 374 Views
Lecture. Starting K&R Chapter 7 and Appendix B Also, UNIX – Various chapters in Glass. Standard Library Functions. Standard library functions in K&R Appendix B On line, you can get documentation about them under the corresponding header files:
E N D
Lecture • Starting K&R Chapter 7 and Appendix B • Also, UNIX – Various chapters in Glass
Standard Library Functions • Standard library functions in K&R Appendix B • On line, you can get documentation about them under the corresponding header files: http://www.digitalmars.com/rtl/stdio.html • On UNIX, use grep to find them in the .h files, e.g. % grep strcmp /usr/include/* • You can get details of them using the man command, e.g. % man printf
UNIX grep, Glass Pg 109+ • UNIX command “grep” finds matches for a specified string in identified filenames • If no filenames present, grep searches stdin • Some options in grep: -i ignore case (“TEXT” same as “text”) -n adds line numbers to display -v gives only lines that don’t match -w only matches complete words
UNIX “Pipes”, Glass Pg 175+ • Remember redirection for sysin and sysout? % command <filename1 >filename2 • In general, you can invoke a program and pass sysout from that program as sysin to another program via UNIX pipe – symbol | % command1 arguments | command2 arguments % grep pattern filename(s) | more
Standard Input /Output, 7.1 • C code for reading stdin char getchar (void) gets a character from stdin • C code for writing to stdout void putchar(char) puts a character to stdout • stdin and stdout can be redirected or piped % ./tail <tail.in | more % cat filename1 | ./tail >filename2
Formatted Output, printf, K&R 7.2 • Formats and prints out internal values. int printf(char *format, arg1, arg2, . . .); • printf has a variable length argument list (as many arguments after the first one as % conversions in the format string) • We will learn how to do this shortly • Return from printf is number of characters printed • Haven't used this up till now, but it may be useful if there is some error or limit truncation
Formatted Output, printf • Between the % and the conversion character, there are a number of other characters which may exist. In the order they must be placed, they are: - (minus sign) left adjust printing of argument m (number m) minimum field width . (dot) separates min field width & precision p (integer p) precision: max chars for string min digits for int h or l (letters) h for short int, l for long int • ORDER of options for %d is: %[-][m][.][p][h|l]d, Note: No embedded spaces allowed!
Formatted Output, printf • Figure out what these would do: %10d, %-10d, %hd, %e, %10ld, %10.p • Experiment for 10 minutes with a program, using different formats • Learn string precision given on pg. 154 • Also, to print at most max characters from string s (max is int type var or const), use * after % and include the int max as an argument before s: printf("%.*s", max, s);
Formatted Output, printf • Can print string literal as format string with no “%s” printf("hello, world!\n"); • Could also print a string variable as format string: char s[ ] = "hello, world"; printf(s); • If string s has a % character in it, this is unsafe! • printf will look for another argument after format string s. Better to write out a variable string s as: printf("%s", s);
Formatted Output, sprintf • See sprintf in K&R Appendix B, pg 245 • Function sprintf works same as printf, but it writes to a specified string, e.g. char array[ ], with trailing ‘\0’ int sprintf(char *string, char *format, arg1, arg2, …); • Note: int return value does not include trailing ‘\0’ • Recall how we wrote itoa() and itox() functions • No functions like this in C library! • Use sprintf() to print int into a string using %d or %x
Formatted Input, scanf • This is the opposite of printf. Reads in variables from stdin using conversion format string. See pg. 246 (and prior pg 245 which explains everything). int scanf(char *format, …); • Return value from scanf( ) is number of successfully scanned tokens • Not successful if scanf can't parse any value brought in from stdin according to the specified format
Formatted Input, scanf • Must call scanf with a POINTER to each variable so that values can be set by scanf which is a function! int age, weight, cnt; char lname[100]; while(some condition) { printf("Input your last name, age, and weight"); cnt = scanf("%s %d %d", lname, &age, &weight); } • Note: lname is an array and is already a pointer
Formatted Input, scanf • Scanf is useful to allow you to read in int or double value AS A NUMBER (instead of a character string leaving you to do your own conversion in your code) • scanf() always see a character sequence in stdin: it just does its own conversion to int or double
Formatted Input, scanf • However, scanf is FLAWED, because it ignores '\n' characters. • Can get very confusing if the user enters too few arguments on an input line being parsed by scanf • (Prompt) Input your last name, age, and weight: • (User input) Clinton 52 • User gets no response after carriage return. • User retries, remembers to enter weight this time • (User input) Clinton 52 200
Formatted Input, scanf • scanf sees Clinton 52 Clinton since the user entered carriage return is seen as white space • scanf thinks weight has bad value and returns 2 as number of successfully scanned tokens • scanf has gotten out of synch with input process • Re-entered 52 will be seen as a last name and 200 as an age in next prompt/scanf loop
Formatted Input, scanf • Use scanf only for programs needing only ONE input item, usually "quick and dirty" programs with no input checking. • Can't code defensively with scanf( ): can't count number of tokens parsed ON A LINE - scanf doesn't care about input lines • Best approach is to read a line into an array s[ ] and use "sscanf( )" to parse the arguments in line • This also allows you to try to interpret things in more than one way
Formatted Input, sscanf • See sscanf in K&R Appendix B, pg 246 • Function sscanf works same as scanf, but it reads from a specified string, e.g. char array[ ], with a trailing ‘\0’ int sscanf(char *string, char *format, &arg1, &arg2, …); • Recall how we wrote function atoi, axtoi to convert a decimal or hex character string s to an integer i? • Use sscanf(s, "%d", &i) for atoi • Use sscanf(s, "%x", &i) for axtoi
Formatted Input, scanf/sscanf • Note: with both scanf and sscanf, if you put specific characters in the format string, the functions must see exactly those specific characters in the user input cnt = sscanf(s, "%d/%d/%d", &month, &day, &year); • Expects input to look exactly like this: 07/23/96 • If not, cnt value returned by sscanf is less than 3
Variable Length Argument Lists • Both printf and scanf have an argument (the format string) that defines the number and type of the remaining arguments in the list • C does not support multiple declarations of the same function each with different lists • How is it supported in C? • Look at stack frame after a function call!
Typical Stack frame Stack Pointer After Call Decreasing Addresses Stack Pointer Before Call A r g 1 A r g 2 A r g 3 Function’s Automatic Variables Return Data e.g.PC, other Registers, etc Code provides the location of the last fixed argument in call sequence to va_start Address 0xffffffff From fixed arguments, the code must determine the number of additional arguments to access via offsets from stack pointer and va_arg can work its way back up the stack to get each argument
Variable Length Argument Lists • Use va_list data type and va_ macro package inside function with a variable length argument list to get args • va_start, va_arg, va_end macros are defined in /usr/include/stdarg.h void foo (int n, …) /* note ellipsis … */ { va_list ap; /* variable name ap */ va_start(ap, n); /* n is last named arg */ • Now ap points just before first unnamed arg
Variable Length Argument Lists • Each call to va_arg( ) advances pointer ap by one argument and returns value by type: ival = va_arg(ap, int); fval = va_arg(ap, float); sval = va_arg(ap, char *); • Function must clean up before returning: va_end(ap); }
More examples • Go over the minprintf(char *fmt, …) in K&R p.156
minprintf Program Listing (page 1) /* minprintf program in K&H P.156 */ #include <stdio.h> #include <stdarg.h> void minprintf(char *fmt,...); int main() { int count =5; char * ptr= "life"; minprintf("%s...%d times\n", ptr, count); return 0; }
void minprintf(char *fmt,...) { va_list ap; char *p, *sval; int ival; double dval; va_start(ap, fmt); for (p = fmt; *p; p++){ if (*p != '%'){ putchar(*p); continue; } minprintf Program Listing (page 2)
minprintf Program Listing (page 3) switch(*++p){ case 'd': ival=va_arg(ap, int); printf("%d", ival); break; case 'f': dval=va_arg(ap,double); printf("%f", dval); break; case 's': for (sval = va_arg(ap, char*); *sval; sval++) putchar(*sval); break; default: putchar(*p); break; } } va_end(ap); }