1

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

Всім привіт.
Допоможіть мені будь ласка вирішити задачу.
З клавіатури вводитися символ. Визначити, чи є цей символ буквою, цифрою, розділовим знаком чи іншим символом.
Я не розумію як це зробити.
Середовище в якому я працюю - Microsoft Visual Studio Community 2015.
Мої спроби рішити цю задачу:

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

#include <iostream>;
using namespace std;
int main()
{
    char s;
   
    cout << "s=";
    cin >> s;
    if(s == )
    system("pause");
   

}

Дякую.

2

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

#include <cctype>

Також можна взяти std::ctype з locale, але то, мабуть, заскладно поки що для вас буде.

Подякували: Betterthanyou, AnderS0N2

3 Востаннє редагувалося 0x9111A (04.11.2016 16:51:37)

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

Вирішіть задачу "...визначити чи символ це A"

4

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

koala написав:

#include <cctype>

Також можна взяти std::ctype з locale, але то, мабуть, заскладно поки що для вас буде.

Я ознайомився з інформацією, яку ви мені підсказали переглянути. Я скопіював приклад з Вікіпедії і вставив у Visual Studio, на жаль мені видало декілька помилок. Що я зробив не так?

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

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

int main()
{
    unsigned char c;

    do {
        scanf("%c", &c);

        if (isdigit(c))
            printf("You have input a number %i", atoi(&c));
        else
            printf("It is not a number!");
    } while (c != EOF);

    return 0;
}

Помилки, які мені показує Visual Studio

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

Перша помилка: Ошибка (активно) аргумент типа "unsigned char *" несовместим с параметром типа "const char *".
Друга помилка:  Ошибка C2664 "int atoi(const char *)": невозможно преобразовать аргумент 1 из "unsigned char *" в "const char *".
Третя помилка: Ошибка C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

5 Востаннє редагувалося Kizyak (04.11.2016 18:14:05)

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

Вибачте будь ласка, хоч я сам й ідіот, але як ви таке можете не зрозуміти?

AnderS0N написав:
koala написав:

#include <cctype>

Також можна взяти std::ctype з locale, але то, мабуть, заскладно поки що для вас буде.

Я ознайомився з інформацією, яку ви мені підсказали переглянути. Я скопіював приклад з Вікіпедії і вставив у Visual Studio, на жаль мені видало декілька помилок. Що я зробив не так?

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

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

int main()
{
    unsigned char c;

    do {
        scanf("%c", &c);

        if (isdigit(c))
            printf("You have input a number %i", atoi(&c));
        else
            printf("It is not a number!");
    } while (c != EOF);

    return 0;
}

Помилки, які мені показує Visual Studio

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

Перша помилка: Ошибка (активно) аргумент типа "unsigned char *" несовместим с параметром типа "const char *".
Друга помилка:  Ошибка C2664 "int atoi(const char *)": невозможно преобразовать аргумент 1 из "unsigned char *" в "const char *".
Третя помилка: Ошибка C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

#include <stdio.h>
#include <ctype.h>

int main ( int argc, char **argv )
{
    char c;         /* не unsigned! */
    
    /* якщо пише використати scanf_s, то використайте його
       замість scanf */
    scanf ("%c", &c );

    if (isdigit (c)) {
        /* c - число */
    }
    else if (isalpha (c)) {
        /* c - літера */
    }
    else {
        switch (c) {
        case '-':
        case '.':
        case  '!':
        case ':':
        case '(':
        case ')':
        case '?':
        case ',':
        case '\"':
            /* розділовий знак */
            break;
        default:
            ;/* якийсь інший розділовий знак */
        }
    }

    return (0);
}

6

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

Пане, вибачте, але якщо ви неуважно читали - то приклад мовою C. Так, вона переважно сумісна з C++, але ви питали про конкретні функції, які сумісні повністю. Отже:
- в майкрософтівських версіях C++ функція scanf вважається застарілою (але ж я її вам не радив використовувати!). Користуйтеся своїм cin::operator >>.
- C++ поводиться з типами обережніше, ніж C, і не виконує неявного перетворення типів в деяких випадках. Зокрема, без unsigned воно запрацює.
- atoi - це реально помилка в Вікі; дякую, що допомогли її виявити, я вже виправив код там.

7

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

я на с++ не писав уже напевно років 4, в мене вийшло щось таке

#include "stdafx.h"
#include <iostream>
#include <string>

using namespace std;

bool IsLetter(char symbol)
{
    return isalpha(symbol) > 0;
}

bool IsDigit(char symbol)
{
    return isdigit(symbol) > 0;
}

bool IsPunctuationSymbol(char symbol)
{
    const string punctSymbols = string(",.;:!?");
    return punctSymbols.find_first_of(symbol, 0) != string::npos;
}

int main()
{
    string s;
    cout << "Please enter symbol: \t";
    cin >> s;

    auto symbol = s[0];

    if (IsLetter(symbol)) {
        cout << " Symbol is letter" << endl;
    }
    else if (IsDigit(symbol)) {
        cout << " Symobl is digit" << endl;
    }
    else if (IsPunctuationSymbol(symbol))
    {
        cout << "Symobl is punctuation symobl" << endl;
    }
    else        {
        cout << "Unknown symbol" << endl;
    }

    system("pause");
    return 0;
}

8

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

truesupport написав:

я на с++ не писав уже напевно років 4

а могли б іще стільки не писати

truesupport написав:

в мене вийшло щось таке

#include "stdafx.h"
#include <iostream>
#include <string>

Додано нестандартний майкрософтівський stdafx.h (а його код додати?), нема cctype.


truesupport написав:
bool IsLetter(char symbol)
{
    return isalpha(symbol) > 0;
}

Ніхто не гарантує, що результат isalpha не буде від'ємним. Від'ємні значення isalpha мають розглядатися як true.
Ну і взагалі - що робить ваша функція? Перетворює int, який використовується в C, як bool, на явний bool, причому неочевидним (і неправильним) способом. Нащо?

truesupport написав:
    const string punctSymbols = string(",.;:!?");

А лапки - вже не пунктуація? А дужки? І взагалі, чомусь ви там використовували стандартні функції, а тут чогось ispunct не взяли. Бо послідовні? Ну і без static цей рядок буде створюватися кожного разу при запуску функції - дуже корисна річ: створювати, знищувати, знову створювати...

truesupport написав:
    system("pause");

Ну правильно: задля паузи викликати іншу програму, значно більшу і складнішу за вашу. Пауза - це така складна операція...

9 Востаннє редагувалося Betterthanyou (04.11.2016 23:38:57)

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

cctype - я раніше не знав про неї
тут і тут добре пояснено.

#include <cctype>
#include <cstring>//strlen
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    char symbols[100];
    cout << "Input anything\n";
    cin.getline(symbols, 100);
    short lenSymbols = strlen(symbols);
    for (short i = 0; i < lenSymbols; i++)
    {
        if (isdigit(symbols[i]))
            cout << symbols[i] << " is number" << endl;
        else if (isalpha(symbols[i]))
            cout << symbols[i] << " is alphabetic" << endl;
        else if (ispunct(symbols[i]))
            cout << symbols[i] << " is punctuation character" << endl;
        else if (isspace(symbols[i]))
            cout << symbols[i] << " is a white-space" << endl;
        else
            cout << "I do not know what is " << symbols[i] << endl;
    }
    cout << "\nPress any key";
    cin.get();
    return 0;
}
Подякували: AnderS0N1

10

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

Betterthanyou написав:

cctype - я раніше не знав про неї
тут і тут добре пояснено.

#include <cctype>
#include <cstring>//strlen
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    char symbols[100];
    cout << "Input anything\n";
    cin.getline(symbols, 100);
    short lenSymbols = strlen(symbols);
    for (short i = 0; i < lenSymbols; i++)
    {
        if (isdigit(symbols[i]))
            cout << symbols[i] << " is number" << endl;
        else if (isalpha(symbols[i]))
            cout << symbols[i] << " is alphabetic" << endl;
        else if (ispunct(symbols[i]))
            cout << symbols[i] << " is punctuation character" << endl;
        else if (isspace(symbols[i]))
            cout << symbols[i] << " is a white-space " << endl;
        else
            cout << "I do not know what is" << symbols[i] << endl;
    }

    cout << "\nPress any key";
    cin.get();
    return 0;
}

Що за any key?

11

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

Kizyak написав:

Що за any key?

Може то не правильно, але я хотів написати "Натисніть якусь кнопку"

12

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

koala, дякую за ревю. Про статік в середині функції я не знав ((, хоча це насправді дивно конст по ідеї мав би бути статіком або я чогось не розумію, про відємні значення не подумав наскільки я зрозмумів щоб нормально перетворити результат тої функції в bool треба було писати != 0. А чому я написав окрему реалізацю IsPunctuationSymbol це через те що стандарна працює так (http://www.cplusplus.com/reference/cctype/ispunct/) тобто все що не буква і не цифра то знак пунктуації, ну незнаю, мені здається що це не правильно хоча я би мав дійсно добавити більше символів в ту константу додати.

13 Востаннє редагувалося AnderS0N (05.11.2016 08:23:17)

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

koala написав:

Ну правильно: задля паузи викликати іншу програму, значно більшу і складнішу за вашу. Пауза - це така складна операція...

А чим користуватися замість system("pause") і коли доречно використовувати її?

14 Востаннє редагувалося AnderS0N (05.11.2016 08:33:23)

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

Betterthanyou написав:

cctype - я раніше не знав про неї
тут і тут добре пояснено.

#include <cctype>
#include <cstring>//strlen
#include <iostream>

using namespace std;

int main(int argc, char *argv[])  [i]Поясніть мені будь ласка що написано в дужках[/i]
{
    char symbols[100];  [i]Ви берете 100 символів?[/i]
    cout << "Input anything\n";
    cin.getline(symbols, 100);  [i]Чому після cin.(Крапка) і що означає getline?[/i]
    short lenSymbols = strlen(symbols); [i]Короткий символ? Не зовсім розумію цю строку[/i]

    for (short i = 0; i < lenSymbols; i++) [i]Буде добре якщо і це поясните мені) [/i]
    {
        if (isdigit(symbols[i]))  [i]Все що нижче я розумію, ми це проходили з викладачем на занятті, окрім (symbols[i])) [/i]
            cout << symbols[i] << " is number" << endl;
        else if (isalpha(symbols[i]))
            cout << symbols[i] << " is alphabetic" << endl;
        else if (ispunct(symbols[i]))
            cout << symbols[i] << " is punctuation character" << endl;
        else if (isspace(symbols[i]))
            cout << symbols[i] << " is a white-space" << endl;
        else
            cout << "I do not know what is " << symbols[i] << endl;
    }
    cout << "\nPress any key";
    cin.get();  [i] Навіщо потрібна ця строка?[/i]
    return 0;
}






Я всередині вашого коду задав декілька питань, по можливості дайте будь ласка відповідь на них. Я зовсім недавно почав вчитися і мені все це потрібно, буду вдячний за ваші відповіді і поради.

15

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

koala, вам я також дякую за допомогу.

16

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

truesupport написав:

по ідеї мав би бути статіком

Ні, бо існує const_cast. Теоретично, це мав би оптимізатор розрулювати, але як він поведе себе із динамічною пам'яттю в складній структурі - не знаю.

AnderS0N написав:

А чим користуватися замість system("pause")

Зчитувати символи до символа нового рядка. Якщо перед тим було введення за допомогою operator>> - два раз (перший, щоб прибрати той новий рядок, що вже сидить в буфері).

AnderS0N написав:

і коли доречно використовувати її?

Ніколи. Доречно використовувати командний рядок/оболонку або IDE, що самі додають паузу при виконанні консольних додатків (або ж налаштувати свій IDE на таку роботу).

AnderS0N написав:
int main(int argc, char *argv[])  [i]Поясніть мені будь ласка що написано в дужках[/i]

Теги всередині коду не підтримуються, робіть коментарі. Це - параметри, з якими була викликана програма. Вважайте, просто частина стандарту.

AnderS0N написав:

Ви берете 100 символів?

Масиви char в C/C++ використовуються як базовий тип рядків. Розглядайте це як рядок, в якому передбачено до 100 символів.

AnderS0N написав:

Чому після cin.(Крапка) і що означає getline?

Гуглити не намагалися?

AnderS0N написав:

Короткий символ?

short - це ціле число розміром (в байтах) не менше за char і не більше за int. Можете сміливо поставити замість нього int.

AnderS0N написав:

Навіщо потрібна ця строка?

Спроба ваш улюблений system("pause") замінити.

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