Guidelines and Common Errors
Building test
- You’ll lose all the points in MP0 if compilation of
char_count
failed. - Invalid filenames (eg.
Makefile.txt
,char_count.exe
, etc), wrong file hierarchy, or absence of Makefile grants 0 point.
Standard error test
- The stderr output should print exactly
error\n
only when INPUT_FILE doesn’t exist, or you’ll get 0 point. Those writing to stdout grant no points.
Feature test, aka. small/large input test
- Your program should handle both INPUT_FILE and stdin. Otherwise both small and large tests are marked failing.
- The extreme test can be a single line exceeding 1GB. Those reading data with
getline()
,gets()/fgets()
will suffer from buffer overflow. The spec mentioned the line size can be arbitrarily large. Thus, it’s not a good idea to read the whole line with a fixed length buffer. - Any printable and space characters can be included in CHARSET and every characters are counted without exception. Therefore, those filtering out spaces will result in wrong answer.
- Every line is guranteed to have trailing
\n
, and thus it can be treated as the end-of-line mark. Some incorrectly handles\n
and EOF cases, causing the program prints additional lines at the end of output. In this case it will fail both small/large input tests.
Example Implementation
Makefile
.PHONY: clean all
all: char_count
clean:
rm -f char_count
char_count: char_count.c
gcc -o char_count char_count.c -Wall
Source code (char_count.c
)
#include <stdio.h>
int main(int argc, char* argv[])
{
/* Init CHARSET lookup table. */
unsigned char charSet[128] = {};
for (int i = 0; argv[1][i] != '\0'; i++) {
charSet[(int)argv[1][i]] = 1;
}
/* Read from stdin by default. */
FILE* fileInput = stdin;
/* Read from file if argc is 3. */
if (argc == 3) {
fileInput = fopen(argv[2], "r");
}
/* Print error message if fopen failed. */
if (fileInput == NULL) {
fprintf(stderr, "error\n");
return 0;
}
int c;
int count = 0;
while ((c = fgetc(fileInput)) != EOF) {
if (c == '\n') {
/* Print number of matched char. */
printf("%d\n", count);
count = 0;
} else if (charSet[c] == 1) {
/* Add one to counter if in CHARSET */
count++;
}
}
return 0;
}