As homework we were given a C program with a list of problems to debug. I am hav
ID: 3648533 • Letter: A
Question
As homework we were given a C program with a list of problems to debug. I am having trouble with the last two questions:
*) Fix the argument parsing error. (Why is entryCount never zero?)
*) Fix print_result() to print results correctly (as shown in the comments section of the program) and in the same order as the words were specified on the command line.
I have figured out that entryCount is never zero because it is always incremented at least once even when no arguments are given (it seems to count ./main as an argument). Also, it appears that the numer of times a word has been found is always 0 because entries[entryCount++].counter is always given the value of 0. The names of the arguments given aren't properly saved in memory either.
I don't understand how to actually fix the bugs though though, so any help will be greatly appreciated!
//CODE FOR main.c
/*
About this program:
- This program counts words.
- The specific words that will be counted are passed in as command-line
arguments.
- The program reads words (one word per line) from standard input until EOF or
an input line starting with a dot '.'
- The program prints out a summary of the number of times each word has
appeared.
- Various command-line options alter the behavior of the program.
E.g., count the number of times 'cat', 'nap' or 'dog' appears.
> ./main cat nap dog
Given input:
cat
.
Expected output:
Looking for 3 words
Result:
cat:1
nap:0
dog:0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "smp0_tests.h"
#define LENGTH(s) (sizeof(s) / sizeof(*s))
/* Structures */
typedef struct {
char *word;
int counter;
} WordCountEntry;
int process_stream(WordCountEntry entries[], int entry_count)
{
short line_count = 0;
char buffer[30];
while (gets(buffer)) {
if (*buffer == '.')
break;
/* Compare against each entry */
int i = 0;
while (i < entry_count) {
if (!strcmp(entries[i].word, buffer))
entries[i].counter++;
i++;
}
line_count++;
}
return line_count;
}
void print_result(WordCountEntry entries[], int entry_count)
{
printf("Result: ");
while (entry_count-- > 0) {
printf("%s:%d ", entries->word, entries->counter);
}
}
void printHelp(const char *name)
{
printf("usage: %s [-h] <word1> ... <wordN> ", name);
}
int main(int argc, char **argv)
{
const char *prog_name = *argv;
WordCountEntry entries[5];
int entryCount = 0;
/* Entry point for the testrunner program */
if (argc > 1 && !strcmp(argv[1], "-test")) {
run_smp0_tests(argc - 1, argv + 1);
return EXIT_SUCCESS;
}
while (*argv != NULL) {
if (**argv == '-') {
switch ((*argv)[1]) {
case 'h':
printHelp(prog_name);
break;
default:
printf("%s: Invalid option %s. Use -h for help. ",
prog_name, *argv);
}
} else{
if (entryCount < LENGTH(entries)) {
entries[entryCount].word = *argv;
entries[entryCount++].counter = 0;
}
}
argv++;
} // end while
if (entryCount == 0) {
printf("%s: Please supply at least one word. Use -h for help. ",
prog_name);
return EXIT_FAILURE;
}
if (entryCount == 1) {
printf("Looking for a single word ");
} else {
printf("Looking for %d words ", entryCount);
}
process_stream(entries, entryCount);
print_result(entries, entryCount);
return EXIT_SUCCESS;
}
Explanation / Answer
//CODE FOR main.c
/*
About this program:
- This program counts words.
- The specific words that will be counted are passed in as command-line arguments.
- The program reads words (one word per line) from standard input until EOF or an input line starting with a dot '.'
- The program prints out a summary of the number of times each word has appeared.
- Various command-line options alter the behavior of the program.
E.g., count the number of times 'cat', 'nap' or 'dog' appears.
> ./main cat nap dog
Given input:
cat
.
Expected output:
Looking for 3 words
Result:
cat:1
nap:0
dog:0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "smp0_tests.h"
#define LENGTH(s) (sizeof(s) / sizeof(*s))
/* Structures */
typedef struct {
char *word;
int counter;
} WordCountEntry;
int process_stream(WordCountEntry entries[], int entry_count)
{
short line_count = 0;
char buffer[30];
while (gets(buffer)) {
if (*buffer == '.')
break;
/* Compare against each entry */
int i = 0;
while (i < entry_count) {
if (!strcmp(entries[i].word, buffer))
entries[i].counter++;
i++;
}
line_count++;
}
return line_count;
}
void print_result(WordCountEntry entries[], int entry_count)
{
int i = 0;
printf("Result: ");
while (i < entry_count) {
printf("%s:%d ", entries[i].word, entries[i].counter);
i++;
}
}
void printHelp(const char *name)
{
printf("usage: %s [-h] ... ", name);
}
int main(int argc, char **argv)
{
const char *prog_name = *argv;
WordCountEntry entries[5];
int entryCount = 0;
/* Entry point for the testrunner program */
if (argc > 1 && !strcmp(argv[1], "-test")) {
run_smp0_tests(argc - 1, argv + 1);
return EXIT_SUCCESS;
}
argv++;
while (*argv != NULL) {
if (**argv == '-') {
switch ((*argv)[1]) {
case 'h':
printHelp(prog_name);
break;
default:
printf("%s: Invalid option %s. Use -h for help. ", prog_name, *argv);
}
} else{
if (entryCount < LENGTH(entries)) {
entries[entryCount].word = *argv;
entries[entryCount++].counter = 0;
}
}
argv++;
} // end while
if (entryCount == 0) {
printf("%s: Please supply at least one word. Use -h for help. ", prog_name);
return EXIT_FAILURE;
}
if (entryCount == 1) {
printf("Looking for a single word ");
} else {
printf("Looking for %d words ", entryCount);
}
process_stream(entries, entryCount);
print_result(entries, entryCount);
return EXIT_SUCCESS;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.