LINUX.ORG.RU

Простая программа в С, проблема с while loop и input

 , ,


1

1

Добрый день!

Пожалуйста, посмотрите небольшую программу. Я новичок, поэтому прошу снисходительности и помощи.

Задание было следующее: предположим, что количество воды, затраченное в течение одной минуты, проведенной под душем, эквивалентно 12 бутылкам воды. Цель программы запросить пользователя ввести количество минут, которые он/она проводит в душе и выдать количество бутылок воды.

Используются допущения: не проверять на положительные - отрицательные числа (правда я знак добавила). Если вводятся числа, то программа выдает количество бутылок. Если вводится слово (например, foo или 123abc), то программа должна снова ожидать ввод данных.

С последним у меня проблема. Если вводится foo или 123abc, то программа выдает 0. То есть с одной стороны, неверные значения не принимаются, но и запрос на новый ввод тоже не происходит. Вот тест:

reject "foo" minutes
   \ expected prompt for input, not exit code of 0 
 rejects "123abc" minutes
   \ expected prompt for input, not exit code of 0
То есть выдает такой результат: foo 0 Пожалуйста, помогите разобраться.
#include <stdio.h>
#include <ctype.h>

#define MAX 5000
#define BOTTLES_PER_MINUTE 12
int minutes[MAX];

void get_minutes(int minutes[]);
int char_to_digit(int minutes[]);

int main(void)
{
    printf("Please, enter the number of minutes\n");
    get_minutes(minutes);
    
    printf("%d\n", (char_to_digit(minutes) * BOTTLES_PER_MINUTE));
    
    return 0;
}
/* get minutes from the user, fill in the array */
void get_minutes(int minutes[])
{
    int i = 0;
    int c;
    
    while (!isspace(c = getchar()))
    {
        if (isalpha(c))
        {
            continue;
        }
        else
        {
            minutes[i] = c;
            i++;
        }
    }
    
    minutes[i] = '\0';
    
}
/*convert input into digits */
int char_to_digit(int minutes[])
{
    int i = 0;
    int n, sign;
    
    sign = (minutes[i] == '-')? -1: 1;
    if (minutes[i] == '-' || minutes[i] == '+')
    {
        i++;
    }
    
    for (n = 0; minutes[i] != '\0'; i++)
    {
        n = 10 * n + (minutes[i] - '0');
    }
    
    return sign * n;
}

Перемещено beastie из general


Зачем такой огород?

$ cat bottles.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv){
        double minutes;
        if(argc < 2){
                printf("usage: bottles minutes\n");
                return 1;
        }
        minutes = atof(argv[1]);
        printf("You need %lf bottles.\n", 12 * minutes);
        return 0;
}

saahriktu ★★★★★ ()
Ответ на: комментарий от saahriktu

Спасибо. Действительно Ваше решение красивое и лаконичное. Но: 1) по заданию не подразумевается использовать command line arguments 2) нужно prompt the user for input 3) Ваш вариант тоже выдает 0 на foo, а на 123abc выдает 1476; а программа должна при таких вводных снова требовать введение данных

Как быть?

Ducol ()
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>

#define BUFFER_SIZE 64

int main() {
    char buffer[BUFFER_SIZE];
    intmax_t val = 0;
    char *pend;
    size_t len;

    for(;;) {
           printf("enter a number: ");
           if(fgets(buffer,BUFFER_SIZE,stdin)) {
               len = strlen(buffer);
               if(len!) break; /* let me outta here! */
               val = strtoimax(buffer,&pend,10);
               if(pend-buffer == len-1)
                   break;
           }
           printf("wrong input\n");
    }
    printf("the number: %jd\n",val);

    return EXIT_SUCCESS;
}

как-то так, наверное. в попугаев (бутылки) сами переводите.

Iron_Bug ★★★★★ ()
Ответ на: комментарий от unt1tled

вам меня не убить, поверьте. а мне можно писать даже три команды в одной строке.

Iron_Bug ★★★★★ ()
Ответ на: комментарий от i-rinat

ну да, можно так. просто не люблю безвыходные циклы. надо же дать юзеру шанс избавиться от ввода цифирек без паники и Сtrl-C.

Iron_Bug ★★★★★ ()
Ответ на: комментарий от itn

Ctrl-C это SIGINT в стандартно настроенном терминале.

tiandrey ★★★★★ ()
Ответ на: комментарий от Ducol

по заданию не подразумевается использовать command line arguments

В Job.

FIL ★★★★ ()
Ответ на: комментарий от saahriktu

шиньити мочидзуки

ситуация с ним, на самом деле, типичная в программировании, и непонимание его подхода тоже весьма типично (как и непонятки «зачем нам нужен емакс с елипом ну или текст как интерфейс в текстовом редакторе из оберон-систем») :

* он изобрёл свой метаязык и метод, на котором изложил доказательство. примерно так же, как дональд кнут изобрёл WEB, Literate Programming подход.

* на этом метаязыке решил свою задачу, и попытался обобщить для других решений, наиболее универсальным способом. примерно как кнут с LP или теодор холм нельсон с xanadu. или jwz c bbdb и intertwignle

** или турчин с рефалом и суперкомпиляцией и метасистемным переходом.

* «некоторые вещи непонятны нам не потому что в принципе непонятны, а потому что лежат за пределами нашего понимания» (с) козьма прутков. то есть, непонятно ибо ненужно. например, в XEmacs есть гипертекстовый пакет hyperbole, в котором можно делать ссылки кнопками на функции на елиспе.

** непонятно зачем. другое дело, если генерировать их например из скрипта на елиспе, обработав запрос к Gopher+ серверу с отдельным +View на ресурс.

* опять же, обучение на примерах и «знание фактов», о вещах. либо обучение на концептах и знание архитектуры — о структуре процессов (в метасистемах, см. закон Конвея), порождающих вещи.

в целом: нужно продвигать метапрограммирование в массы: лисповые макросы и функции первого порядка в программировании, емакс в текстовых редакторах, мочидзуки с его метаязыком — в математике, теда нельсона с его ксанаду и двусторонними семантическими гиперссылками — в гипертекстах, емакс с елиспом и оберон с «текст как интерфейс»...

это сдвиг мышления — новости из мира кластера метапарадигм.

метасистемный переход — чётко по турчину.

(порождение компилятора автоматически, суперкомпиляцией интерпретатора. то есть: клавиатурных макросов на елиспе. программист заменяется метасистемой: метапрограммой на елиспе, работающей в гипертекстовой WEB/LP среде)

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.