0 / 0 / 0
Регистрация: 22.02.2015
Сообщений: 9
1

Задача по книге Р. Лафоре

24.05.2019, 18:26. Показов 2042. Ответов 6

Пример по книге Лафоре... (Система Windows 10/64bit.)
Я знаю что на форуме есть решения но я хочу своим умом понять и решить, к тому же код там написан извольте промолчать... .
Я лишь хочу чтобы мне указали на мои ошибки!
Кстати как я понял из задания проблему нужно решить именно как массив символов, в моем понимении это char[]...
(... Вам нужно будет обработать денежную строку как массив символов)

Проблема 1:
В main() он придерается к этому куску кода:
C++
1
while ((ch != 'n') || (ch != 'N'))
после ввода 'n' или 'N' или любого другого сивола зациклевается все...
если ввести так:
C++
1
while ((ch != 'n') && (ch != 'N'))
выход осуществляется но повторить цикл невозможно, после ввода любого другого символа зациклевается все...

Проблема 2:
В этом куске не происходит копирование из char в char.
C++
1
2
if ((strmoney[i] >= '49' && strmoney[i] <= '57') || strmoney[i] == '.')
          strtemp[i] = strmoney[i];
переменная
C++
1
 strtemp[i];
выводит просто мусор: MMMMMMMMMMMMMMMMMMMMMMMMMM... .

Проблема 3:
в функции
C++
1
atof(strmoney)
нет вещественной точки, если есть запятая, то на его место выводится точка.
Например, ввод: 123,465,789.25
Вывод: 123.465
Если без запятых...
Например, ввод: 123465789.25
Вывод: 123465789

вот собственно и код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <cstdlib>
using namespace std;
//================================================================
class money
{
private:
    double Dmoney;
public:
    money() : Dmoney(0)
    {}
    money(double Dm) : Dmoney(Dm)
    {}
    double MS_told(char[]);
};
//================================================================
const int SIZE = 22;
//================================================================
double money::MS_told(char strmoney[])
{
    double msmoney = 0.0;
    char strtemp[SIZE];
    for (int i = 0; i < strlen(strmoney); i++)
    {
        if ((strmoney[i] >= '49' && strmoney[i] <= '57') || strmoney[i] == '.')
            strtemp[i] = strmoney[i];
        strtemp[i] = '\0';
    }
    msmoney = atof(strmoney);
        // Вывод для проверки...
    cout << "MS_told strmoney = " << strmoney << endl;
    cout << "strtemp = " << strtemp << endl;
    cout << "msmoney = " << msmoney << endl;
 
    return msmoney;
}
//================================================================
int main()
{
    setlocale(LC_ALL, "RUSSIAN");
    char strmoney[SIZE], ch = NULL;
    double Mmoney = 0.0;
    money m;
    cout << "Программа перевода денежной строки из char в double." << endl;
    while ((ch != 'n') || (ch != 'N'))
    {
        cout << "Введите денежную строку: "; cin.get(strmoney, SIZE);
        Mmoney = m.MS_told(strmoney);
        cout << "Результат вывода программы: " << Mmoney << endl;
        cout << "Продолжить ввод данных(y/n)?: "; cin >> ch;
    }
 
    cin.get();
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.05.2019, 18:26
Ответы с готовыми решениями:

Задачник для изучения по книге Лафоре
Посоветуйте норм задачник для новачка изучаю с++ по книге Лафорте.

Как привести дробь к несократимому виду? Есть ли ошибки в книге Лафоре?
Добрый день! В книге Лафоре по С++ есть пример, того как привести дробь к несократимому виду. У...

Проблемы с переводом строки в число (по книге Лафоре "ООП в С ++ ")
Лафоре &quot;ООП в Си ++ &quot; - проблемы с упражнением 12, глава 7 Условие: Напишите программу,...

Разобраться в примерх к книге Лафоре "Обьектно-ориентированое программирование в С++"
Всем доброго времени суток кто читает эту тему. Сегодня, изучая С++ по книге Лафоре...

6
Вездепух
Эксперт CЭксперт С++
10820 / 5841 / 1585
Регистрация: 18.10.2014
Сообщений: 14,496
24.05.2019, 18:52 2
Цитата Сообщение от UMD Посмотреть сообщение
(strmoney[i] >= '49' && strmoney[i] <= '57')
Что такое '49' и '57'? Что вы хотели сказать этим синтаксисом?
0
0 / 0 / 0
Регистрация: 22.02.2015
Сообщений: 9
24.05.2019, 19:27  [ТС] 3
это код ASCII. где '49' это цифта 0, соответственно '57' это 9
тоесть нужно скопировать в локальную переменную только цифры.
Для дальнейшей перечи в msmoney типа double.

Добавлено через 6 минут
Цитата Сообщение от UMD Посмотреть сообщение
msmoney = atof(strmoney);
Произошла очепятка
msmoney = atof(strtemp); правельней
0
Прощай, Мир!
1672 / 829 / 253
Регистрация: 26.05.2012
Сообщений: 3,057
25.05.2019, 14:14 4
Лучший ответ Сообщение было отмечено UMD как решение

Решение

Цитата Сообщение от UMD Посмотреть сообщение
for (int i = 0; i < strlen(strmoney); i++)
чтобы использовать функцию strlen( ) нужно подключить директиву препроцессора в начале программы..
C++
1
#include <string.h>
Цитата Сообщение от UMD Посмотреть сообщение
if ((strmoney[i] >= '49' && strmoney[i] <= '57') || strmoney[i] == '.')
strtemp[i] = strmoney[i];
strtemp[i] = '\0';
здесь зачем ты заполняешь буквально все элементы массива strtemp[ ] значением нуль терминала!? т.к. это присвоение произойдет при любом раскладе выполнения или не выполнения кода в инструкции if.. лучше напиши после самого блока кода for строку..
C++
1
strtemp[strlen(strmoney)]='\0';
Цитата Сообщение от UMD Посмотреть сообщение
if ((strmoney[i] >= '49' && strmoney[i] <= '57') || strmoney[i] == '.')
Цитата Сообщение от UMD Посмотреть сообщение
это код ASCII. где '49' это цифта 0, соответственно '57' это 9
имхо, здесь у тебя используются не ASCII коды, а строки из двух символов-цифр.. если надо ASCII коды цифр, то так прямо и указывай..
C++
1
if ((strmoney[i] >= '0' && strmoney[i] <= '9') || strmoney[i] == '.')
также имей ввиду, что при присваивании элементу массива strtemp значения элемента массива strmoney индексы могут отличаться, т.к. в первый не копируются и пропускаются символы со второго отличные от цифр и знака точка..
C++
1
2
strtemp[j]=strmoney[i];
j++;
Цитата Сообщение от UMD Посмотреть сообщение
while ((ch != 'n') || (ch != 'N'))
такое условие в корне неверное, т.к. оно несовместимое.. лучше использовать в конце блока кода while условие if..
C++
1
2
3
4
5
6
7
8
9
10
11
12
if(ch=='n' || ch=='N')
{
    break;
}
else if(ch=='y')
{
    continue;
}
else
{
    break;
}
но суть дела не в этом.. тебе требуется очищать буфер перед вводом новой строки, т.к. после ввода символа ch и нажатия клавиши Enter в буфере будет находится символ переноса строки "\n", который будет автоматически записываться в массив strmoney..
C++
1
cin.ignore()
вобщем вот весь измененный код.. желаю успехов в его заборе (тьфу-ты.. разборе)..
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <string.h>
#include <cstdlib>
using namespace std;
//================================================================
class money
{
private:
    double Dmoney;
public:
    money() : Dmoney(0)
    {}
    money(double Dm) : Dmoney(Dm)
    {}
    double MS_told(char[]);
};
//================================================================
const int SIZE = 22;
//================================================================
double money::MS_told(char strmoney[])
{
    double msmoney = 0.0;
    char strtemp[SIZE];
    for (int i=0,j=0;i<(int)strlen(strmoney);i++)
    {
        if ((strmoney[i] >= '0' && strmoney[i] <= '9') || strmoney[i] == '.')
        {
            strtemp[j]=strmoney[i];
            j++;
        }
    }
    strtemp[strlen(strmoney)]='\0';
 
    msmoney = atof(strtemp);
        // Вывод для проверки...
    cout << "MS_told strmoney = " << strmoney << endl;
    cout << "strtemp = " << strtemp << endl;
    cout << "msmoney = " << msmoney << endl;
 
    return msmoney;
}
//================================================================
int main()
{
    setlocale(LC_ALL, "RUSSIAN");
    char strmoney[SIZE], ch;
    int f=0;
    double Mmoney = 0.0;
    money m;
 
    cout<<"Программа перевода денежной строки из char в double." << endl;
 
    while(true)
    {
        cout<<"\nВведите денежную строку: ";
        if(f==0)
        {
            f=1;
        }
        else
        {
            cin.ignore();
        }
        cin.get(strmoney,SIZE);
        Mmoney=m.MS_told(strmoney);
        cout<<"Результат вывода программы: "<<Mmoney<<endl;
        cout<<"Продолжить ввод данных(y/n)?: ";
        cin>>ch;
 
        if(ch=='n' || ch=='N')
        {
            break;
        }
        else if(ch=='y')
        {
            continue;
        }
        else
        {
            break;
        }
    }
 
    return 0;
}
1
0 / 0 / 0
Регистрация: 22.02.2015
Сообщений: 9
25.05.2019, 16:31  [ТС] 5
На сколько мне известно функция strlen(); в C++ помещена в пространство имен std;
Или как минимум в моем компиляторе, в заголовочном файле <iostream> уже включен <cstring>
В конечном счете я с вами согласен, лучше подключать <cstring>, так как не во всех компиляторах это реализовано.
(Хочу заметить, я не умничаю, просто читал об этом, если же ошибаюсь прошу наставить на путь истинный).

здесь я понял, так же понял про ASCII коды, и указал прямо цифры, спасибо!

C++
1
2
3
if ((strmoney[i] >= '0' && strmoney[i] <= '9') || strmoney[i] == '.') 
        strtemp[i] = strmoney[i]; 
strtemp[i + 1] = '\0';
что касается strtemp[strlen(strmoney)]='\0'; я реализовал так: strtemp[i + 1] = '\0'; тоже заработало
но ваш способ наглядней, и легко читаем, хоть и длиннее

здесь я сам не понял почему, но все заработало после ввода cin >> strmoney;
C++
1
2
3
4
5
6
7
    while (ch != 'n' && ch != 'N')
    {
        cout << "Введите денежную строку: "; cin >> strmoney;
        Mmoney = m.MS_told(strmoney);
        cout << "Результат вывода программы: " << Mmoney << endl;
        cout << "Продолжить ввод данных(y/n)?: "; cin >> ch;
    }
Вообщем спасибо вам большое за разъяснение, но есть одно НО...
Что в вашем примере, что в моем примере, функция atof(); не передает точку например:
Ввод: 123456.55
Вывод: 123456
Если есть запятая после нее(запятой) не выводится нечего
Ввод: 123,456.55
Вывод 123
Я склоняюсь к тому что фукнция atof() не работает правильно через фунцию MS_told();
Потому что когда я запускаю функцию atof() в main() пример:
Ввод: 123,456.78
Вывод 123.456
Если же ввести с точкой:
Ввод: 123.45
Вывод: 123
Я предполагаю это связано с setlocale(,,); но разобраться я не смог в этом вопросе.
0
Прощай, Мир!
1672 / 829 / 253
Регистрация: 26.05.2012
Сообщений: 3,057
26.05.2019, 09:43 6
Лучший ответ Сообщение было отмечено UMD как решение

Решение

Цитата Сообщение от UMD Посмотреть сообщение
здесь я понял
Цитата Сообщение от UMD Посмотреть сообщение
if ((strmoney[i] >= '0' && strmoney[i] <= '9') || strmoney[i] == '.')
strtemp[i] = strmoney[i];
strtemp[i + 1] = '\0';
по-моему, ты ничего не понял.. я же сказал ранее, что для массива strtemp должны идти свои индексы (например, j а не i)..
и присвоение нуль терминального символа должно происходить после всего цикла for, а не после if.. например, так..
C++
1
2
3
4
5
6
7
8
9
10
11
12
int j=0;
 
for (int i=0;i<(int)strlen(strmoney);i++)
{
    if ((strmoney[i] >= '0' && strmoney[i] <= '9') || strmoney[i] == '.')
    {
        strtemp[j]=strmoney[i];
        j++;
    }
}
 
strtemp[j]='\0';
и только тогда у тебя будут пропускаться буквы в исходной строке и записываться только цифры и точка во временную строку..
проверь свой код и мой.. замечаешь разницу!?
Задача по книге Р. Лафоре


Цитата Сообщение от UMD Посмотреть сообщение
Что в вашем примере, что в моем примере, функция atof(); не передает точку
Цитата Сообщение от UMD Посмотреть сообщение
Я склоняюсь к тому что фукнция atof() не работает правильно через фунцию MS_told();
это не вина функции atof.. просто выводить значение msmoney нужно с помощью манипуляторов..
C++
1
2
3
#include <iomanip>
...
cout << setiosflags(ios::fixed)<<setprecision(8) << "msmoney = " << msmoney << endl;
смотри скриншот..
Задача по книге Р. Лафоре


Цитата Сообщение от UMD Посмотреть сообщение
Если есть запятая после нее(запятой) не выводится нечего
а какой смысл тестирования программы с запятой, если она (запятая) не копируется во временную строку!? ведь именно временная строка преобразуется в число типа double.. да и вообще функция atof вроде работает только с точкой.. число может заканчиваться любым символом, который не может являться частью числа с пла*вающей точкой. например, этим символом может быть пробел, знак пунктуации, отличный от точки, буква, отличная от «Е» или «е»..
1
Вездепух
Эксперт CЭксперт С++
10820 / 5841 / 1585
Регистрация: 18.10.2014
Сообщений: 14,496
27.05.2019, 22:14 7
Цитата Сообщение от UMD Посмотреть сообщение
это код ASCII. где '49' это цифта 0, соответственно '57' это 9
Код ASCII для '0' и '9' - это 49 и 57. У вас же в коде написано '49' и '57'. Это никакие не "коды ASCII".
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.05.2019, 22:14
Помогаю со студенческими работами здесь

Задача из Лафоре
Для разъяснения действия наших доморощенных указателей мы смоделируем память компьютера с помощью...

Задача из Лафоре
есть задачка из Лафоре -&gt; Модифицируйте класс bMoney из упражнения 12 главы 7 «Массивы и...

Не компилируется задача из Лафоре
Помогите пожалуйста разбораться почему компилятор ругается: 1&gt;L.obj : error LNK2019: unresolved...

Лафоре задача по классам
Задача из книги лафоре по классам №7: нужно написать программу используя классы для ввода и вывода...

Очередь (задача из Лафоре)
Задача 9 из Лафоре: Надо написать класс queue, имеющий два метода: put() для помещения элемента в...

Лафоре. Глава 11. Задача 2
Решал задачку из учебника - Лафоре. Глава 11. Задача 2. Вот код #include &lt;iostream&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru