Unix: Programming with Standard I/O

Download Report

Transcript Unix: Programming with Standard I/O

Programming with Standard I/O
CSRU3130, Spring 2008
Ellen Zhang
Last Class
• Midterm questions review
– Command line arguments, standard
input/output/error
– Solutions will be posted soon
• C Programming vs C++ Programming
– No classes or objects
– Doesn’t support function overloading
– Different standard I/O
– Different string operations
Today
•
•
•
•
A script a day
First C program: reverse
Second C program: vis
Programming with standard I/O
A script a day
#!/bin/bash
PATH=/bin:/usr/bin
case $# in
0) echo “Usage: watchfor person’ 1>&2; exit 1
esac
until who | egrep “$1”
do
sleep 60
done
Change file suffix
#!/bin/bash
for i in `ls *.cpp`
do
#old way: mv $i `basename $i .cpp`.cc
mv $i ${i/%.cpp/.cc}
done
Variable expansion / Substring replacement
${var/%Pattern/Replacement}
If suffix of $var matches Pattern, then substitute
Replacement for Pattern
A script a day: overwrite
• To replace UNIX with UNIX(TM) in a file called
ch2:
– How about: sed ‘s/UNIX/UNIX(TM)/g’ ch2 > ch2
• A general solution ?
– A script “overwrite” that save standard input to a
file
– sed ‘s/UNIX/UNIX(TM)/g’ ch2 | overwrite ch2
– sort –k 3 –n data.txt | overwrite data.txt
A script a day: overwrite
#!/bin/bash
PATH=/bin:/usr/bin
case $# in
1) ;;
*) echo “Usage: overwrite file’ 1>&2; exit 2;;
esac
new=/tmp/overwr.$$
cat >$new
cp $new $1
rm –f $new
A Real C Program
• reverse: accepts one command line argument
– Treats the argument as a string, and reverses the
letters in the string, prints out the reversed string
– For example
$ ./reverse apple
elppa
$./reverse spring_song
gons_gnirps
$./reverse Hello world
olleH
8
Handling strings in C
• A “string” is an array of characters, terminated
with null character (‘\0’)
– The array can be statically or dynamically allocated
• E.x. char myStr[10]=“Hello”;
– Asking for a statically allocated array of characters
of size 10, with myStr pointing to first element of
the array
– Initialize the array with string “hello”
9
Visualize memory
• Memory diagram: a way to visualize how
variable is maintained in RAM
1. int num=10;
num
2. int * p=NULL;
p
3. int * p=#
p
4. int nArray[20];
10
\
num
10
nArray
20
10
Handling strings in C
• Now our string
– char myStr[10]=“Hello”;
myStr
H
e
l
l
o
\0
– myStr[0]=‘H’; or equivalently, *myStr = ‘H’;
– myStr[1]=‘e’; or, *(myStr+1)=‘e’;
– myStr[2]=‘l’; or, *(myStr+2)=‘l’;
11
Handling strings in C
• char myStr[10]=“Hello”;
H
e
l
l
o
\0
• Library functions for operations on string:
– strcpy, strlen, strtok, strcat, …
– All using the ‘\0’ to tell where a string ends …
• Examples
– strcat (myStr, “!”);// append ! To the last non-null char
– str_len = strlen (myStr);
– str_len is set to 5, the actual length of the string, not the
size of the array
12
reverse.c (1)
#include <stdio.h> /* printf */
#include <stdlib.h> /* malloc, free */
/* MAX is the size of largest string we can handle */
#define MAX 1000
typedef char bigstring[MAX];
13
reverse.c (2)
/* reverses a string in place
returns a pointer to the string */
char * reverse (char * s){
bigstring buf;
int i, len;
len = strlen (s); // fine the length of the string
for (i=0;i<len;i++)
buf[i] = s[len-i-1];
buf[i] = ‘\0’; // null terminate !
strcpy (s,buf);
// put back to s
return (s);
}
14
reverse.c (3)
void main (int argc, char ** argv) {
if (argc<2){
printf (“Invalid usage: must supply a string\n”0;
exit(1);
}
printf (“%s\n”,reverse (argv[1]));
}
Make sense of char ** argv, draw the memory diagram
15
Compiling on Unix
• We can use GNU compiler named gcc
• gcc –o reverse reverse.cc
Tells compiler to
create executable file with the
name reverse
Tells compiler the name of input
file
16
Running the program
$ ./reverse hidave
Evadih
$ ./reverse This is a long string
sihT
$./reverse “This is a long string”
Gnirts gnol a si sihT
17
Exercise
• Implement our own int mystrlen(char * s)
function
• Implement our own strcpy:
– char * mystrcpy (char *src, char * dest)
C: Standard I/O Libraries
• Standard I/O library: a collection of routines
that provide efficient and portable I/O and
system services
– getchar, putchar
– printf, scanf, fopen, fread …
19
What’s inside a file ?
• For example, how is the following script saved ?
#!/bin/bash
for i in `ls *.cpp`
do
#mv $i `basename $i .cpp`.cc
mv $i ${i/%.cpp/.cc}
done
Octal Dump
• “wc” command tells us the file has 93 characters
• Octal dump command: od
– -c option: interpret bytes as characters
[zhang@storm Demo]$ od -c changefile
0000000 # ! / b i n / b a s h
0000020
i
i n
` l s
* .
0000040 \n d o \n \t # m v
$
0000060 e n a m e
$ i
. c
0000100 c \n \t m v
$ i
$ {
0000120 p p / . c c } \n d o n
0000135
Positions in the file (base 8)
\n \n f o r
c p p `
i
` b a s
p p ` . c
i / % . c
e \n
everything is binary numbers
• Remember that everything (numbers, characters)
in computer is a stream of 0’s and 1’s
– In register, RAM, disk, CD, tape, …
• How to represent character in numbers ?
– An encoding scheme is needed
– ASCII (American Standard Code for Information
Interchange) codes represent text in computers,
communications equipment, and other devices that
work with text.
ASCII code excerpt
Decimal Octal Hex Binary
Value
------- ----- --- ------ -------------------------------000 000 000 00000000 NUL (Null char.)
001 001 001 00000001 SOH (Start of Header)
007 007 007 00000111
BEL (Bell)
008 010 008 00001000
BS (Backspace)
009 011 009 00001001
HT (Horizontal Tab)
010 012 00A 00001010
LF (Line Feed)
011 013 00B 00001011
VT (Vertical Tab)
012 014 00C 00001100 FF (Form Feed)
013 015 00D 00001101 CR (Carriage Return)
ASCII code excerpt
Decimal Octal Hex Binary Value
------- ----- --- ------ -------------------------------062 076 03E 00111110 > (greater than)
063 077 03F 00111111 ? (question mark)
064 100 040 01000000 @ (AT symbol)
065 101 041 01000001 A
066 102 042 01000010 B
067 103 043 01000011 C
068 104 044 01000100 D
069 105 045 01000101 E
070 106 046 01000110 F
Octal Dump
• od –cb changefile : show the bytes as octal (base 8) number
as well
[zhang@storm Demo]$ od -cb changefile
0000000 # ! / b i n / b a s h \n \n f o r
043 041 057 142 151 156 057 142 141 163 150 012 012 146 157 162
0000020
i
i n
` l s
* . c p p `
040 151 040 151 156 040 140 154 163 040 052 056 143 160 160 140
0000040 \n d o \n \t # m v
$ i
` b a s
012 144 157 012 011 043 155 166 040 044 151 040 140 142 141 163
0000060 e n a m e
$ i
. c p p ` . c
145 156 141 155 145 040 044 151 040 056 143 160 160 140 056 143
0000100 c \n \t m v
$ i
$ { i / % . c
143 012 011 155 166 040 044 151 040 044 173 151 057 045 056 143
0000120 p p / . c c } \n d o n e \n
160 160 057 056 143 143 175 012 144 157 156 145 012
0000135
Our observations
• Unix uses newline (a special character) to
terminate a line
– In your editor, you hit “Enter” key to insert a
newline into the file
• No special character for “end of file”
– The file just stops
– System simply says there is no more data in the
file
• e.g. more details later
C: Standard I/O Libraries
• Standard I/O library: a collection of routines
that provide efficient and portable I/O and
system services
• Today: read/write to standard input/output
– getchar, putchar
– printf, scanf
27
A simple C program
• vis:
– copies its standard input to its standard output
– makes all non-printing characters visible by
printing them as \nnn, where nnn is the octal
value of the character.
• Normal file viewing commands
– Do not display non-printing characters
• Note: useful for checking if there are some
weird characters in the file
Simplest I/O routines
• char * getchar():
– Gets/returns the next character from the standard
input
– Return EOF when it encounters end of file (or
error)
• putchar (c):
– Puts the character c on the standard output
vis program
#include <stdio.h>
#include <ctype.h>
main()
{
int c;
while ((c=getchar()) !=EOF)
if (isascii(c) && (isprint(c) || c==‘\n’ || c==‘\t’ || c==‘ ‘))
putchar (c);
else
printf (“\\%03o”,c);
exit(0);
}
Character test macros
•
•
•
•
•
•
•
Defined in /usr/include/ctype.h
isascii(c): whether c is an ascii code
isalpha(c): alphabetic a-z, A-Z
isdigit(c): digit: 0-9
ispunct(c):
isprint(c): printable
…
Quick I/O Primer: printf
int printf (const char *, … );
• Write strings, integers, doubles, etc to standard
output, perform format conversion
• e.g., write i=10 as “10”; d=10.23 as “10.230” …
• … means “variable number of arguments”, the
first argument is required (a string).
32
Simple printf
• Given a simple string, printf just prints the
string (to standard output).
printf (“Hi – I am a string\n”);
printf (“I\thave\ttabs\n”);
char s[100];
strcpy(s, “printf is fun!\a\n”);
printf (s);
33
Escape sequence in C
\' Single quote
\" Double quote
\\ Backslash
\nnn Octal number (nnn), \xnnn Hexadecimal number (nnn)
\0 Null character (really just the octal number zero)
\a Audible bell
\b Backspace
\f Formfeed
\n Newline
\r Carriage return
\t Horizontal tab
Doing more with printf
• You can tell printf to embed some variables’
values in the string
• Example:
– printf (“here is an integer: %d\n”, i);
– printf(“\\%03o”,c);
• %o means: prints the parameter, c, as octal
numbers
35
More integer arguments
printf (“%d + %d = %d\n”, x, y, x+y);
for (j=99;j>=0;j--)
printf (%d bottles of beer on the wall\n”,j);
printf (“%d is my favorite number\n”, 17);
36
printf is dumb
• %d is replaced by the value of the parameter when
treated as an integer, even if the parameter is not
an integer variable
– printf (“print an int %d\n”, “Hi Dave”);
• print an int 134513980
– printf ("print an int %d\n",12.3);
• print an int -1717986918
– printf ("print chars as unsigned int %u %u %u\n",'a','b','c');
• print chars as unsigned int 97 98 99
37
Other formatting tags
• printf : formatting tag
– %[flags][width][.precision][length]specifier
• Specifiers:
–
–
–
–
–
–
–
d: treat the corresponding parameter as a signed integer
u means unsigned integer
x means print as hexadecimal
s means treat it as a string
c is for character (char)
f is for floating point numbers
…
38
Controlling the output
• printf : formatting tag
– %[flags][width][.precision][length]specifier
• Width:
– A number specifying the width of the output (left padding with
space if needed)
• Flags:
– 0: means left padding the output with 0; default is space
• Precision:
– the number of digits after decimal points
• Example:
– printf (“square root of 10 is %20.15f\n”,sqrt(10);
square root of 10 is
3.162277660168380
39
Fun with printf
• printf(“\\%03o”,’>’);
– print ‘>’ as octal number of 3 character long, left padding with 0
– 076
• char * s = “Hi Dave”;
• printf (“the string \”%s\” is %d characters long\n”, s,
strlen(s));
• printf (“The square root of 10 is %f\n”,sqrt (10));
40
Lining things up
int i;
for (i=0; i<5; i++)
printf (“%2d %f %20.15f\n”,I, sqrt(i),sqrt(i));
• 1 1.000000 1.000000000000000
• 2 1.414214 1.414213562376095
• …..
41
Before we move on
• There are more formats and format options
for printf
• The man page for printf includes a complete
description
• man 3 printf
42
Reading from standard Input - scanf
•
•
•
•
•
scanf provides input from standard input
scanf use pointers, or addresses
Every C variable is stored in memory
Every memory location has an address
In C, you can use variables called pointers to refer to
variables by their address in memory
– int x;
– int * p;
– p=&x;
43
scanf
• int scanf (const char * format, … );
– Remember “…” means “variable number of
arguments”
– Uses format string to determine what kind of
variable(s) it should read
– The arguments are the addresses of the variables,
i.e., pointers pointing to variables
• Example: scanf (%d %d”,&x,&y);
– x,y should be two integer variables
44
A simple example of scanf
float x;
printf (“Enter a number\n”);
scanf (“%f”,&x);
f stands for “floating point” (similar to printf)
printf (“Square root of %f is %f\n”,x,sqrt(x));
45
scanf and strings
• Using %s in a scanf tells scanf to read
the next word from input – not a line
of input
char s[100];
printf (“Type in your name\n”);
scanf (“%s”,&s);
printf (“Your name is %s\n”,s);
46
Reading a line
• You can use function fgets to read an entire line
• char *fgets (char *s, int size, FILE * stream);
– size is the maximum # of chars
– FILE is a file handle, for now, remember
• stdin (a constant): standard input
– Read a line (i.e., read character until newline is met or until
reach maximum #) from specified file, and save to the
string pointed to by s
47
Example of fgets
char s[101];
printf (“Type in your name\n”);
fgets (s,100,stdin);
printf (“Your name is %s\n”,s);
48
Exercise
• Write a C program:
– That asks user to input two integer values
– Prints out the sum of the two values
Next class
•
•
•
•
More on scanf
File access library calls
GCC compiler chain
Introduction to gdb