Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > функция вызывает ошибку системы


Автор: jurgal 6.1.2008, 22:47
Код

void money::mstold(char *s)
{
    double d=0;
    int l = static_cast<int>(strlen(s));
    for(int i=0;i<l;i++)
    {
        if(isdigit(s[i]))
            d = d*10+s[i];
        else if(s[i]=='.')
        {
            d = d+s[i+1]/10+s[i+2]/100;
            break;
        }
    }
    m = d;   // m - переменная объекта money
    strcpy_s(str,strlen(s),s); // str - переменная объекта money

}


при выполнении функции система просит отправить рапорт об ошибке в майкрософт =)

Автор: bsa 6.1.2008, 23:09
ошибок в приведенном коде не нашел.
1. возможно, ты передаешь кривой указатель в качестве параметра
2. что за функцмя strcpy_s(), главное, зачем?
3. str указывает куда? память выделена?
4. если твоему методу передать "100.", то может вылететь с ошибкой. Догадайся почему (hint: обрати внимание на точку)

Автор: Fazil6 7.1.2008, 00:19
Цитата(jurgal @  6.1.2008,  21:47 Найти цитируемый пост)
при выполнении функции система просит отправить рапорт об ошибке в майкрософт =)

значит нужно отправить...

Автор: jurgal 7.1.2008, 00:55
Цитата(bsa @  6.1.2008,  23:09 Найти цитируемый пост)
2. что за функцмя strcpy_s(), главное, зачем?

это безопасная функция копирования строк, средний аргумент - длина копируемой строки. С обычной strcpy() VC++ Express не работает, вернее работает, но нужно в начале указывать, чтобы компилятор не обращал внимание на эту опасную(с точки зрения компилятора) старую функцию. 


Цитата(bsa @  6.1.2008,  23:09 Найти цитируемый пост)
str указывает куда? память выделена?


char *str - закрытая переменная класса money, правда я без конструктора класс написал, может быть в этом проблема, инициализировать нулем ('\0') ? Сейчас попробую.


Цитата(bsa @  6.1.2008,  23:09 Найти цитируемый пост)
если твоему методу передать "100.", то может вылететь с ошибкой. Догадайся почему (hint: обрати внимание на точку)

спасибо) понял ошибку, если строка будет 100.  , то выйду за границы массива при увеличении индекса после точки =)


Автор: JackYF 7.1.2008, 01:02
Цитата(jurgal @  6.1.2008,  23:55 Найти цитируемый пост)
старую функцию. 

да уж,  smile а мужики-то не знают... 

Цитата(jurgal @  6.1.2008,  23:55 Найти цитируемый пост)
правда я без конструктора класс написал, может быть в этом проблема

скорее всего. Память выделить под строку надо.

Автор: bsa 7.1.2008, 01:08
Цитата(jurgal @ 7.1.2008,  00:55)
char *str - закрытая переменная класса money, правда я без конструктора класс написал, может быть в этом проблема, инициализировать нулем ('\0') ? Сейчас попробую.

Твоя ошибка в этом месте. strcpy не выделяет память под переменную. Поэтому ты должен либо сделать str статическим массивом (char str[1000]) или перед выполнением strcpy выделять память.
Кстати, если уж на то пошло, что надо писать не strcpy_s(str, strlen(s), s), а strcpy_s(str, str_size, s), где str_size - объем выделенной памяти под str

Автор: jurgal 7.1.2008, 03:58
Код

class money
{
    double m;
    char str[100];
public:
    money(){m=0; str[0]='\0';}
    void mstold(char *s);
    void disp()const
    {
        cout << m << endl;
    }

};

void money::mstold(char *s)
{
    double d=0;
    int l = static_cast<int>(strlen(s));
    for(int i=0;i<l;i++)
    {
        if(isdigit(s[i]))
            d = d*10+(s[i]);
        else if(s[i]=='.')
        {
            d = d+s[i+1]/10+s[i+2]/100;
            break;
        }
    }
    m = d;

}

int main()
{
    money mon;
    char str1[100];
    cout << "Input string: ";
    cin >> str1;
    mon.mstold(str1);
    mon.disp();


    return 0;
}


сейчас работает, но результат не правильный. strcpy_s() вообще убрал пока, чтобы не смущало =) . 

допустим если ввести 45, то результатом будет 573 , т.е. он переводит 4 по ASCII в 52, затем умножает на 10 и прибавляет к 5 переведенной через ASCII в 53 и в итоге получается 573. Что то я запутался, ведь isdigit() проверяет символ аргумент или число. Пытался функцией atoi() каждый символ который isdigit преобразовать в int, но компилятор ругается на невозможность такого преобразования. Хелп =)

Автор: Kuvaldis 7.1.2008, 04:48
Код

d = d*10+(s[i]);


Надо
Код

d = d*10+(s[i] - '0' );

Потому что код цифры и ЗНАЧЕНИЯ цифры - это разные вещи... и отличаются на 48
Для переносимости вычитаем из кода цифры код нуля (это как раз и есть 48 = 0x30 )

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)