1

Тема: Робота з рядками

Добрий вечір. Щось я давно не бачив лаб в нас на форумі, потрібно це виправити :)

Щож, є завдання (далі тролейбусною мовою): Людина вирішила переглянути та замовити білет на рейс. Створити програму яка при вводі місця для сидіння вказувала де знаходиться це місце: window (вікно), aisle (прохід), nether (ні прохід, ні вікно).

На схемі зображено 3 відділення літака (преміум-клас, бізнес-клас, економ-клас), де 1..65 - ряди місць, A..K - позиція місця (ви можете помітити, що між H та J відсутня буква I, але в умові сказано, що позиція місць в економ-класі позначається буквами від A..K окрім I).

Схема розташування місць в літаку:

http://screenshot.su/img/4e/c0/dc/4ec0dc8c7a4d735ad344353889ccfd28.jpg
Приклад вхідних даних та результату:

3С  aisle
24A  window
55B  neither

Код програми:

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

using namespace std;

int main()
{
    string Row, Place, Number;
    string RowPlace, RowNumber;
    int CountRowTwo = 0;
    int CountRowThree = 0;
    setlocale(0, "");

    cout << "Введiть номер мiсця: " << endl;
    cin >> Row;

    CountRowTwo = Row.length();
    CountRowThree = Row.length();

    RowPlace = Row;
    RowNumber = Row;
    if (CountRowTwo == 2)
    {
        Place = RowPlace.erase(0, 1);
        Number = RowNumber.erase(1);
    }
    else
        if (CountRowThree == 3)
        {
            Place = RowPlace.erase(0, 2);
            Number = RowNumber.erase(2);
        };
    
    system("pause");
    return 0;
}

В коді я розділяю номер та місце на дві змінних.
Питання таке: якою функцією можна перевести значення типу string в int (наприклад як в Delphi, StrToInt()) для подальшої роботи з числами.

P.S. Вибачте за недолугий малюнок схеми.

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

2

Re: Робота з рядками

1. sprintf() + MyString.c_str()
2. stringstream
3. atoi()

Щось я давно не бачив лаб в нас на форумі, потрібно це виправити

Бракує тега сарказму :).

I belong to the Dead Generation.
Подякували: Logans1

3 Востаннє редагувалося koala (08.12.2013 00:24:14)

Re: Робота з рядками

Найпростіший нативний C++ спосіб переводити string в int - це пхати його в stringstream і витягати звітди. Але тут можна і простіше:

    int row;
    char place;
    cin >> row >> place;

4 Востаннє редагувалося Logans (08.12.2013 00:36:15)

Re: Робота з рядками

Bartash написав:

1. sprintf() + MyString.c_str()
2. stringstream
3. atoi()

Щось я давно не бачив лаб в нас на форумі, потрібно це виправити

Бракує тега сарказму :).

Я однозначно "за" за такий тег)

Команди приведені вище використав ось так:

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

    int IntegerPlace = 0;
    int IntegerNumber = 0;
    IntegerPlace = atoi(Place.c_str());
    IntegerNumber = atoi(Number.c_str());

    cout << IntegerNumber << " " << IntegerPlace << endl;

Але вийшло ось так:

Вивід:

3С 0
34С 0
45В 0

Тобто на букву виводить одні нулі. З цифрою все нормально.


koala написав:

Найпростіший нативний C++ спосіб переводити string в int - це пхати його в stringstream і витягати звітди. Але тут можна і простіше:

    int row;
    char place;
    cin >> row >> place;

Тобто використовувати для вказування ряду int-значення, а для вказування місця char-значення?
Звісно це логічніше, але за умовою завдання я маю зробити цю програму використовуючи лише string (а потім зробити і для char) рядки.

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

5 Востаннє редагувалося Bartash (08.12.2013 00:37:52)

Re: Робота з рядками

Logans написав:

зробити цю програму використовуючи лише string (а потім зробити і для char) рядки.

Складність розв'язку прямо пропорційна хитрості тарганів викладача: інноватори приймуть зі stringstream, консерватори змусять писати свій sprintf для string. :)

Тобто на букву виводить одні нулі. З цифрою все нормально.

cppreference написав:

If the converted value would be out of the range of representable values by an int, it causes undefined behavior

I belong to the Dead Generation.

6

Re: Робота з рядками

Bartash написав:
Logans написав:

зробити цю програму використовуючи лише string (а потім зробити і для char) рядки.

Складність розв'язку прямо пропорційна хитрості тарганів викладача: інноватори приймуть зі stringstream, консерватори змусять писати свій sprintf для string. :)

Хотілося б вміти використовувати обидва рішення, можливо можете навести приклади використання?

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

7 Востаннє редагувалося Bartash (08.12.2013 00:41:20)

Re: Робота з рядками

Logans написав:

Хотілося б вміти використовувати обидва рішення, можливо можете навести приклади використання?

stringstream приклад навів koala. А самописні велосипеди, як правило, далі лаб не слід поширювати.

I belong to the Dead Generation.

8

Re: Робота з рядками

Bartash написав:
Logans написав:

Хотілося б вміти використовувати обидва рішення, можливо можете навести приклади використання?

stringstream приклад навів koala. А самописні велосипеди, як правило, далі лаб не слід поширювати.

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

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

9

Re: Робота з рядками

Приклад з практики: StackOverflow.

I belong to the Dead Generation.

10

Re: Робота з рядками

Logans написав:

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

Я в одному з проектів віддав перевагу stringstream під час парсингу текстового файлу з подальшим формуванням масиву чисел.

I belong to the Dead Generation.

11 Востаннє редагувалося Logans (08.12.2013 01:01:19)

Re: Робота з рядками

Кому цікаво, ось приклад повної програми.

Не знаю, чи правильно перевірку зробив, здається дещо некоректно, але іншого варіанту не придумав.

Код

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

using namespace std;

int main()
{
    string Row, Place, Number;
    string RowPlace, RowNumber;
    int CountRowTwo = 0;
    int CountRowThree = 0;
    setlocale(0, "");

    cout << "Введiть номер мiсця: " << endl;
    cin >> Row;

    CountRowTwo = Row.length();
    CountRowThree = Row.length();

    RowPlace = Row;
    RowNumber = Row;
    if (CountRowTwo == 2)
    {
        Place = RowPlace.erase(0, 1);
        Number = RowNumber.erase(1);
    }
    else
        if (CountRowThree == 3)
        {
            Place = RowPlace.erase(0, 2);
            Number = RowNumber.erase(2);
        };
    
    int IntegerNumber = 0;
    IntegerNumber = atoi(Number.c_str());
    if (IntegerNumber <= 2)
    {
        if ((Place == "A") || (Place == "D"))
            cout << "window" << endl;
        else
            if ((Place == "B") || (Place == "C"))
                cout << "aisle" << endl;
    }
    else
        if ((IntegerNumber >= 3) && (IntegerNumber <= 20))
        {
            if ((Place == "A") || (Place == "F"))
                cout << "window" << endl;
            else
                if ((Place == "B") || (Place == "C") ||
                    (Place == "D") || (Place == "E"))
                    cout << "aisle" << endl;
        }
        else
            if ((IntegerNumber >= 21) && (IntegerNumber <= 65))
            {
                 if ((Place == "A") || (Place == "K"))
                     cout << "window" << endl;
                 else
                     if ((Place == "C") || (Place == "D") ||
                         (Place == "G") || (Place == "H"))
                         cout << "aisle" << endl;
                     else
                         if ((Place == "B") || (Place == "E") ||
                             (Place == "F") || (Place == "J"))
                             cout << "nether" << endl;
            };


    system("pause");
    return 0;
}

Щодо параметрів які не відповідають цьому діапазону, я перевірку не робив.

Дякую за допомогу. :)

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

12

Re: Робота з рядками

Logans написав:

за умовою завдання я маю зробити цю програму використовуючи лише string (а потім зробити і для char) рядки.

Вам допомагати - як з шулером грати: тільки здається, що ти виграєш, аж тут виявляється, що ви це партія не в шашки, а в го. Може, варто в майбутньому все ж повністю умову викладати?

13

Re: Робота з рядками

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

за умовою завдання я маю зробити цю програму використовуючи лише string (а потім зробити і для char) рядки.

Вам допомагати - як з шулером грати: тільки здається, що ти виграєш, аж тут виявляється, що ви це партія не в шашки, а в го. Може, варто в майбутньому все ж повністю умову викладати?

Вибачаюсь, просто я гадав, що написаного буде достатньо)

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

14

Re: Робота з рядками

Я б додав купу цікавого, що можна виправити/покращити, але, мабуть, там в умові було написано, щоб вийшов неефективний бидлокод, тому просто скопіюю його на govnokod.ru, якщо не заперечуєте.

15

Re: Робота з рядками

koala написав:

Я б додав купу цікавого, що можна виправити/покращити, але, мабуть, там в умові було написано, щоб вийшов неефективний бидлокод, тому просто скопіюю його на govnokod.ru, якщо не заперечуєте.

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

А фразу "якщо не заперечуєте", я гадаю потрібно писати перед тим, як зробити те, що комусь може не сподобатись, якщо вже скопіювали то так і буде.

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

16

Re: Робота з рядками

Logans написав:

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

CountRowTwo якось відрізняється від CountRowThree? Якщо ні - нащо там дві змінні? І нащо два виклики Row.length()?
Замість erase тут краще використовувати substr. І дотримуватися DRY:

int rowLength = Row.length();
RowPlace  = Row.substr( rowLength - 1,  1);
RowNumber = Row.substr( 0, rowLength - 1 );

І ще незрозуміло, чи треба казати, чи знаходится місце 1A біля проходу. З фактом - так. Ваша програма каже window і все... але може то за умовою так треба?

Logans написав:

А фразу "якщо не заперечуєте", я гадаю потрібно писати перед тим, як зробити те, що комусь може не сподобатись, якщо вже скопіювали то так і буде.

Де я скопіював? У вас прекешування з майбутнього встановлено? Підкажіть, як?

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

17

Re: Робота з рядками

Дякую за корисні речі, CountRowTwo\Three я раніше намагався зробити через одну змінну, очевидно, що після використання однієї я забув в if переписати, дякую. За substr я не знав, також вельме вдячний :)

І ще незрозуміло, чи треба казати, чи знаходится місце 1A біля проходу. З фактом - так. Ваша програма каже window і все... але може то за умовою так треба?

слід розцінювати як біля вікна, пріорітет: window (вікно) - aisle (прохід) - nether (ні то, ні то).

Де я скопіював? У вас прекешування з майбутнього встановлено? Підкажіть, як?

Можливо я занадто різко зреагував, вибачте. З вашого повідомлення я зробив висновок, очевидно, що не вірний, що ви вже відправили код.

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

18

Re: Робота з рядками

Logans написав:

За substr я не знав, також вельме вдячний :)

З erase код виходить практично такий самий, тільки erase/insert менш ефективні за substr і copy. Хоча, звісно, в цьому коді це практичного значення не має.

19 Востаннє редагувалося Logans (08.12.2013 10:05:30)

Re: Робота з рядками

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

За substr я не знав, також вельме вдячний :)

З erase код виходить практично такий самий, тільки erase/insert менш ефективні за substr і copy. Хоча, звісно, в цьому коді це практичного значення не має.

Дякую, вже використав і справді корисна річь, меньше коду це справді те, що мені потрібно.

А для цього перебору (пошук згідно літери), можете щось порекомендувати? Тому, що досить не гарно виглядить код з таким багажем перевірок.

"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program."
- Linus Torvalds

20 Востаннє редагувалося koala (08.12.2013 11:50:25)

Re: Робота з рядками

#include <stdlib.h>
#include <iostream>
#include <string>
 
using namespace std;

const string w = "window",
             a = "aisle",
             n = "neither";
const int salonCount = 3;

struct Salon
{

  int firstRow;
  const string *placeTypes[20];
}  airBus[salonCount] = {
                { 1,  {&w,             &a,         &a,             &w} },
                { 3,  {&w,     &a,     &a,         &a,     &a,     &w} },
                { 21, {&w, &n, &a,     &a, &n, &n, &a,     &a, &n, &w} }
              };

int main()
{
    string Row;
    setlocale(LC_ALL, "");
 
    cout << "Введiть номер мiсця: " << endl;
    cin >> Row;
 
    int rowLength = Row.length();
    string Place  = Row.substr( rowLength - 1, 1             ),
           Number = Row.substr( 0,             rowLength - 1 );
    int IntegerNumber = atoi(Number.c_str());
    int salonNumber=0;
    while( ( salonNumber < salonCount) && ( IntegerNumber >= airBus[salonNumber].firstRow ) )
            ++salonNumber;
      
    char Litera = Place[0];
    if( Litera > 'I' ) --Litera;
    cout << *airBus[salonNumber - 1].placeTypes[Litera - 'A'];
    
    return 0;
}

Додати stdafx та паузу за смаком.
todo: зробити завантаження схеми літаку з файлу :)