1 Востаннє редагувалося koala (05.11.2016 13:53:59)

Тема: С++ алгоритм розгалудження

Доброго дня.
Я вирішую наступну задачу:    з клавіатури вводиться номер місяця. Необхідно вивести на екран до якої пори року відноситься місяць.

Прихований текст
#include <iostream>
using namespace std;
int main(int argc, char* argv[])

{
    char a;
    cout << "a=";
    cin >> a;
    switch (a)
    {
    case '1':
    case '2':
    case '3': cout << "Winter\n";
        break;
    case '4':
    case '5':
    case '6': cout << "Spring\n";
        break;
    case '7':
    case '8':
    case '9': cout << "Summer\n";
        break;
    case '10':
    case '11':
    case '12':
    default:cout << "Autumn\n";
        cin.get();
    return 0;
        
    }
}

Проблем з case 1-9 нема, все виводиться так, як мені потрібно.
При вводі числа 10-12 з клавіатури на екран виводиться повідомлення "Winter", а повинно виводитись "Autumn".

2

Re: С++ алгоритм розгалудження

Прихований текст

Додавайте тег code. Зараз я додав, але наступного разу - самостійно.

char - це символ. Однобайтний. Один. Донедавна комбінація '10' викликала помилку в усіх компіляторах, бо в одинарних лапках два байти. Але через те, що зараз часто використовуються складніші кодування (Юнікод), в деяких компіляторах C++ дозволено кількобайтні комбінації, і проблема стає непомітною при компіляції, а під час виконання зчитується тільки перший символ (1) і це і дає першу гілку switch-а.
Ви вводите число в два символи - для цього вам потрібен рядок (string, char[]) або просто число (int). Раджу зупинитися на останньому варіанті. І тоді приберіть всі лапки - вони тут не потрібні.
І ще загальні поради:
- в реальному коді не використовуйте case, якщо в усіх гілках код розрізняється тільки константами, для цього існують масиви;
- гілку default краще лишати на випадок помилок - наприклад, якщо введено "20".

Подякували: AnderS0N, leofun012

3

Re: С++ алгоритм розгалудження

Немає такого chara — '10'. Ви читаєте '1', а '0', '1' або '2' ігноруєте.

Подякували: AnderS0N1

4 Востаннє редагувалося ReAl (05.11.2016 15:01:39)

Re: С++ алгоритм розгалудження

Хіба що навпаки — «тепер заборонено кількобайтні комбінації» ;)
Виділено мною:

ANSI C SPECIFICATION (C89) написав:

3.1.3.4 Character constants
Syntax
character-constant:
        'c-char-sequence'
        L'c-char-sequence'

Examples

To specify an integer character constant containing the two characters whose values are 0x12 and '3', the construction
'\0223' may be used

Щодо «wide character constant» («зараз часто використовуються складніші кодування»), так для них з 1989 року оте L, а не кілька символів у константі.

Справа в тому, що тут використовується спочатку cin >> a й у символьну змінну a читається лише перший символ з набраних 10/11/12.
До milti-character constant справа просто не доходить, їх нема куди у один char запхати. Хоча незалежно від цього компілятор мав би видати попередження в дусі «case label value exceeds maximum value for type» (бо тип у switch()char, а константа mult-char).

Отак чудово працює (ну, на low-endian ;)
#include <stdio.h>

void fu(unsigned key)
{
        switch (key) {
        case 'dc':
                puts ("Command 'cd'");
                break;
        case 'mr':
                puts ("Command 'rm'");
                break;
        }
}

void fl(unsigned long key)
{
        switch (key) {
        case 'feeb':
                puts("Command 'beef'");
                break;
        case 'daeD':
                puts("command 'Dead'");
                break;
        }
}

void main()
{
        fu('mr');
        fu('c' + ('d'<<8));
        const char *p = "Dead";
        fl( *(unsigned long*)p);
        return 0;
}
Подякували: koala, leofun012

5

Re: С++ алгоритм розгалудження

2.14.3 Character literals
1 A character literal is one or more characters enclosed in single quotes, as in ’x’, optionally preceded by
one of the letters u, U, or L, as in u’y’, U’z’, or L’x’, respectively. A character literal that does not begin
with u, U, or L is an ordinary character literal, also referred to as a narrow-character literal. An ordinary
character literal that contains a single c-char representable in the execution character set has type char,
with value equal to the numerical value of the encoding of the c-char in the execution character set. An
ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter
literal, or an ordinary character literal containing a single c-char not representable in the execution character
set, is conditionally-supported, has type int, and has an implementation-defined value

Подякували: ReAl, leofun012

6

Re: С++ алгоритм розгалудження

Ну от через всі оці «implementation-defined» я цю штуку давно перестав використовувати.
Якось було — двосимвольні команди і switch з unsigned short змінною, займало відчутно менше коду, ніж ланцюжок if/else зі strcmp чи пошук у масиві з наступним таки switch по індексу. Але часи «історії одного байту» давно пройшли.

7

Re: С++ алгоритм розгалудження

Нагадує мені, чому в *NIX приховані файли на . починаються...

8 Востаннє редагувалося -=ЮрА=- (05.11.2016 21:14:28)

Re: С++ алгоритм розгалудження

AnderS0N, навіщо взагалі вибір по чарах?Робимо цілочисельний параметр та його вводимо. Далі по коду йшла помилка, навіть дві - одна логічна, друга концептуальна.
Логічна - чому наприклад 13 місяць повинен бути зачилений до якогось періода - це непідтримуємий ключ вибору а на пора року, а тут плавно підходимо до логічної помилки - нагадую що 12-2 - зима, 3-5 весна 6-8 літо 9-11 осінь, а у вас що?Також вихід зі світчу взагалі тягне на ще +1 помилку

#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
    size_t a;
    cout << "a=";
    cin >> a;
     switch (a)
    {
    case 12:
    case 1:
    case 2: cout << "Winter\n";
        break;
    case 3:
    case 4:
    case 5: cout << "Spring\n";
        break;
    case 6:
    case 7:
    case 8: cout << "Summer\n";
        break;
    case 9:
    case 10:
    case 11:
        cout << "Autumn\n";
        break;
    default:
        cout<<"Unsupported key";
        break;
    }
    cin.get();
    return 0;
}

http://codepad.org/XRQGpcoa

Подякували: AnderS0N1

9

Re: С++ алгоритм розгалудження

-=ЮрА=- написав:

AnderS0N, навіщо взагалі вибір по чарах?Робимо цілочисельний параметр та його вводимо. Далі по коду йшла помилка, навіть дві - одна логічна, друга концептуальна.
Логічна - чому наприклад 13 місяць повинен бути зачилений до якогось періода - це непідтримуємий ключ вибору а на пора року, а тут плавно підходимо до логічної помилки - нагадую що 12-2 - зима, 3-5 весна 6-8 літо 9-11 осінь, а у вас що?Також вихід зі світчу взагалі тягне на ще +1 помилку

#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
    size_t a;
    cout << "a=";
    cin >> a;
     switch (a)
    {
    case 12:
    case 1:
    case 2: cout << "Winter\n";
        break;
    case 3:
    case 4:
    case 5: cout << "Spring\n";
        break;
    case 6:
    case 7:
    case 8: cout << "Summer\n";
        break;
    case 9:
    case 10:
    case 11:
        cout << "Autumn\n";
        break;
    default:
        cout<<"Unsupported key";
        break;
    }
    cin.get();
    return 0;
}

http://codepad.org/XRQGpcoa

Так дійсно, ви праві, мені соромно за помилки. У мене було ще 10 вільних хв і хотів встигнути зробити ще 1 задачу і ось що вийшло... Дякую вам всім за допомогу.