Size: 5743
Comment:
|
Size: 5723
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 137: | Line 137: |
=== Program output and error messages === | === 3. A file === A program can open and close, and read from, and write to, a file that is 'internally' defined. This is generally done when you have large volumes of stored data, or complex data or non-printable data. * these rarely happen in this course == Program output == |
Line 177: | Line 184: |
=== 3. A file === A program can open and close, and read from and write to, a file that is 'internally' defined. This is generally done when you have large volumes of stored data, or complex data or non-printable data. * these rarely happen in this course |
Contents
C I/O
Program input
There are 3 main sources of input for programs:
- from the command line
you get access to data on the command line by using argc and argv[][]
from standard input (also called stdin)
stdin can be the keyboard, a data file, or the output of another program
- from an 'internally-defined' file
open a file, use fscanf(), and don't forget to close the file
1. command line
To read from the command line:
include argc and argv in your parameter list for main().
use sscanf() to read the arguments (it stands for 'string scanf()')
the first argument of a sscanf() is a string
Here is a program that counts from 1 to num, where num is provided by the user on the command line
1 // countc.c
2 // reads an integer from the command line and counts
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 int main(int argc, char *argv[]) {
7 int num = 0;
8 if (argc < 2 || sscanf(argv[1], "%d", &num) != 1) { // num is defined here
9 fprintf(stderr,"Usage: %s integer\n", argv[0]);
10 return EXIT_FAILURE;
11 }
12 for (int i=1; i<=num; i++) {
13 printf("%d ", i);
14 }
15 printf("\n");
16 return EXIT_SUCCESS;
17 }
Notice the program prints a 'Usage' message if an integer argument is missing (discussed in next session)
To execute the program:
prompt$ dcc -o countc countc.c prompt$ ./count Usage: ./count integer prompt$ ./count !t#q Usage: ./count integer prompt$ ./count 10 1 2 3 4 5 6 7 8 9 10
2. standard input
To read from standard input (usually called simply stdin)
a scanf() is used (instead of sscanf())
a scanf() misses the string argument of a sscanf()
so where does num comes from?
... the default 'channel' stdin
1 //counts.c
2 // reads an integer from stdin and counts
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 int main(void) {
7 int num;
8 if (scanf("%d", &num) != 1) {
9 fprintf(stderr, "Usage: a number expected\n");
10 return EXIT_FAILURE;
11 }
12 // the rest of the program is exactly the same as the command-line version
13 for (int i=1; i<=num; i++) {
14 printf("%d ",i);
15 }
16 printf("\n");
17 return EXIT_SUCCESS;
18 }
Notice the Usage message this time is simpler than the command-line version above
... because we did not declare argc and argv, and so cannot use argv[0] this time!!
- we could have if we wanted to of course
There are many ways to 'test' a program that reads stdin.
- Using the keyboard
prompt$ dcc -o counts counts.c prompt$ ./counts 10 1 2 3 4 5 6 7 8 9 10
where the integer 10 was typed on the keyboard by the user, and the program generates the count from 1 to 10.
Using a data file, input.txt say, which contains the integer 10 (followed by a newline).
prompt$ more input.txt 10 prompt$ ./counts < input.txt 1 2 3 4 5 6 7 8 9 10
Using a pipe command. A pipe command joins the stdout of a program to the stdin of another program. If we have a program called write10.c:
then we can pipe its stdout to the stdin of our counting program
prompt$ dcc -o write10 write10.c prompt$ dcc -o counts counts.c prompt$ ./write10 | ./counts 1 2 3 4 5 6 7 8 9 10
But you can actually generate a string much more easily in UNIX using echo
prompt$ echo "10" | ./counts 1 2 3 4 5 6 7 8 9 10
3. A file
A program can open and close, and read from, and write to, a file that is 'internally' defined.
This is generally done when you have large volumes of stored data, or complex data or non-printable data.
- these rarely happen in this course
Program output
There are two standard output 'channels', standard output stdout and standard error stderr.
- both are normally defined as the screen
printf() writes to stdout, hence the screen
fprintf(), which stands for file-printf, writes to a file, which could be stderr' for example, in you could argue over whether it should go to There is convention here: standard input is from a string is s standard output is to a file is f Like (where the integer 10 is input by the user) will result in the count from 1 to 10 going to the file The following does the same thing: This also does the same thing:
The vast majority of program can be written just using these i/o system calls -
countc.c the 'Usage' message went to stderr: 1 fprintf(stderr,"Usage: %s integer\n", argv[0]);
stderr (hence be just a printf)
scanf(),
scanf(), and it has an 'extra' first argument that is a string
printf(), and it has an 'extra' first argument that is a 'channel' (file) dcc -o counts counts.c
./counts > output.txt
10
./counts < input.txt > output.txt
echo "10" | ./counts > output.txt
Input/output design considerations
scanf() to read from stdin - sscanf() to read from the command line - printf() to write to stdout - fprintf() to write to stderr