Как ввести элементы массива в С++ в одну строку

Я новичок в С++, в основном я принадлежу к 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 */
}

он не выдает ошибку при компиляции. Но оп не так, как требуется. это

Введите, разделенные значения: 20,56,67,45

myvector содержит: 0 0 0 0 50 3276800 4196784 4196784

------------------ (программа завершилась с кодом: 0) Нажмите клавишу возврата, чтобы продолжить


person Manoj Dhiman    schedule 07.09.2015    source источник
comment
values равно one char, поэтому ваш массив содержит ровно один элемент. Вы должны использовать std::vector<int> и push_back. (Примеры есть во всем интернете.)   -  person molbdnilo    schedule 07.09.2015
comment
Вам не нужен специальный класс для сортировки int, так как он уже поддерживает 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