***Some of you will need to use the first 4 or 5 letters of your last name. Try first 3, then 4, and then 5***
stu@riely373:~$ passwdNote: The Linux box is for classwork only. All files on this machine may be read by The Prof.
Changing password for stu.
(current) UNIX password:
Enter new UNIX password:
Retype new UNIX password:
Command: pwd
Description: Print Working Directory; i.e., display the name of the current directory.
Example:
stu@riely373:~$ pwdThis directory is the home directory of user stu
/home/stu
Command: ls
Arguments: Optional list of files and or directory namesOptions: -l
Description: Lists the specified files and or directories. For a directory, all its files and directories are listed. If no file or directory is specified, the current directory is assumed.
Example:stu@riely373:~$ ls
stu@riely373:~$ ls .
stu@riely373:~$ ls ..
alg bia che dav fen hei kur mei nys sal she tra
alz bro chi dem ghan hes liu mil pan sch stu van
any cham cho elm ghar jiw mac mon prof sci tay wil
ath chan dan fai gie kru mcc nak rob sha tho
stu@riely373:~$ ls -l ..
total 188
drwx------ 2 alg alg 4096 2013-09-16 10:53 alg
drwx------ 2 alz alz 4096 2013-09-16 10:53 alz
drwx------ 2 any any 4096 2013-09-16 10:53 any
drwx------ 2 ath ath 4096 2013-09-16 10:53 ath
drwx------ 2 bia bia 4096 2013-09-16 10:53 bia
drwx------ 2 bro bro 4096 2013-09-16 10:53 bro
drwx------ 2 cham cham 4096 2013-09-16 10:53 cham
drwx------ 2 chan chan 4096 2013-09-16 10:53 chan
drwx------ 2 che che 4096 2013-09-16 10:53 che
drwx------ 2 chi chi 4096 2013-09-16 10:53 chi
drwx------ 2 cho cho 4096 2013-09-16 10:53 cho
drwx------ 2 dan dan 4096 2013-09-16 10:53 dan
drwx------ 2 dav dav 4096 2013-09-16 10:53 dav
drwx------ 2 dem dem 4096 2013-09-16 10:53 dem
drwx------ 2 elm elm 4096 2013-09-16 10:53 elm
drwx------ 2 fai fai 4096 2013-09-16 10:53 fai
drwx------ 2 fen fen 4096 2013-09-16 10:53 fen
drwx------ 2 ghan ghan 4096 2013-09-16 10:53 ghan
drwx------ 2 ghar ghar 4096 2013-09-16 10:53 ghar
drwx------ 2 gie gie 4096 2013-09-16 10:53 gie
drwx------ 2 hei hei 4096 2013-09-16 10:53 hei
drwx------ 2 hes hes 4096 2013-09-16 10:53 hes
drwx------ 2 jiw jiw 4096 2013-09-16 10:53 jiw
drwx------ 2 kru kru 4096 2013-09-16 10:53 kru
drwx------ 2 kur kur 4096 2013-09-16 10:53 kur
drwx------ 2 liu liu 4096 2013-09-16 10:53 liu
drwx------ 2 mac mac 4096 2013-09-16 10:53 mac
drwx------ 2 mcc mcc 4096 2013-09-16 10:53 mcc
drwx------ 2 mei mei 4096 2013-09-16 10:53 mei
drwx------ 2 mil mil 4096 2013-09-16 10:53 mil
drwx------ 2 mon mon 4096 2013-09-16 10:53 mon
drwx------ 2 nak nak 4096 2013-09-16 10:53 nak
drwx------ 2 nys nys 4096 2013-09-16 10:53 nys
drwx------ 2 pan pan 4096 2013-09-16 10:53 pan
drwx--x--x 13 prof prof 4096 2013-09-16 10:52 prof
drwx------ 2 rob rob 4096 2013-09-16 10:53 rob
drwx------ 2 sal sal 4096 2013-09-16 10:53 sal
drwx------ 2 sch sch 4096 2013-09-16 10:53 sch
drwx------ 2 sci sci 4096 2013-09-16 10:53 sci
drwx------ 2 sha sha 4096 2013-09-16 10:53 sha
drwx------ 2 she she 4096 2013-09-16 10:53 she
drwx------ 3 stu stu 4096 2013-09-16 10:53 stu
drwx------ 2 tay tay 4096 2013-09-16 10:53 tay
drwx------ 2 tho tho 4096 2013-09-16 10:53 tho
drwx------ 2 tra tra 4096 2013-09-16 10:53 tra
drwx------ 2 van van 4096 2013-09-16 10:53 van
drwx------ 2 wil wil 4096 2013-09-16 10:53 wil
stu@riely373:~$
Command: cp
Arguments: existing_file new_copy
Description: Copy existing_file to the file new_copy. If new_copy doesn't exist, create it. If it does exist, first delete its contents.
If new_copy is a directory, a copy of existing_file is created in directory new_copy with the same file name - existing_file.
Example:stu@riely373:~$ cp /home/prof/public/lecture1/hello.c .
stu@riely373:~$ ls
hello.c
stu@riely373:~$ ls -l
total 4
-rw-r--r-- 1 stu stu 70 2013-01-07 09:47 hello.c
stu@riely373:~$ cp hello.c test.c
stu@riely373:~$ ls
hello.c test.c
stu@riely373:~$ ls -l
total 8
-rw-r--r-- 1 stu stu 70 2013-01-07 09:47 hello.c
-rw-r--r-- 1 stu stu 70 2013-01-07 09:53 test.c
stu@riely373:~$
Command: mkdir
Arguments: new_subdirectory_name
Description: Create a subdirectory of the current directory
Example:stu@riely373:~$ mkdir hw1
stu@riely373:~$ mkdir hw2
stu@riely373:~$ ls
hello.c hw1 hw2 test.c
stu@riely373:~$ ls -l
total 16
-rw-r--r-- 1 stu stu 70 2013-01-07 09:47 hello.c
drwxr-xr-x 2 stu stu 4096 2013-01-07 10:00 hw1
drwxr-xr-x 2 stu stu 4096 2013-01-07 10:00 hw2
-rw-r--r-- 1 stu stu 70 2013-01-07 09:59 test.c
stu@riely373:~$
Command: rm
Arguments: file list
Options: -i -r
Description: Removes (deletes) the specified files
-i Ask before removing each file (Good idea since it is not possible to reverse a removal)Example:
-r Recursive remove directories and subdirectories in
the list. Files will be removed in these directories
first and then the directory itself.(Useful but dangerous)
stu@riely373:~$ rm test.c
stu@riely373:~$ ls
hello.c hw1 hw2
stu@riely373:~$ rm hw2
rm: cannot remove `hw2': Is a directory
stu@riely373:~$ rm -r hw2
stu@riely373:~$ ls
hello.c hw1
stu@riely373:~$ rm -ri hw1
rm: remove directory `hw1'? n
stu@riely373:~$ ls
hello.c hw1
stu@riely373:~$
Command: mv
Arguments: existing_file new_file
Options: -i
Description: Renames existing_file to have the name new_file -i Prompts if mv would overwrite an existing file.
Example:stu@riely373:~$ mv hello.c test.c
stu@riely373:~$ ls
hw1 test.c
stu@riely373:~$ mv hw1 homeworks
stu@riely373:~$ ls
homeworks test.c
stu@riely373:~$
Command: cd
Arguments: target_directory
Description: Change the current directory (working directory) to the specified target_directory. If no target_directory is specified, change to the login/home directory.
stu@riely373:~$ cd homeworks/
stu@riely373:~/homeworks$ pwd
/home/stu/homeworks
stu@riely373:~/homeworks$ cd ..
stu@riely373:~$ ls
homeworks test.c
stu@riely373:~$ pwd
/home/stu
stu@riely373:~$
stu@riely373:~$ more test.c
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
stu@riely373:~$
stu@riely373:~$ cat test.cThe cornmand cat gets its name from concatenate: it reads its input file names and writes them to the screen. If you give it more than one file name then cat will first the file contents one after another.
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
stu@riely373:~$
stu@riely373:~$ cat test.c test.c
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
stu@riely373:~$
stu@riely373:~$ cat test.c test.c > test2.txtwould give you a file named test2.txt whose content is the contents of the concatenation of test.c and test.c. This is a good way to add files together.
stu@riely373:~$ more test2.txt
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
#include <stdio.h>
int main()
{
printf("hello, world\n");
}
stu@riely373:~$
To print a file, you need to transfer
the file to your PC. You can then print the file as you would any
other file on the PC.
stu@riely373:~$ man -k fork
fork (2) - create a child process
forkpty (3) - tty utility functions
vfork (2) - create a child process and block parent
stu@riely373:~$ man fork
FORK(2) Linux Programmer's Manual FORK(2)
NAME
fork - create a child process
SYNOPSIS
#include <unistd.h>
pid_t fork(void);
DESCRIPTION
fork() creates a new process by duplicating the calling process. The
new process, referred to as the child, is an exact duplicate of the
calling process, referred to as the parent, except for the following
points:
* The child has its own unique process ID, and this PID does not match
the ID of any existing process group (setpgid(2)).
* The child's parent process ID is the same as the parent's process
ID.
* The child does not inherit its parent's memory locks (mlock(2),
mlockall(2)).
Manual page fork(2) line 1
stu@riely373:~$ cp /home/prof/public/lecture1/hello.c .The command gcc (GNU C Compiler) compiles the program hello.c, links it with any standard c library routines called (e.g. i/o routines) and produces the executable file named hello.
stu@riely373:~$ gcc -o hello hello.c
The file hello is an executable and could run at the command line
stu@riely373:~$ helloif the PATH environment variable includes the current directory (denoted .) . The value of the PATH environment variable is a sequence of directories the shell will look in for executables. To view this sequence, do:
stu@riely373:~$ echo $PATHNote the the current directory (.) is not included. To execute hello, you will need to specify where the executable hello is:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
stu@riely373:~$ ./hello/home/stu/hello is the absolute pathname of file hello
hello, world
stu@riely373:~$ /home/stu/hello
hello, world
stu@riely373:~$
$ gcc -o hello hello.cThe compilation system performs the translation of the source file hello.c to an executable hello which consists of a sequence of low-level machine language instructions.
$ gcc -E hello.cTo obtain the assembly program hello.s, do:
stu@riely373:~$ gcc -S hello.cTo obtain the relocatable object file (binary file that is not yet executable because it is not linked to helper library functions) hello.o, do:
stu@riely373:~$ ls
hello hello.c hello.s
stu@riely373:~$ more hello.s
.file "hello.c"
.section .rodata
.LC0:
.string "hello, world"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
movl $.LC0, (%esp)
call puts
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
.section .note.GNU-stack,"",@progbits
stu@riely373:~$
stu@riely373:~$ gcc -c hello.cA binary file cannot be viewed using text viewing tools...
stu@riely373:~$ ls
hello hello.c hello.o hello.s
stu@riely373:~$ more hello.o
******** hello.o: Not a text file ********
hello.cYou can get the examples that follow by copying folder lecture1 to your current directory:
stu@riely373:~$ cp -r ../prof/public/lecture1 .
stu@riely373:~$ ls
hello hello.c hello.o hello.s lecture1
stu@riely373:~$ cd lecture1
stu@riely373:~/lecture1$ ls
arithmetic.c count2.c flow.c pointers3.c power.c
ascii.c count.c hello.c pointers4.c sort.c
blocks.c data-types.c loops.c pointers5.c sum.c
cmdline.c demo1.c pointers2.c pointers.c temp.c
stu@riely373:~/lecture1$
demo1.cThe #include line at the top are similar to an import in Java but they differ significantly. In C, the #include is a pre-compilation directive that instructs the compiler to replace the #include line with the text from the indicated file. This file is called a header file and it contains references to library function executables that the program uses.
printf("Please enter an integer: ");
and
printf("x: %d y: %d\n", x,y );
In the first printf we supply a string literal. What you see is what
you get. In the second printf call we pass in a format string,
followed by one or more arguments ( the x and y variables). The
format string is printed as is except for placeholders denoted with
a % symbols. The values of the arguments (x and y) will be printed
exactly where the placeholders are. Each placeholder (%) is followed
by a conversion instruction---d in our examples---that says
how the value is to be printed (in decimal notation, or binary,
hexadecimal, etc.) In ou case, %d means decimal notation. At the end
of the format there is an escape sequence \n which
denotes a newline.To read data from the keyboard our first C program uses:
scanf("%d", &x );
The first argument is, again, a format string. It is used to
instruct the function scanf how to interpret what the user types. In
this case it instructs scanf to interpret the user's input as an
integer in decimal notation. The second argument contains the name
of the variable where the input is to be stored (x). Note the
ampersand character ( & ) before
the x variable. This ampersand character is the address-of
operator. This operator when placed before an
variable produces the address of that variable, rather than
the value of the variable. This address value is a positive
memory address between 0 and however much memory you have in your
computer. scanf needs the address of x not the value
of x because scanf wants to know where to store the numeric
conversion of the string you typed into the keyboard.
Recall that when we just want the value of x we just use the name x in a statement such as:
x=15; // assignment into the value of x
or
y=x+5; // lookup the value of x
or
printf("value of x: %d", x ); // lookup the value of x
This is the first time we have ever been concerned with the address of where a variable is stored in memory. Java intentionally shields us from any such concerns. C does not. Thus it is important to understand the distinction between the value of a variable, and the address of a variable. They are not the same. If we want the address we must put the & operator immediately to the left of the variable name.
The four basic data types are int, float, double, and char.
In
printf("%d %c\n",x,a);conversion instructions other than d are used. Here are the conversions we will use:
printf("%3d %5c\n",x,a);
printf("%f %e\n",e,d);
printf("%.9f %.9e\n",e,d);
printf("%20.9f %20.9e\n",e,d);
| Conversion Specification | Output |
|---|---|
| %c | character |
| %s | string of characters |
| %d or %i | decimal integer |
| %e | floating point number in e-notation |
| %f | floating point number in decimal notation |
| %p | pointer |
| %u | unsigned decimal integer |
| %o | octal integer |
| %x | hexadecimal integer, using lower case |
| %X | hexadecimal integer, using upper case |
| %% | Prints a % sign |
printf("%3d %5c\n",x,a);For float and double values, a precision can be specified:
printf("%20.9f %20.9e\n",e,d);
printf("%.9f %.9e\n",e,d);The following is a list of some common escape sequences:
printf("%20.9f %20.9e\n",e,d);
| Escape Sequences | Meaning |
|---|---|
| \n | New break |
| \b | Backspace |
| \f | Form feed |
| \r | Carriage return |
| \t | Horizontal tab |
| \\ | Prints a \ |
| \' | prints a ' |
| \" | prints a " |
stu@riely373:~$ man -k printfThe printf C function is described in man 3:
asprintf (3) - print to allocated string
dprintf (3) - print to a file descriptor
fprintf (3) - formatted output conversion
fwprintf (3) - formatted wide-character output conversion
printf (1) - format and print data
printf (3) - formatted output conversion
snprintf (3) - formatted output conversion
sprintf (3) - formatted output conversion
swprintf (3) - formatted wide-character output conversion
vasprintf (3) - print to allocated string
vdprintf (3) - print to a file descriptor
vfprintf (3) - formatted output conversion
vfwprintf (3) - formatted wide-character output conversion
vprintf (3) - formatted output conversion
vsnprintf (3) - formatted output conversion
vsprintf (3) - formatted output conversion
vswprintf (3) - formatted wide-character output conversion
vwprintf (3) - formatted wide-character output conversion
wprintf (3) - formatted wide-character output conversion
stu@riely373:~$ man 3 printfIn C, the char type is really an integer type. We use the conversion instructions to illustrate this:
PRINTF(3) Linux Programmer's Manual PRINTF(3)
NAME
printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf,
vsnprintf - formatted output conversion
SYNOPSIS
#include <stdio.h>
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
#include <stdarg.h>
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
snprintf(), vsnprintf(): _BSD_SOURCE || _XOPEN_SOURCE >= 500 ||
_ISOC99_SOURCE; or cc -std=c99
Manual page printf(3) line 1
...
ascii.c
C supports classical algebraic operators.
Notes:
loops.cSome more examples
sum.cNote the use the #define line to define symbolic constants LOWER, UPPER and STEP. It is good practice to use them instead of "burying" numbers like 300 and 20 deep inside the code. Symbolic constants can refer to values of any type (int, char, string, float, etc.)
temp.c
blocks.c
C supports two statements that modify the execution of a loop:
flow.c
power.cParameter passing: In C, function arguments are passed "by value". This means that the called function is given copies of the original values. For example, when the main program executes power(2, i) when the value of i is 5, copies of 2 and 5 are written to local variables base and n (they are local to the execution of function power):
int power(int base, int n)
{
int i, p;
p = 1;
for (i = 1; i <= n; ++i)
p = p * base;
return p;
}
scanf("%d", &x );
Since a C programmer may need to store a variable's address for
later use, C provides a data type called the pointer type.
The pointer type allows us to declare variables that are meant
to hold the address of some other variable. So, a pointer is a
variable that contains the address of another variable.int *pi /* creates a 32 bit variable whose data type is pointer to int */
int i; /* an int var */
pi = &i; /* pi now holds i's address - i.e it points to i */
pointers.cEvery variable in C has 2 at least 2 properties:
char *pc; /* pc is type: pointer to char */
float *pf; /* pf is type: pointer to float */
double *pd; /* pd is type: pointer to double */
typedef struct
double cost;
int age;
} student_type;
student_type *ps; /* ps can store the address of any student_type variable */
student_type one_student;
ps = &one_student; /* ps has the address where one_student is stored in memory */
We can use pointer variable pi to manipulate the contents of the int variable i. To do so we must dereference pi as follows:int *pi; /* variable of type pointer to int */
int i; /* plain old int var */
pi = &i; /* pi now contains address of var i */
*pi = 15; /* i now contains 15. */The expression *pi can be thought of as the value at the address which is stored in pi.
printf(" value pointed to by pi is: %d\n" *pi ); /* deref's pi and prints 15 */
int *pi;
pointers2.cSo, does the below function swap work correctly?
void swap(int x, int y)To alter the value of a variable (e.g., val in example pointers2 and a and b in example pointers3) in the calling function (i.e., function main), the calling function must pass a pointer to the variable.
{
int temp;
temp = x;
x = y;
y = temp;
}
int main()
{
int a = 0;
int b = -123;
swap(a, b);
return 0;
}
pointers3.c
pointers4.cThe correct way to swap in C:
pointers5.c
arrays.cFor an arrays with n entries, the valid index values are from 0 to n-1.
str.cNotes:
int y;Pointer p is incremented by 5*4 = 20 bytes. This is because p is an integer pointer and what p + 5 really means is the 5th integer after the one that p references.
int *p = &y;
p = p + 5;
int a[10];element a[0] can be accessed as *pa, or *a, or p[0]
int *p;
p = a;
struct.cThe typedef instruction, which defines a new (user-defined) type, can be used to facilitate the usage of structs:
struct2.c
employee *eptr;then the pointer must be dereferenced in order for the structure content to be accessed:
(*eptr).first = "Sam";An alternative notation is typically used:
(*eptr).last = "Smith";
(*eptr).age = 55;
printf("%s %s, age %d\n", (*eptr).first, (*eptr).last, (*eptr).age);
// alternative notation
eptr->first = "Sam";
eptr->last = "Smith";
eptr->age = 55;
printf("%s %s, age %d\n", eptr->first, eptr->last, eptr->age);
struct3.cNote: the call malloc(12) allocates 12 bytes and returns the addess of the first byte (similar to new() in C++ and Java)
void* malloc(int n)Note that the input is an integer and the return type is a generic address: void*. When you need to dynamically create a new integer, for example, you will use malloc() to allocate 4 bytes. However, in order to use these 4 bytes as an int value, you will need to cast the void* pointer as an int* pointer. Therefore, the typical usage of malloc() to "create" an integer dynamically is:
int *iptr = (int *) malloc(4);Then you can assign an integer value to this new, dynamically allocated integer:
*iptr = 5To dynamically create an array of 10 integers you would need 40 bytes:
int *array = (int *) malloc(40)Even better, for code portability reasons, would be using the C sizeof() function that takes a type and returns the number of bytes the type requires:
int *array = (int *) malloc(10*sizeof(int))Then you can use array just like a statically defined array:
for (int i = 0; i < 10; i++)To create a 2-dimensional array of integers dynamically, it is helpful and cleaner to use the C typedef instruction to define new types for a table row and for the table itself:
array[i] = i;
typedef int* row_t;The new type row_t is just a new name for the int* type; As we saw above, it can be used to refer to a dynamically allocated array of integers, i.e. a row of a 2-D array of integer
typedef row_t* table_t;
#include <stdlib.h>You can find this program, malloc_example2.c, in directory /home/prof/public/lecture1/ of our linux box riely373.cdm.depaul.edu. You can find there another example, malloc_example.c, that allocates a 2-D array of structs containing a memory address and an integer.
#include <stdio.h>
typedef int* row_t; // define row type
typedef row_t* table_t; // define table type
int main () {
int num_rows = 2;
int num_columns = 3;
table_t t;
int i,j;
// allocate space for holding num_rows row references
// t will refer to this spaces
t = (table_t) malloc(sizeof(row_t) * num_rows);
for (i=0; i<num_rows; i++)
// for every row allocate space for num_columns integers
t[i]=(int *) malloc(sizeof(int) * num_columns);
// Fill table t with zeros
for (i=0; i<num_rows; i++)
for (j=0; j<num_columns; j++)
t[i][j] = 0;
// Print the value in table t, row by row
for (i=0; i<num_rows; i++){
for (j=0; j<num_columns; j++)
printf("%d ", t[i][j]);
printf("\n");
}
return 0;
}
FILE* fp = fopen("test.txt", "r");Then, to read the first line of the file into a character array buf, use function fgets():
fgets(buf, 1000, fp)Functions fgets() will read a line or the first 999 bytes if the line is 1000+ bytes long) from the file refered to by fp and store it into the character array buf. The following is a ccomplete program that opens file "test.txt", reads it line by line, prints each line to standard output, and then closes the file:
#include <stdio.h> // to use printf, FILE, fgets, fcloseWhen executed, it will show on the screen the content of file test.txt:
int main()
{
char buf[1000]; // an array of characters for storing a line
FILE* fp = fopen("test.txt", "r"); // open file
while( fgets(buf, 1000, fp) != NULL) {
// repeatedly read a file line into buf until end of file
// and print content of buf (i.e. the line)
printf("%s\n", buf);
}
fclose(fp); // close the file
return 0;
}
$ ./fileIO_example1The complete fileIO_example1.c program and the test file test.txt are in directory /home/prof/public/lecture1/ of our linux box.
a 100,:,11
b 200,:,22
c 300,:,33
d 400,:,44
e 500,:,55
b 200,:,22and store them, respectively, in variables, c, a, and b defined as:
char c;The function sscanf() can be used to do this. It takes as input: the character array buf that contains the line, a format string, and addresses of variables c, a, and b:
unsigned int a;
int b;
sscanf(buf, " %c %u,:,%d", &c, &a, &b);The format string describes the format of the string stored in buf and the placeholders %c, %u, and %u indicate the places where the values to be extracted into c, a, and b are.