非常新的编程将非常感谢帮助。
我有以下程序来计算在命令行中输入的单词
例如:
> ./main cat nap dog
Given input:
cat
.
Expected output:
Looking for 3 words
Result:
cat:1
nap:0
dog:0
这是我为它写的代码:
#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 (fgets(buffer,sizeof(buffer),stdin)) {
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)
{
fprintf(stdout,"Result:\n");
for(int i=0; i <=entry_count;i++){
printf("%s:%d\n", entries[i].word, entries[i].counter);
}
}
void printHelp(const char *name)
{
fprintf(stderr,"usage: %s [-h] <word1> ... <wordN>\n", name);
}
int main(int argc, char **argv)
{
const char *prog_name = *argv;
WordCountEntry entries[argc];
int entryCount = 0;
while ((*argv) != NULL) {
if (**argv == '-') {
switch ((*argv)[1]) {
case 'h':
printHelp(prog_name);
break;
case'f':
freopen((*argv)[2],"w",stdout);
break;
default:
fprintf(stderr,"%s: Invalid option %s. Use -h for help.\n",
prog_name, *argv);
}
} else {
if (entryCount < argc-1) {
entries[entryCount].word = *argv;
entries[entryCount++].counter = 0;
}
}
argv++;
}
if (entryCount == 0) {
fprintf(stderr,"%s: Please supply at least one word. Use -h for help.\n",
prog_name);
return EXIT_FAILURE;
}
if (entryCount == 1) {
fprintf(stdout,"Looking for a single word\n");
} else {
fprintf(stdout,"Looking for %d words\n", entryCount);
}
process_stream(entries, entryCount);
print_result(entries, entryCount);
return EXIT_SUCCESS;
}
我似乎无法弄清楚为什么print_result函数甚至不输出“Result:”语句
答案 0 :(得分:1)
你在自己身上做的事情比你需要的要难得多。虽然您可以使用指针算术来迭代argv
中的字符串,直到您到达 sentinel nul ,但您可以更好地迭代{{1}为此目的使用数组索引。 (不要忘记第一个条目,索引for (i = 1; i < argc; i++)
是程序名称)。
您按原样使用0
将完全模糊您程序的所有输出。在测试freopen
时,不如调用freopen
,最好设置保存文件名变量。然后,当您输出结果时,只需测试是否有输出文件名,如果有,请简单地调用-f
。我会让你考虑实施。
正如评论中所述,fopen
读取 ,包括fgets
,并在缓冲区中包含换行符。为了将'\n'
与entries[x].word
进行比较,您需要在比较之前删除尾随buffer
,因为您当前的比较将永远不会匹配,例如:
'\n'
最后,循环逻辑有点混乱。你可以自由地做任何有效的方式,但保持简单和干净将极大地帮助你在你的脑海中保持索引。
将这些拼图放在一起,您可以进行相对较少的更改并执行以下操作:
strcmp ("foo", "foo\n")
注意:如果你使用C89,那么你需要在外面独立声明#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Structures */
typedef struct {
char *word;
int counter;
} WordCountEntry;
int process_stream (WordCountEntry entries[], int entry_count)
{
short line_count = 0;
char buffer[30];
while (fgets (buffer, sizeof (buffer), stdin)) {
if (*buffer == '.')
break;
/* strip trailing '\n' from buffer */
size_t len = strlen (buffer); /* get word length */
if (buffer[len - 1] == '\n') /* check for '\n' */
buffer[--len] = 0; /* overwrite with nul-byte */
/* Compare against each entry */
if (!strcmp (entries[line_count].word, buffer))
entries[line_count].counter++;
if (++line_count == entry_count)
break;
}
return line_count;
}
void print_result (WordCountEntry entries[], int entry_count)
{
fprintf (stdout, "\nResult:\n");
for (int i = 0; i < entry_count; i++) {
printf ("%s:%d\n", entries[i].word, entries[i].counter);
}
}
void printHelp (const char *name)
{
fprintf (stderr, "usage: %s [-h] <word1> ... <wordN>\n", name);
}
int main (int argc, char **argv)
{
const char *prog_name = *argv;
WordCountEntry entries[argc];
int entryCount = 0;
for (int i = 1; i < argc; i++) {
if (*argv[i] == '-') {
switch (argv[i][1]) {
case 'h':
printHelp (prog_name);
break;
default:
fprintf (stderr, "%s: Invalid option %s. Use -h for help.\n",
prog_name, *argv);
}
}
else {
entries[entryCount].word = argv[i];
entries[entryCount++].counter = 0;
}
}
if (!entryCount) {
fprintf (stderr,
"%s: Please supply at least one word. Use -h for help.\n",
prog_name);
return EXIT_FAILURE;
}
if (entryCount == 1) {
fprintf (stdout, "Looking for a single word\n");
}
else {
fprintf (stdout, "Looking for %d words\n", entryCount);
}
process_stream (entries, entryCount);
print_result (entries, entryCount);
return EXIT_SUCCESS;
}
:
i
示例使用/输出
for (int i = 0; i < entry_count; i++) {
仔细看看,如果您有其他问题,请告诉我。有许多不同的方法可以进行循环和索引,所以这并不是你能做到的唯一方法,甚至是最正确的方法。
答案 1 :(得分:0)
将fflush(stdout);
放在主要功能的末尾。这应该将所有内容清除到标准输出。