Как получить * символов и вернуть нецелое число? - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь получить символы с клавиатуры и вернуть двойное число, чтобы я мог записать ввод "number.number", а взамен получить двойное число.number

На данный момент у меня есть следующее код, но моя программа перестает работать при выполнении.

#include<stdio.h>
#include<stdlib.h>

double number(char *ch) {
    double s=1, d=0, x=0;
    char *ch2= 0;

    switch (*ch) {
        case '+':  *ch = getchar(); break;
        case '-':  *ch = getchar(); s = -1; break;
    }
    while ( ('0' <= *ch) && (*ch <= '9') ) {
        d = 10*d + (*ch - '0');
        *ch = getchar();
    }
    if(*ch == '.'){
        *ch2 = getchar();
        while ( ('0'<=*ch2) && (*ch2<='9') ) {
            x = (*ch2 - '0') / 10;
            d = x + d;
        }
    }
    return (s * d);
}   

int main(void) {
    double d;
    char ch;

    ch = getchar();
    d = number(&ch);
    printf("%f",d);

    return 0;
}

Любая помощь приветствуется, и вполне возможно, что в моем коде есть очевидные ошибки, так как я чертовски новичок.

1 Ответ

1 голос
/ 14 января 2020

Прежде всего, было бы проще использовать strtod вместо написания собственной функции для этой задачи.

Во-вторых, ваша структура функций не имеет смысла. Нет смысла читать первый символ из стандартного ввода внутри функции main и читать все последующие символы из другой функции. Вы должны использовать подпрограммы только для указанных c подзадач.

Однако эти две проблемы не являются причиной сбоя вашей программы. Причина в том, что весь код после чтения '.' ссылается *ch2 вместо *ch. В отличие от ch, который указывает на действительный char, указатель ch2 указывает на ничто. Он инициализируется так, чтобы указывать на адрес памяти 0. Следовательно, ваша программа обработает sh, когда вы попытаетесь получить доступ к адресу памяти 0, потому что там нет ничего, к чему ваша программа имеет доступ.

Нет причина иметь этот второй указатель ch2. Если вы удалите строку, в которой он объявлен, и замените все ссылки на него ch, проблема сбоев будет решена.

Однако после исправления этой ошибки ваша программа все равно не будет работать, поскольку у него есть еще одна ошибка. Он застрянет в бесконечном l oop, потому что ваш второй while l oop продолжает проверять, находится ли символ чтения между 0 и 9, не читая никаких новых символов. Следовательно, вы должны добавить строку '* ch = getchar ();' как вы делали в своем первом while l oop.

После исправления этих двух ошибок ваша программа больше не будет обрабатывать sh или застревать в бесконечном l oop. Это все равно не даст правильного результата, так как ваша логика c для вычисления дробной части неверна, но я оставлю это на ваше усмотрение, как решить эту новую проблему.

Однако, что бы я хотел Я хотел бы показать, как лучше структурировать свою программу. Как я уже говорил, не имеет смысла, как вы структурировали свою программу. Вызов getchar как изнутри main, так и изнутри вашей подпрограммы не имеет смысла. Было бы лучше просто написать весь ваш код в функцию main (), если вы не можете найти осмысленный способ разделить вашу программу на несколько функций.

Если вы хотите разделить вашу программу на подпрограмму, я рекомендует следующее:

double read_number()
{
    double s = 1, d = 0, x = 0;
    char c;

    c = getchar();

    switch ( c ) {
    case '+':
        c = getchar();
        break;
    case '-':
        c = getchar();
        s = -1;
        break;
    }

    while ( ('0' <= c) && (c <= '9') ) {
        d = 10 * d + (c - '0');
        c = getchar();
    }

    if ( c == '.' ) {
        c = getchar();
        while ( ('0' <= c) && (c <= '9') ) {
            x = (c - '0') / 10;
            d = x + d;
            c = getchar();
        }
    }

    return(s*d);
}


int main( void )
{
    double d;

    d = read_number();

    printf( "%f", d );

    return 0;
}

Таким образом, вам больше не нужно передавать параметр по указателю (что делает вашу программу излишне сложной).

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

В качестве примечания, я также хотел бы отметить, что, как правило, вы не должны хранить результат getchar в char, а скорее в int, потому что char недостаточно велик для хранения результата, если из getchar возвращается не символ (например, EOF). См. документацию по getchar для получения дополнительной информации. Однако это не причина, по которой ваша программа не работает.

...