Skip to content

Commit fbddc16

Browse files
committed
Add exam 4
1 parent ad56cb8 commit fbddc16

8 files changed

+609
-0
lines changed

exam4/Makefile

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# compiler & options
2+
CC=gcc
3+
CCFLAGS=-Wall -Wshadow -g
4+
5+
# source files & binaries
6+
HIDE_BIN=hidestrings
7+
HIDE_SRC=$(HIDE_BIN).c
8+
REST_BIN=restorestrings
9+
REST_SRC=$(REST_BIN).c
10+
LIST_BIN=listmain
11+
LIST_SRC=listfunctions.c $(LIST_BIN).c
12+
13+
# usage message
14+
help:
15+
@echo 'Usage:'
16+
@echo ' make $(HIDE_BIN) -or-'
17+
@echo ' make $(REST_BIN) -or-'
18+
@echo ' make $(LIST_BIN)'
19+
@echo ''
20+
@echo 'To build either part of the exam.'
21+
22+
# compile directives
23+
$(HIDE_BIN): $(HIDE_SRC)
24+
$(CC) $(CCFLAGS) $^ -o $@
25+
26+
$(REST_BIN): $(REST_SRC)
27+
$(CC) $(CCFLAGS) $^ -o $@
28+
29+
$(LIST_BIN): $(LIST_SRC)
30+
$(CC) $(CCFLAGS) $^ -o $@
31+
32+
# clean up
33+
clean:
34+
rm -rf $(HIDE_BIN) $(REST_BIN) $(LIST_BIN)

exam4/README

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
EXAM 4
2+
3+
PROBLEMS ONE AND TWO (30% each)
4+
5+
The first two problems ask you to complete two C programs that are
6+
provided by us in mostly complete form. The details are described in the .c
7+
files and the hidestrings.h file.
8+
9+
There is a Makefile provided that can make either program.
10+
"make hidestrings" will make the executable hidestrings from hidestrings.c.
11+
"make restorestrings" will make the executable restorestrings from restorestrings.c.
12+
13+
You should not have to modify any part of those files except the ALL
14+
CAPS COMMENTS where you are requested to place code.
15+
16+
Each program stands alone (has its own main() function) and is
17+
controlled from the command line as described in the help message it
18+
prints out if given no arguments.
19+
20+
21+
We provide sample inputs and outputs for hidestrings in the directory samples/
22+
The inputs and outputs for restorestrings are just the reverse of those for hidestrings.
23+
24+
25+
PROBLEM THREE, A to H (5% each)
26+
27+
Modify the files lists.h and listfunctions.c as described therein.
28+
29+
The file listmain.c is provided to compile with listfunctions.c and provide command-line testing.
30+
31+
Use "make listmain" to make the executable listmain that does this command-line testing.
32+
33+
34+
ALL PROBLEMS
35+
36+
In addition to sample inputs and outputs, a tester script that tests a few
37+
testcases for each problem is provided. The tester script does not run a check
38+
for memory errors. Also, note that the grading scripts will very likely be more
39+
sophisticated (and test more corner cases) than the tester script.

exam4/hidestrings.c

+157
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// eswan
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <stdint.h>
5+
#include <string.h>
6+
#include "hidestrings.h"
7+
8+
int count_lines (char *filename);
9+
10+
/*
11+
PROBLEM ONE -- REPLACE THE COMMENTED ALL CAPS SECTIONS OF MAIN() FUNCTION
12+
WITH YOUR CODE
13+
14+
--also replace all caps section in hidestrings.h
15+
16+
Complete the implementation of the main() function below that reads
17+
in a ASCII text file (a normal non-binary file) line by line and
18+
writes out each line in a binary file according the following
19+
encoding:
20+
21+
The first 8 bytes of the encoded file follow this format:
22+
23+
-------------------------------------------------
24+
| magic-number (all 0s) | number of lines coded | 8 bytes
25+
-------------------------------------------------
26+
27+
The magic number is a 4-byte integer zero. The number of lines
28+
coded is also a 4-byte integer.
29+
30+
Then, for each line coded, a section is written of the output file
31+
according to the following
32+
33+
-------------------------------------------------
34+
| number n of coded bytes | coded bytes | 4+n bytes,
35+
-------------------------------------------------
36+
37+
An n-byte string is coded (WITHOUT the null terminator AND without
38+
the newline character) as the 4-byte int n, followed by n coded
39+
bytes. Each byte is coded independently: the coded byte is the
40+
original byte with every bit flipped, which can be computed as
41+
follows:
42+
43+
char uncoded = ...expression setting the char to be coded...;
44+
char coded = uncoded ^ 255; // 255 is hexadecimal FF, i.e. all bits one.
45+
46+
The coding can be reversed the same way:
47+
48+
char decoded = coded ^ 255;
49+
50+
*/
51+
52+
53+
int main (int argc, char **argv) {
54+
55+
if (argc != 3 || 0==strcmp(argv[1],"--help")) {
56+
printf("Usage: %s <infile> <outfile>\n", argv[0]);
57+
printf(" <infile> is an input file of binary encoded strings \n");
58+
printf(" <outfile> will be written over with the decoded version of the contents of <infile>\n");
59+
return 0;
60+
}
61+
62+
int numlines = count_lines (argv[1]);
63+
if (numlines<0) return 1;
64+
65+
66+
FILE *infile = fopen(argv[1],"r");
67+
68+
if (!infile) {
69+
fprintf(stderr, "Error opening input file \"%s\"\n", argv[1]);
70+
return 1;
71+
}
72+
73+
FILE *outfile = fopen(argv[2], "wb");
74+
75+
if (!outfile) {
76+
fprintf(stderr, "Error opening output file \"%s\"\n", argv[2]);
77+
return 1;
78+
}
79+
80+
// for fwrite below
81+
File_header header;
82+
header.magic = 0;
83+
header.line_count = numlines;
84+
85+
if(fwrite(&header, sizeof(File_header), 1, outfile) != 1) {
86+
fprintf(stderr, "Error writing output file \"%s\"\n", argv[2]);
87+
return 1;
88+
}
89+
90+
// for getline below
91+
char *lineptr=NULL;
92+
size_t n=0;
93+
94+
// loop index for "encoding" using ^255
95+
uint32_t i;
96+
97+
while (getline(&lineptr, &n, infile)>0) {
98+
uint32_t len = strlen(lineptr)-1; // don't count newline so won't encode or write it
99+
100+
for (i=0; i<len; i++) {
101+
lineptr[i] = lineptr[i] ^ 255;
102+
}
103+
104+
if (fwrite(&len, sizeof(uint32_t), 1, outfile) != 1) {
105+
fprintf(stderr, "Error writing output file \"%s\"\n", argv[2]);
106+
return 1;
107+
}
108+
109+
// If we have an "empty" line (just a newline, fwrite will return 0 here
110+
if (len > 0 && fwrite(lineptr, len, 1, outfile) != 1) {
111+
fprintf(stderr, "Error writing output file \"%s\"\n", argv[2]);
112+
return 1;
113+
}
114+
}
115+
116+
free(lineptr);
117+
118+
if (fclose(infile)) {
119+
fprintf(stderr, "Error closing input file \"%s\"\n", argv[1]);
120+
return 1;
121+
}
122+
123+
if (fclose(outfile)) {
124+
fprintf(stderr, "Error closing output file \"%s\"\n", argv[2]);
125+
return 1;
126+
}
127+
128+
return 0;
129+
}
130+
131+
132+
// This function does not need to be altered during the exam.
133+
// This function returns the number of lines found in the file, or -1 if any error.
134+
135+
int count_lines (char *filename) {
136+
FILE *infile = fopen(filename,"r");
137+
138+
if (!infile) {
139+
fprintf(stderr, "Error opening input file \"%s\"\n", filename);
140+
return -1;
141+
}
142+
143+
char *lineptr=NULL;
144+
size_t n=0;
145+
146+
int result=0;
147+
while (getline(&lineptr, &n, infile)>0) result++;
148+
149+
if (fclose(infile)) {
150+
free(lineptr);
151+
fprintf(stderr, "Error closing input file \"%s\"\n", filename);
152+
return -1;
153+
}
154+
155+
free(lineptr);
156+
return result;
157+
}

exam4/hidestrings.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// eswan
2+
3+
/*
4+
You must write the body of this struct so that it has two fields, both of type uint32_t.
5+
One filed is called "magic" and the other "line_count"
6+
*/
7+
typedef struct {
8+
uint32_t magic;
9+
uint32_t line_count;
10+
} File_header;

0 commit comments

Comments
 (0)