CS 240 Summer 2024

Lab 3: Programming using pointers, arrays and strings, basic file I/O (280 pts)

Due: 07/03/2024 (Wed), 11:59 PM


Reading

Read chapters 4 and 5 from K&R (textbook).


Lab 3 Code Base

A tarball of lab3/ is available as

/homes/park/pub/cs240/lab3.tar

Unlike lab1 and lab2, the coding problems do not directly depend on the code in lab3/. Instead, code in the subdirectories of lab3/ serve as examples and exercises whose lessons and skills are utilized to solve the assignment.


Problems [280 pts]

Problem 1 (80 pts)

Create a directory v15/ under lab3. Code main() in v15/prog15.c that declares a local 1-D character array of main(), char strinput[MAXLEN], where MAXLEN is a macro set to 10 using CPP command #define. main() calls, int readstring(char *), coded in prog15.c by passing strinput as argument. As noted in class, main() returns 0 if execution proceeded normally.

readstring() reads from standard input using library function getchar() a sequence of ASCII characters not to exceed MAXLEN including '\n' which is generated when ENTER/RETURN is pressed on stdin, i.e., the keyboard. The characters are stored in the 1-D char array passed by the caller. If the number of characters exceeds MAXLEN readstring() stops reading and returns -1 to its caller. If the input is valid (i.e., does not exceed MAXLEN) the '\n' character is replaced by '\0' to indicate end-of-string and readstring() returns the number of characters read excluding '\0'. main() checks the return value readstring(). If it is -1, main() outputs a suitable error message to stdout and terminates by executing the return statement with value 1. Otherwise, main() calls function filternum() coded in prog15.c.

The function, int filternum(char *), goes through the characters of the string passed by its caller and outputs a character to stdout (i.e., terminal) if it is a numerical ASCII character '0', '1', ..., '9'. Otherwise, a character is not output. For example, if the string is "a2014b$" then 2014 is output to stdout. Use the library function putchar() to print ASCII characters to stdout. filternum() iterates through the characters until EOS is reached or the number of characters exceeds MAXLEN. In the latter case, filternum() returns -1 to its caller, otherwise 0.

Test and verify that your code works correctly.

Problem 2 (30 pts)

A continuation of Problem 1, create a subdirectory v16/ under lab3/. Place main() in its own file v16/main.c, readstring() in readstring.c, filternum() in filternum.c. Place the CPP statement #define that sets of value MAXLEN in header file, v16/header16.h, that is included in the .c files using CPP statement #include. Create Makefile in v16/ that automates compilation and creation of executable file, main.exe. Test and verify that your revised implementation works correctly.

Problem 3 (30 pts)

A continuation of Problem 2, create subdirectory lab3/v17. Modify the code so that, char strinput[MAXLEN], is declared as global in main.c instead of being a local variable of main(). Create a second header file, v17/header17.h, which can be included in readstring.c and filternum.c using #include to reference the global variable. Modify the function prototypes of readstring() and filternum() so that do not pass arguments given that strinput[] is now global. Update the code of readstring() and filternum() accordingly. Test and verify that your code works correctly.

Problem 4 (60 pts)

Create subdirectory lab3/v18. Code an app, main() in v18/prog18.c, that reads a filename (a sequence of ASCII characters) from stdin where filename cannot exceed 12 characters including EOS. Reuse the technique from Problem 1 for checking validity of input length, outputting an error message to stdout and terminating if the filename provided exceeds 12 characters. Use library function fopen() to open the specified file. If fopen() fails, output a suitable error message before terminating the app by main() returning 1.

The content of the file may not be ASCII text, i.e., contain byte values in the range 128-255. Read each byte of the file using library function fgetc() until the end of file is reached. Use the while-loop condition

while((c = fgetc(fp)) != EOF)

where fp is of type, FILE *, and c is of type int. For each byte, check in the body of the while-loop if it is ASCII. Keep in mind that the value of a byte read is stored in variable c which is of type int. If the byte is an ASCII character, output its value to stdout using library function fputc(). Thus your app outputs only ASCII characters contained in a file, filtering out all non-ASCII bytes. Since v18/ contains prog18.c only, we will not use the make utility (i.e., no Makefile). Test and verify that your code works correctly.

Problem 5 (80 pts)

Create subdirectory v19/ in lab3/. Use the code of Problem 2 as a starting point to implement a new app that reads lines of characters from a file into a 2-D char array, char filelines[MAXROW][MAXCOL], declared as local to main() in main.c. Use CPP command #define to set MAXROW to 20 and MAXCOL to 10 in header file v19/header19.h. The header files in v16/ can remain in v19/ but will not be needed. Change the name of the function readstring() to readlines() (in v19/readlines.c) and modify the function prototype to, int readlines(char **), so that the 2-D char array filelines is passed to by the caller main().

Code readlines() so that it opens file "test.dat" using fopen() to read. The filename is fixed. readlines() reads each line ending with '\n' of the input file in a row of filelines[][] starting at row 0. readlines() checks that a line does not exceed MAXCOL characters including '\n'. If line length is exceeded, readlines() returns -1 to its caller. readlines() also checks that the number of lines does not exceed MAXROW. If it does, readlines() returns -2 to its caller main(). If the input is valid, readlines() returns the number of lines read to its caller. For example,

abcde
213
%#(Yz
ABe

contained in test.dat is valid, and readlines() returns 4.

If readlines() returns -1, main() outputs a suitable error message to stdout, returns 1 and terminates. If readlines() returns -2, main() outputs a suitable message different from that of return value -1, then calls exit(1) to terminate. Otherwise, main() calls reorder() in v19/reorder.c with function prototype, int reorder(char **, int rownum), where main() passes the 2-D character array as first argument and the number of lines as second argument. reorder() uses library function fputc() to output the lines of the input file read into filelines[][] in reverse order, i.e., the last line is output first and the first line is output last.

Create Makefile to automate compilation and generation of an executable file, revlines. Annotate your code so that it is more easily understandable by a third party reading your code. 10 points out of 80 will be contributed by adequate code annotation. Test and verify that your code works correctly.


Bonus problem (30 pts)

Create subdirectory lab3/v20. Modify your code of Problem 5 so that the 2-D character array, char filelines[MAXROW][MAXCOL], is declared as global in main.c. Make changes to the rest of the code, including modifying function prototypes, to conform with the change of filelines[][] from local to global. Test and verify that your code works correctly.


Turn-in instructions

Electronic turn-in instructions:

i) For problems that require answering/explaining questions, submit a write-up as a pdf file called lab3.pdf. Place lab3.pdf in your directory lab3/. You can use your favorite editor subject to that it is able to export pdf files which many freeware editors do. Files submitted in any other format will not be graded. The TAs need to spend their time evaluating the content of your submission, not switching between editors or hunting down obscure document formats which wastes time and is in no one's interest.

ii) We will use turnin to manage lab assignment submissions. In the parent directory of lab3, run the command

turnin -c cs240 -p lab3 lab3

You can verify/list your submission by running: turnin -c cs240 -p lab3 -v. Please double-check that you submitted what you intended to submit.


Back to the CS 240 web page