Warning! This site is under development.
This class will be recorded! Its use will be limited to members of the class. Please do not share with others.
Approximate overview
top-five to top-n. You may limit the line size, but
not the number of lines.pipe-to-file fname that reads from stdin and puts
output both to the given file and to stdout.Are the robots awesome?
Yes, particularly when they fail to work properly.
Will you teach us Unix-style regexps?
Yes.
Will you teach us a bit about vi/vim/neovim/emacs/whatever else?
Maybe.
Will you teach us about the stupid !’s you use?
Yes.
\r\n to just \nA bit of (silly) history. Typewriters had this lever that (a) moved
you to the next line and (b) shoved the carriage back to the right.
In the Unix world, we used \n to represent that action. (“Newline”)
It is possible to go to a new line without resetting the carriage.
The designers of DOS (aka Young Bill) decided we should have both
characters. Amazingly, no one has ever reconciled the two worlds.
If you’re not careful, things work poorly on the other platform.
Steve Jobs, unwilling to follow standards, forced his programmers
to use only \r.
What are strategies we can use to fix that problem?
sed. Sed is the “stream editor”. Takes a sequence
of characters as output, produces a sequence of characters as output,
and does any list of commands to the input sequence.
s/\r\n/\n/g\r\n\ntr, which translates or deletes characters.
\r anywhere in the line. (But who
uses \r except for \r\n?) (See note above.)\r\n?
od command: Octal dump. It lets you look at the
underlying data as characters or hex digits or ….dos2unix, which is not installed by default on most Linux
systems, but which should be.sed again.vi and type an appropriate command.sed 's/\(.\)/\L\1/g'tr (this is often a standard use of tr).grep searchessort sortshead takes the first few values (or tail)
headsed again
| sed -e 's/,[^,]*,[^,]*$//g'cut (the more Unix commands you know, the more efficient
you are, at least until you start to confuse them with each other)What are some strategies you saw here?
Identify positive and negative aspects of each of these.
See examples/file-downcase/downcase.c.
/*
* Some Student <student@grinnell.edu>
*
* TASK: Given a standard text file, convert all uppercase letters to
* lowercase.
*
* Usage: To convert an input text file to all lowercase letters, pass the
* name of the input file and the desired output file name as command-line
* arguments.
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
/* checks to see if there was a file argument passed */
if (argc != 3) {
fprintf(stderr, "usage: lower <input>.txt <output.txt>\n");
exit(EXIT_FAILURE);
}
/* opens the input file for reading and checks for errors */
FILE *in_fp;
if (!(in_fp = fopen(argv[1], "r"))) {
fprintf(stderr, "error: fopen failed\n");
exit(EXIT_FAILURE);
}
/* opens output file for writing and checks for errors */
FILE *out_fp;
if (!(out_fp = fopen(argv[2], "w"))) {
fprintf(stderr, "error: fopen failed\n");
exit(EXIT_FAILURE);
}
/*
* iterates over the characters in the input file until it hits EOF,
* writing the lower-case version of each character to the output file.
*
* note: tolower will leave non-alphabetical and lowercase letters
* unchanged, so we don't have to check for either
*/
char ch;
while ((ch = getc(in_fp)) != EOF) {
putc(tolower(ch), out_fp);
}
fclose(in_fp);
fclose(out_fp);
}
argv[0] as the command name, rather than
hard-coding it.fclose fails?do { } while. NO.getc returns an integer. Should we really store it in a char?tolower.See examples/top-five/top-five.c.
/*
============================================================================
Name : grades.c
Author : Student Name
Version :
Copyright : Your copyright notice
Description : Prints the five highest grades from HW2 in a CSV file
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define DATA_FILE "grades.csv"
#define LINE_LENGTH 100
#define STRING_LENGTH 256
int main(int argc, char* argv[])
{
FILE* stream = fopen(DATA_FILE, "r");
if(stream == NULL)
{
fprintf (stderr, "%s: Cannot open %s: %s\n",
argv[0], DATA_FILE, strerror(errno));
return -1;
}
char line[LINE_LENGTH][STRING_LENGTH];
int i;
for(i = 0; i < LINE_LENGTH; ++i)
{
strcpy(line[i], "");
}
char storeString[STRING_LENGTH];
i = 0;
while(fgets(storeString, STRING_LENGTH, stream))
{
if(strstr(storeString, "HW2"))
{
int storeLength = strlen(storeString);
int characterNum = 2;
for(int j = storeLength - 1; j > storeLength - 4; --j)
{
line[i][characterNum--] = storeString[j];
}
++i;
}
}
int mainArr[5];
for(i = 0; strcmp(line[i], "")/* line[i] != NULL */; ++i)
{
int currNum = atoi(line[i]);
if(currNum > mainArr[0])
{
mainArr[4] = mainArr[3];
mainArr[3] = mainArr[2];
mainArr[2] = mainArr[1];
mainArr[1] = mainArr[0];
mainArr[0] = currNum;
continue;
}
if(currNum > mainArr[1])
{
mainArr[4] = mainArr[3];
mainArr[3] = mainArr[2];
mainArr[2] = mainArr[1];
mainArr[1] = currNum;
continue;
}
if(currNum > mainArr[2])
{
mainArr[4] = mainArr[3];
mainArr[3] = mainArr[2];
mainArr[2] = currNum;
continue;
}
if(currNum > mainArr[3])
{
mainArr[4] = mainArr[3];
mainArr[3] = currNum;
continue;
}
if(currNum > mainArr[4])
{
mainArr[4] = currNum;
continue;
}
}
for(i = 0; i < 5; ++i)
{
printf("%d ", mainArr[i]);
}
return 0;
} // end of program
Some thoughts
mallocstdin than hard-code a file name.How do I get rid of the cruft in this directory?
$ ls
'*' important MyThesis/ -rf '-rf *'
Why use stdin rather than a file name for a quick hack?
Easier to test when things go wrong.
Easier to use in more cases without changing it. (You can always change your input with
<or with|.)
Filters are standard Unix approaches, which makes it easier to use with other files.
No need to remember the file opening and closing commands.
What do < and | do?
If you type
command < filename, it reads the input from the given file.
If you type
command-1 | command-2, the output ofcommand-1is the input tocommand-2.
The second allows us to chain things together.
If you want
command-1to take input from a file, you usecommand-1 < file | command-2.
Most would type
cat file | command-1 | command-2.
catis short for “can anybody type?” (or “concatenate”)
What happens if you have a command with no output, such as in
command1 > file | command2?
In that particular case
command1will put its output in the file, and command2 will read empty input. (I think.)
There is a command to split your output to a file, but I don’t remember it.
You could also write that command.
We’re done. I’ll move the rest to the next class (or maybe just “another class”).
Taken from Task 2b.
How do you learn *nix tools?
lsNo, that’s not “ones”.
manEveryone’s favorite gendered command.
duWhat does du do?
grep (or egrep)Grinnell’s excellent program
trIs that pronounced “tiara” because it’s the crown of commands?
tarA sticky substance. Also “tape archive”.
uniqKind of like Unix, I think.
sortI wonder what this is an abbreviation for.
head and tailCan you write Scheme in the shell?
cutSounds dangerous.
killSounds even more dangerous.
whichNo, not witch.
fileLearn about file types.
Let’s pretend that Sam has not reread Raymond in five years, and that half of your classmates neglected to do the reading. What are the key takeaways from the Raymond reading?
This example is adapted from Kernighan and Plauger.
What does this do? (TPS)
for (int i = 1; i <= ROWS; i++)
for (int j = 1; j <= COLS; j++)
M[i-1][j-1] = (i/j)*(j/i);
How should you write it if you wanted to be clear?
This one will be fun, because I’ll need to figure it out again.
To illustrate my point that understanding memory in C is important, let’s continue with a problem that a friend gave to me a while ago. He showed me the following fragment of C code.
x = malloc (...);
foo ();
bar ();
free (x);
The program was crashing on the call to free.
Here are some things they discovered.
free, the program ran through to completion.free before the call to bar, the program ran
through to completion.free in bar.What is likely to be wrong with their code? How would you trace the error?