Софтуерно Инженерство
Loading...
v.krastev avatar v.krastev 54 Точки

Handling user input in C++

Здравейте!

Идеята ми е в козолата да се въвеждат n на брой числа (int-ове) и да ги записвам като елементи на масив от int-ове. съответно правя проверка дали въведеното реално може да бъде запаметено в променлива от тип int, ако не - съобщение за грешка и да се въвежда отново. след това пускам цикъл да принтира масива, но вместо това изкарва моето съобщение за грешка няколко пъти (с един по-малко от въведеите числа...) като всеки път изяжда всяка следваща първа буква от съобщението. Кодът е следния:

#include<iostream>
#include<sstream>
using namespace std;

int main()
{
    int number = 0;
    short int br = 0;
    bool sInput = false;
    string str_arr1, str_arr2;
    cout<<"Enter the first array in line: ";
    
    while(!sInput)
    {

        string inputLine;
        getline(cin, inputLine);
        istringstream inputStream(inputLine);
        ostringstream mistakes;
        sInput = true;
        while(inputStream)
        {
            if(inputStream>>number)
            {
                str_arr1 += to_string(number) + " ";
                br++;
            }
            else
            {
                inputStream.clear();
                string str_mistakes;
                inputStream>>str_mistakes;
                if(!str_mistakes.empty())
                {
                    sInput = false;
                    mistakes<<str_mistakes<<" ";
                }
            }
        }
        if(!sInput)
        {
            cout<<"The following isn't numbers: "<<endl<<mistakes.str()<<endl<<"Please re-enter: ";

        }
    }
    istringstream inputStream(str_arr1);
    int arr1[br];
    int i = 0;
    while(inputStream)
    {
        if(inputStream>>number)
        {
            arr1[i] = number;
        }
        i++;
    }
    for(int i = 0; i <br; i++)
    {
        cout<<arr1[i] + " ";
    }

 

Въвеждам числата 1 2 3 и след Enter ми връща:

The following isn't numbers: he following isn't numbers:

Някой знаещ и можещ с препоръки и насоки?

Тагове:
0
C++ Programming
MartinBG avatar MartinBG 1262 Точки
Best Answer

Проблемът е на този ред:

cout<<arr1[i] + " ";

Не може да събираш int и стринг :)

За да работи, трябва да го промениш така:

cout<<arr1[i] << " ";

 

Аз бих посъкратил и while цикъла преди това до:

    while(inputStream>>number)
    {
        arr1[i++] = number;
    }
    

0
v.krastev avatar v.krastev 54 Точки

Чел съм твои коментари и на други въпроси из форума... Много ме радваш, благодаря много!!! Идиотска грешка, да, но нямаше да я открия, ако не я беше казал!!!

П.С. - за да стане в цикъла i++, трябва да му задам начална стойност на i = -1, за да може индексите да вървят от нула, не от първи. като го драсна така, при вход 1 2 3, изкарва 2 3 и някакво огромно число. сигурно аз нещо не върша както трябва, но няма значение, отново - много благодаря!!!

0
MartinBG avatar MartinBG 1262 Точки

Проблема с индекса е странен.

Това е кода, който съм променил:


    while(inputStream>>number)
    {
        arr1[i++] = number;
    }
    for(i = 0; i <br; i++)
    {
        cout<<arr1[i] << " ";
    }

 

Изхода е коректена на Kubuntu x64 и Windows 7:

Enter the first array in line: 0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
Process returned 0 (0x0)   execution time : 11.704 s

Между другото, to_string не работи на версията на mingw, която се инсталира с Codeblocks на Windows и трябваше да я заменя с моя функция, но това няма отношение към output проблема при теб.

0
v.krastev avatar v.krastev 54 Точки

to_string е функция от c++11. компилатора си ми е generic-а mingw който вървеше с codeblocks-а когато го изтеглих от сайта и линка посочен от жоро първата лекция и си работи. и на мен ми боде очите това нещо и че само заради него трябва да използвам c++11. ако не код, то поне би ли казал какво правиш вместо тази функция, защото ми се ще да я разкарам и да си върви всичко без 11-ката?

за цикъла - да, работи както казваш, инициализирам i  в началото с 0, не с -1 и работи. но защо!? още при първото завъртане на while - а, number присвоява първото въведено число, но отдолу индекса на масива веднага става arr1[0 + 1] тоест първи индекс. не разбирам защо работи? при начална стойност на i==0, би трябвало да въвежда чилата от втората позиция в масива или бъркам :D ?

0
MartinBG avatar MartinBG 1262 Точки
template <typename T>
string ToString(T val)
{
    stringstream stream;
    stream << val;
    return stream.str();
}

Кодът е взет от тук и изисква #include<sstream>

Може да се опрости и да се напише без темплейт, но тогава ще работи само за един тип данни, напр. само за int:

string ToString(int val)
{
    stringstream stream;
    stream << val;
    return stream.str();
}

Относно въпроса ти за инкрементирането i в цикъла, то работи така:

int i = 0; // начална стойност на i - сочи към елемент 0
while(inputStream>>number)
{
    arr1[i++] = number; // тук i се увеличава с 1 след всяко преминаване
}

Т.е. при първото минаване през цикъла, i ще е 0 когато се ползва като индекс, но веднага след като бъде използван (още преди да излезе от текущата итерация), ще бъде инкрементиран с 1 (i++) и готов за второто завъртане.
Можеш да го провериш, като добавиш "cout << i;" преди и след "arr1[i++] = number;".

За добро осмисляне на това как работи инкрементирането може да пробваш този код и да сравниш аутпута:

    int j = 0;
    for (int i = 0; i < 3; i++)
    {
        cout << "j++ = " << j++ << endl; // Инкрементацията става след използването на j
    }
    j = 0;
    for (int i = 0; i < 3; i++)
    {
        cout << "++j = " << ++j << endl; // Инкрементацията става преди използването на j
    }

 

0
11/03/2017 13:23:59
v.krastev avatar v.krastev 54 Точки

това с template - а ще трябва да го разуча, но благодаря за цялата информация!!!

с последното обяснение: j++ и ++j се сетих че съм чел за това и за какво ставаше дума, на кое кога му се добавяше нещо. благодаря много и за това разяснение и оценявам че си изгуби толкова време в писане и обяснения!!! :D

0