int getchar(void); int putchar(int);and about redirection of standard input and output.
It is also possible to take the standard output of one program and
make it the standard input of another.
This is called piping or using a pipe.
Example:
ls | sort -rWill list your directory sorted in reverse order.
ls -l | sort -n +4Will give a long listing sorted by file size.
int printf(const char *format, arg1, arg2, arg3, ...);The first parameter is a string which contains ordinary characters and conversion specifications. The ordinary characters are just sent to standard output and the conversion specifications cause some form of conversion.
Each conversion specification begins with % and ends with a conversion character. You are familiar with some of the conversion characters: c, s, d, etc.
Example:
printf("This is the value of x:%d\n",x);Some format specifications can contain alignment information, field width or a precision.
These must be in the following order if they appear:
Here are the ones you must know about:
man -s3S printfExample: Consider "hello world" printed with the following format specifications:
:%s: :hello, world: :%10s: :hello, world: :%.10s: :hello, wor: :%-10s: :hello, world: :%15s: : hello, world: :%.15s: :hello, world: :%-15s: :hello, world : :%15.10s: : hello, wor: :%-15.10s: :hello, wor :Here is an example of using the * as a filed width:
void printTree(int vals[], int size) { int currentsize = 40; int numperline = 1; int perlinecount = 0; int i; printf("\n"); if (size <= 0) return; for (i=0;i<size;i++) { if (perlinecount > 0) printf("%*s",currentsize,""); printf("%*d",currentsize,vals[i]); perlinecount++; if (perlinecount == numperline) { perlinecount = 0; numperline *= 2; currentsize /= 2; printf("\n"); } } printf("\n"); }You can output to a string rather than standard output with
int sprintf(char *string, char *format, arg1, arg2, ...);You must make sure that enough space has been allocated for the output.
Both printf and sprintf return the number of bytes transmitted (not including the string terminator in the case of sprintf).
It skips over white space in the input.
Blanks and tabs are ignored in the format string.
int scanf(char *format, arg1, arg2, ...);Note that since we are setting values, the args need to be pointers.
It returns the number of items matched or EOF if input ends before the first match.
Note that the f format specifier is for floats, not doubles.
To input a double you need to use lf.
Find as many errors as you can in the following:
Example: read in two integers, a double and a string:
int n,m; double x; char *s; scanf("%d%d%f%s",n,m,x,s);
int n,m; double x; char s[100]; scanf("%d%d%lf%s",&n,&m,&x,s);
In C, a file pointer is a pointer to a structure of type FILE.
We are not concerned with the internal structure of this data type.
To create a file pointer from a file name, use the fopen function:
FILE *fopen(char *name, char *mode)The first parameter is the name of the file.
The second parameter is a short string that describes what you want to
do with the file.
Here are the most-used options:
On some systems (not Unix) you need to also specify b as part of the mode string for binary files.
There are version of some of the functions we already know about that can be used for file I/O:
int getchar(void) | int getc(FILE *fp) |
int putchar(int c) | int putc(int c, FILE *fp) |
int printf(char *format, ...) | int fprintf(FILE *fp, char *format, ...) |
int scanf(char *format, ...) | int fscanf(FILE *fp, char *format, ...) |
You can use these new ones to do I/O to standard input and standard output without fopen by using the predefined file pointers stdin and stdout.
In fact, in some systems we have:
#define getchar() getc(stdin) #define putchar(c) putc((c),stdout)with similar definitions for printf and scanf.
There is also another predefined file pointer called stderr.
When you are done with file I/O you should close the corresponding file with
int fclose(FILE *fp):This is automatically done when you do a return from main.
Example: concatenating files
The Unix command cat can take any number of command line parameters
which are names of files.
The files are sent to standard output in the order
they appear on the command line.
If no command line parameters are given, the input comes from standard input.
Example:
cat file1 file2 file3 > file4
Here is a simple version of cat
#include <stdio.h> main (int argc, char *argv[]) { FILE *fp; void filecopy(FILE *, FILE *); if (argc == 1) filecopy(stdin,stdout); else while (--argc > 0) if ( (fp = fopen(*++argv, "r")) == NULL) { printf("cat: can't open %s\n",*argv); return 1; } else { filecopy(fp,stdout); fclose(fp); } return 0; } void filecopy(FILE *ifd, FILE *ofd) { int c; while (c=getc(ifp) != EOF) putc(c, ofp); }One of the problems with this version is that if you redirect the output you never see the output.
Another useful function is
int ferror(FILE *fp);which returns true if an error has previously occurred reading or writing to the named file pointer.
Here is another version of out cat
main (int argc, char *argv[]) { FILE *fp; void filecopy(FILE *, FILE *); char *prog = argv[0]; if (argc == 1) filecopy(stdin,stdout); else while (--argc > 0) if ( (fp = fopen(*++argv, "r")) == NULL) { fprintf(stderr,"%s: can't open %s\n",prog,*argv); return 1; } else { filecopy(fp,stdout); fclose(fp); } if (ferror(stdout)) { fprintf(stderr,"%s: error writing stdout\n",prog); return 2; } return 0; }
Another useful function is exit which exits your program. This can be called from a function other than main.
In general you should avoid doing this unless absolutely necessary.
When called from main, exit(expr) does exactly the same thing as return expr.
strcat(s,t) strncat(s,t,n) strcmp(s,t) strncmp(s,t,n) strcpy(s,t) strncpy(s,t,n) strlen(s) strchr(s,c) return a pointer to the first c in s or NULL strrchr(s,c) return a pointer to the last c in s or NULLOther useful functions
int atoi(const char *str); double atof(const char *str);
Mathematical Functions
These are defined in math.h and you will need to add -lm
to the end of your compile line.
All take double parameters and return double:
sin(x) cod(x) atan2(y,x) exp(x) log(x) log10(x) pow(x,y) sqrt(x) fabs(x)
Practice with doubly linked lists:
typedef struct nodeentry { stringval sval; struct nodeentry *next; struct nodeentry *prev; } nodeentry; typedef struct { nodeentry *front; nodeentry *rear; } doublelist;static doublelist q;
int insert_after(stringval sval, nodeentry *nentryp); int insert_before(stringval sval, nodeentry *nentryp); stringval remove(nodeentry *nentryp);