Как потребителят да въвежда елементите на масива в c++ в един ред

Аз съм нов в c++, по принцип принадлежа към PHP. Така че се опитвам да напиша програма само за практика, за сортиране на масив. Успешно създадох програмата със стойност на статичен масив, която е

// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector


bool myfunction (int i,int j) { return (i<j); }

struct myclass { bool operator() (int i,int j) { return (i<j);} } myobject;

int main () {
   int myints[] = {55,82,12,450,69,80,93,33};
  std::vector<int> myvector (myints, myints+8);               

  // using default comparison (operator <):
  std::sort (myvector.begin(), myvector.begin()+4);           

  // using function as comp
  std::sort (myvector.begin()+4, myvector.end(), myfunction); 

  // using object as comp
  std::sort (myvector.begin(), myvector.end(), myobject);     

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;
    std::cout << '\n';

  return 0;
}

изходът му е ок. Но искам елементите да се въвеждат от потребител с space разделени или , разделени. Така че аз опитах това

int main () {
    char values;
    std::cout << "Enter , seperated values :";
    std::cin >> values;
  int myints[] = {values};


  /* other function same */
}

не хвърля грешка по време на компилиране. Но op не е както се изисква. то е

Въведете, разделени стойности: 20,56,67,45

моят вектор съдържа: 0 0 0 0 50 3276800 4196784 4196784

------------------ (програмата излезе с код: 0) Натиснете връщане, за да продължите


person Manoj Dhiman    schedule 07.09.2015    source източник
comment
values е едно char, така че вашият масив има точно един елемент. Трябва да използвате std::vector<int> и push_back. (Примери има навсякъде в интернет.)   -  person molbdnilo    schedule 07.09.2015
comment
Не се нуждаете от специален клас за сортиране на ints, тъй като той вече поддържа operator<.   -  person user877329    schedule 07.09.2015


Отговори (5)


Можете да използвате този прост пример:

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>

using namespace std;

int main()
{
    stringstream ss;
    string str;
    getline(cin, str);
    replace( str.begin(), str.end(), ',', ' ');
    ss << str;

    int x = 0;
    while (ss >> x)
    {
        cout << x << endl;
    }
}

Демо на живо


или, ако искате да го имате по-общо и добре затворено във функция, връщаща std::vector:

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>

using namespace std;

template <typename T>
vector<T> getSeparatedValuesFromUser(char separator = ',')
{
    stringstream ss;
    string str;
    getline(cin, str);
    replace(str.begin(), str.end(), separator, ' ');
    ss << str;

    T value{0};
    vector<T> values;
    while (ss >> value)
    {
        values.push_back(value);
    }

    return values;
}

int main()
{
    cout << "Enter , seperated values: ";
    auto values = getSeparatedValuesFromUser<int>();

    //display values
    cout << "Read values: " << endl;
    for (auto v : values)
    {
        cout << v << endl;
    }
}

Демо на живо

person PiotrSliwa    schedule 07.09.2015
comment
Моля, прочетете този въпрос и неговите отговори. - person molbdnilo; 07.09.2015
comment
@molbdnilo Добро наблюдение, благодаря. Актуализирах отговора. - person PiotrSliwa; 07.09.2015

Прочетете всички стойности в един низ, след което използвайте токенизатор, за да отделите отделните стойности.

Как да токенизирам низ в C++?

person ravenspoint    schedule 07.09.2015

Горните отговори са много добри за произволен брой входове, но ако вече знаете колко числа ще бъдат поставени, можете да го направите така:

int[5] intList;
std::cin >> intList[0] >> intList[1] >> intList[2] >> intList[3] >> intList[4]

Но имайте предвид, че този метод не прави никаква проверка дали числата са поставени правилно, така че ако във входа има например букви или специални знаци, може да получите неочаквано поведение.

person DrDonut    schedule 07.09.2015

Да видим какво си написал:

int main () {
    char values;
    std::cout << "Enter , seperated values :";
    std::cin >> values; // read a single character
    int myints[] = {values}; // create a static array of size 1 containing the single character converted to an int

    /* other function same */
}

това от което се нуждаете е:

#include <sstream>
#include <string>

...

int main () {
    std::cout << "Enter space seperated values :";
    std::vector<int> myvector;
    std::string line;
    std::getline(std::cin, line); // read characters until end of line into the string
    std::istringstream iss(line); // creates an input string stream to parse the line
    while(iss >> value) // so long as values can be parsed
        myvector.push_back(value); // append the parsed value to the vector

    /* other function same */
}

Ако искате разделен със запетая вход, ще трябва да анализирате запетаята като единичен знак в допълнение към целочислените стойности.

person BeyelerStudios    schedule 07.09.2015

Какво правиш

int main () {
    char values; //Declare space for one character
    std::cout << "Enter , seperated values :"; //Ask user to enter a value
    std::cin >> values; //Read into values (one value only)
  int myints[] = {values}; // assign the first element to the ASCII code of whatever user typed.


  /* other function same */
}

В езика char работи като 8-битово цяло число. Чрез претоварване на функция може да се реализира различно поведение. Прочетете за статичния полиморфизъм за повече подробности как работи.

Какво трябва да направите

std::vector<int> values;
char ch_in;
std::string temp;
while(cin.get(ch_in)) {
    switch(ch_in) {
         case ',':
         case ' ': //Fall through
             values.push_back(atoi(temp.c_str()); //include cstdlib for atoi
             temp.clear();
             break;
         default:
             temp+=ch_in;
    }
}

Трябва да поставите това в отделна функция. С този скелет можете да приложите по-фантастичен синтаксис, като добавите повече регистри, но тогава имате нужда от нещо друго освен std::vector<int>, в което да поставите нещата. Можете (трябва ли?) също да добавите проверка за грешки в случай default:

         default:
             if( (ch_in>='0' && ch_in<='9') 
                 || (temp.size()==0 && ch_in=='-') ) {
                 temp+=ch_in;
             }
             else {
                 cerr<<ch_in<<" is an illegal character here."
                 temp.clear();
             }
person user877329    schedule 07.09.2015