CS253 HW5: Options!                
Changes                
Behavior is undefined if case-independent is in effect, and two -c
arguments differ only by case, e.g., -c yip -i -c YIp
. You may
treat this as an error, ignore it, or any other behavior.
                
Look into toupper() for case conversion for case-independent matching.
It converts a single char; not an entire string.
                
Description                
For this assignment, you will build upon your previous work in HW3,
adding command-line options parsed with getopt(). This is a complete
program, not a library.
                
Words                
Only replace a complete word. We define a word as a sequence of
letters, a…zA…Z, delimited (bordered) by non-letters, or the start/end
of the line. If we’re censoring the word “foo”, then input such as
“fooYMP” must not be changed, but “foo4194303” must be.
                
Arguments                
The first command-line arguments should be options :
                
-
-r
replacement -
The argument is the replacement string for censoring. It may have any
value. If this option is not given, use the eight-character string
“CENSORED”.
-
-c
one-word-to-censor -
Add this word to the list of words to censor.
-
-i
-
If this option is given, words to censor are considered to be
case-independent.
-c hAMbonE -i
will censor the word “HamBone” in
the input. If this options is not given, matching is case-dependent,
as in HW3.
-
-v
-
Announce each filename to standard output, just before reading the
data inside it. Before reading standard input, announce that in
some way that includes the words “
standard input
”.
After the options comes an optional list of filenames, as in HW3.
If any filenames are given, read from them, and write their censored
contents to standard output. Otherwise, read from standard input,
instead, and write its censored contents to standard output.
                
This is the Colorado State University CS253 web page
https://cs.colostate.edu/~cs253/Spring22/HW5
fetched by unknown <unknown> with Linux UID 65535
at 2024-11-21T20:00:22 from IP address 18.117.172.189.
Registered CSU students are permitted to copy this web page for personal
use, but it is forbidden to repost the information from this web page to the
internet. Doing so is a violation of the rules in the CS253 syllabus,
will be considered cheating, and will get you an F in CS253.
Sample Runs                
Here are sample runs, where %
is my prompt.
                
% cat CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(hw5)
# Are we in the wrong directory?
if (CMAKE_SOURCE_DIR MATCHES "[Hh][Ww]([0-9])$"
AND NOT PROJECT_NAME MATCHES "${CMAKE_MATCH_1}$")
message(FATAL_ERROR "Building ${PROJECT_NAME} in ${CMAKE_SOURCE_DIR}")
endif()
# Using -Wall is required:
add_compile_options(-Wall)
# These compile flags are highly recommended, but not required:
add_compile_options(-Wextra -Wpedantic)
# Optional super-strict mode:
add_compile_options(-fmessage-length=80 -fno-diagnostics-show-option
-fstack-protector-all -g -O3 -std=c++17 -Walloc-zero -Walloca
-Wctor-dtor-privacy -Wduplicated-cond -Wduplicated-branches -Werror
-Wextra-semi -Wfatal-errors -Winit-self -Wlogical-op -Wold-style-cast
-Wshadow -Wunused-const-variable=1 -Wzero-as-null-pointer-constant)
# add_compile_options must be BEFORE add_executable.
# Create the executable from the source file main.cc:
add_executable(${PROJECT_NAME} main.cc match.cc)
# Create a tar file every time:
add_custom_target(${PROJECT_NAME}.tar ALL COMMAND
tar -cf ${PROJECT_NAME}.tar *.cc match.h CMakeLists.txt)
% cmake . && make
… cmake output appears here …
… make output appears here …
% cat lim1
There was a young woman named Bright,
Whose speed was much faster than light.
% cat lim2
She set out one day,
In a relative way,
And returned on the previous night.
% ./hw5 -c briGHT -c was lim1 lim2
There CENSORED a young woman named Bright,
Whose speed CENSORED much faster than light.
She set out one day,
In a relative way,
And returned on the previous night.
% ./hw5 -c bright -r@ -ic was lim1 lim2
There @ a young woman named @,
Whose speed @ much faster than light.
She set out one day,
In a relative way,
And returned on the previous night.
% echo -e "three . one four one five nine\ntwo six five" | ./hw5 -vc one
Reading standard input.
three . CENSORED four CENSORED five nine
two six five
Debugging                
If you encounter “STACK FRAME LINK OVERFLOW”, then try this:
export STACK_FRAME_LINK_OVERRIDE=ffff-ad921d60486366258809553a3db49a4a
Hints                
- Look into toupper() for case conversion for case-independent matching.
It converts a single char; not an entire string.
- My
CMakeLists.txt
mentions match.h
and match.cc
because
my implementation uses those files. Yours doesn’t have to.
- A word that needs censoring might appear more than once in
a line in the input—censor them all.
- Whitespace is not special in this assignment. If your code
compares something to space or tab, or calls isspace(), you’re doing
it wrong.
- Don’t take any significant action when an option (e.g.,
-i
)
is encountered. Instead, just remember what needs to be done
later. Options don’t usually do things; instead, they modify
how things will be done later.
- Don’t guess what the user meant. If the arguments don’t match the
specification, complain and stop.
- Don’t make up your own rules. Don’t produce an error for situations
that you don’t like, such as no words to censor, or a file being
empty. Do what the specification says.
- However, if the specification seems ridiculous, ask.
Who knows—it could be a mistake in the spec!
Requirements                
- You must use getopt() to parse the options. If you do not,
then you will receive a three-point penalty.
- Behavior is undefined if the
-r
string contains a word that
appears as a -c
argument.
- The list of words to censor in argv, and the dash,
are part of HW3, and do not apply here.
- Error messages:
- go to standard error
- include the program name as given by
argv[0]
.
- stop the program
- If multiple things are bad, pick one, complain, and stop.
You don’t have to mention all problems.
- Produce an error message and stop the program if:
-r
is given more than once
- a bad option or bad option argument is given
(the message must contain the bad option and argument, if present)
- any filename given in argv isn’t readable
(the message must contain the bad filename)
- An option is bad if:
- the argument to
-c
is not purely alphabetic
- a word given via
-c
is repeated, e.g., -c A -i -c A
- Repeating
-i
or -v
has no additional effect.
- A space after an option taking an argument (
-r
or -c
)
is optional.
-cfoolish
and -c consistency
are both valid.
- Options must precede filenames. Option processing must stop at the
first argument that isn’t an option (or an argument to an option,
e.g.,
-c hobgoblin
).
This must attempt to treat -v
as a file, which will probably fail: ./hw5 infile -v
- Option bundling:
./hw5 -vi
is equivalent to ./hw5 -v -i
./hw5 -ivr123-65535
is equivalent to
./hw5 -i -v -r 123-65535
./hw5 -i-v
is invalid.
- The next non-space character after an option that requires an
argument must be the argument itself, not another option flag.
./hw5 -r Little -cv minds
will treat v
as the argument to -c
, and will then regard
minds
as a filename, which will probably fail.
- You must use getopt() to parse the options.
- Input format:
- The input may consist of any number of lines.
- Each input line may be arbitrarily long.
- You may not use any external programs. You many not use
system(), fork(), popen(), execl(), execvp(), etc.
- You may not use C-style I/O
such as printf(), scanf(), fopen(), and getchar().
- You may not use endl. Use flush if needed.
- You may not use dynamic memory via new, delete,
malloc(), calloc(), realloc(), free(), strdup(), etc.
- It’s ok to implicitly use dynamic memory via containers
such as string or vector.
- You may not use the .eof() method.
- No global variables.
- Except for an optional single global string called
program_name
containing argv[0]
.
- For readability, don’t use ASCII int constants (
65
) instead of
char constants ('A'
) for printable characters.
- We will compile your program like this:
cmake . && make
- If that generates warnings, you will lose a point.
- If that generates errors, you will lose all points.
- There is no automated testing/pre-grading/re-grading.
- Test your code yourself. It’s your job.
- Test with the CSU compilers, not just your laptop’s compiler.
- Even if you only change it a little bit.
- Even if all you do is add a comment.
- You must use getopt()!
Tar file                
- The tar file for this assignment must be called:
hw5.tar
- It must contain:
- source files (
*.cc
) required to build
- any header files (
*.h
) required to build
CMakeLists.txt
- This command must produce the program
hw5
(note the dot):
cmake . && make
- At least
-Wall
must be used every time g++ runs.
How to submit your work:                
In Canvas, check in the
file
hw5.tar
to the assignment “HW5”.
It’s due 11:59ᴘᴍ MT Saturday, with a five-day late period.
                
How to receive negative points:                
Turn in someone else’s work.