2017-01-20 4 views
0

Очень новый для программирования по достоинству оценят помощь.
У меня есть следующие программы для подсчета слов, которые вводятся в командной строкеЗаявление о печати не выводит результат

, например:

> ./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 не выводит даже оператор «Результат:»

+2

1) Необходимо удалить новую строку из 'buffer'. 2) 'i <= entry_count;' -> 'i 'const char * prog_name = * argv ++;' (для skip argv [0]) 4) «freopen» и обработка аргументов неправильны. 5) – BLUEPIXY

+1

Функция 'help' не позволяет пользователю узнать о опции '-f outfile'. –

+0

для удобства чтения и понимания: 1) последовательно отступать код. отступ после каждой открывающей скобки '{'. unindent перед каждой закрывающей скобкой '}', предлагайте 4 пробела для каждого уровня отступа, как это видно даже с изменяемыми ширинами шрифта. 2) отдельные блоки кода (для if, else, while, do ... while, switch, case, default) через пустую строку. 3) следуйте аксиоме: * только один оператор на строку и (самое большее) одно объявление переменной для каждого оператора. * 4) рассмотрите закрывающую скобку '}' как отдельный оператор. – user3629249

ответ

0

Put fflush(stdout); в конце вашей основной функции. Это должно вывести все на стандартный вывод.

1

Вы делаете вещи намного сложнее, чем вам нужно. В то время как вы можете использовать арифметику указателей перебирать струны в argv, пока вы не достигнете дозорного NUL, вы гораздо лучше служили переборе for (i = 1; i < argc; i++), используя массив индексации для этой цели. (не забывайте, что первая запись, индекс 0 - это имя программы).

Ваше использование freopen как есть, полностью затмит все выходные данные для вашей программы. Вместо того, чтобы вызывать freopen, когда вы тестируете -f, было бы лучше задать переменную имени файла сохранения. Затем, когда вы выводите свои результаты, вы просто проверяете, есть ли выходное имя файла, и если да, сделайте простой вызов fopen. Я оставлю вас думать о реализации.

Как уже упоминалось в комментариях, fgets читает до и включая '\n' и включает в себя символ новой строки в буфере. Для того, чтобы сравнить entries[x].word с buffer, необходимо удалить заднюю '\n' перед сравнением, поскольку текущее сравнение никогда не будет соответствовать, например .:

strcmp ("foo", "foo\n") 

Наконец логика петли просто немного запутался. Вы можете делать это так, как только это будет работать, но простота и чистота помогут вам сохранить индексирование прямо в вашем уме.

Положив эти кусочки мозаики вместе, вы могли бы сделать относительно немного изменений и выполните следующие действия:

#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; 
} 

примечание: если вы используете C89, то вам нужно будет самостоятельно объявить i снаружи:

for (int i = 0; i < entry_count; i++) { 

Пример использования/выход

$ ./bin/printfissue one two three "four and a half" five 
Looking for 5 words 
one 
two 
three 
four and a half 
five 

Result: 
one:1 
two:1 
three:1 
four and a half:1 
five:1 

Посмотрите все и сообщите мне, если у вас есть дополнительные вопросы. Существует множество способов сделать петли и индексирование, поэтому это не значит, что вы можете это сделать, или даже самый правильный способ сделать это в этом отношении.

Смежные вопросы