Строка parse, содержащая числа в целочисленный массив
Строка задается как входной элемент, который состоит из чисел, и я хочу преобразовать его в целые массивы в С++.
#include <string>
#include <iostream>
#include <sstream>
using std::string;
using std::stringstream;
using std::cout;
using std::endl;
int main(int argc,char** argv) {
string num="-24 2 90 24 50 76";
stringstream stream(num);
while(stream){
int n;
stream>>n;
cout<<n<<endl;
}
return 0;
}
Выход (GCC):
-24 2 90 24 50 76 76
Почему я получаю дополнительную ценность и что является эффективным для преобразования их в целочисленный массив?
UPDATE:
Что делать, если поток строк содержит разделитель, отличный от пробела. Как это проанализировать?
Например:
string num="-24,2,90,24,50,76";
Ответы
Ответ 1
Конец условия файла не задан при успешном анализе, вы должны проверить состояние потока после разбора.
Второй 76
- это, по сути, просто чистый шанс. Несовершенный синтаксический анализ оставляет целевой операнд нетронутым, и поскольку вы не инициализировали n
, это может быть что угодно.
Быстрое исправление:
stream>>n;
if (stream)
cout<<n<<endl;
Чистое исправление:
int n;
while(stream >> n){
cout<<n<<endl;
}
Чтобы сохранить эти целые числа, канонический способ - использовать std::vector
, если количество элементов неизвестно. Пример использования:
std::vector<int> values;
int n;
while(stream >> n){
...do something with n...
values.push_back(n);
}
Однако вы можете использовать итераторы поверх потоков и использовать следующее:
// Use std::vector range constructor
std::vector<int> values(
(std::istream_iterator<int>(stream)), // begin
(std::istream_iterator<int>())); // end
Ответ 2
Я не знаю, найдете ли вы ответ на свой обновленный вопрос или нет. если вы этого не сделаете, вы можете легко сделать это с помощью кода
for (string::iterator it = num.begin(); it != num.end(); ++it) {
if (*it == ',') {
*it = ' ';
}
else continue;
}
этот код удаляет все ваши двоеточия и заменяет их пробелом. то вы можете сделать только нормально
Ответ 3
Еще одно средство обращения с целым числом, разделенным символом, с использованием вектора, который даже, возможно, немного более упрощен, более похож на это:
string str = "50,2,25,38,9,16";
vector<int> ints;
stringstream ss(str);
int n;
char ch;
while(ss >> n) {
if(ss >> ch)
ints.push_back(n);
else
ints.push_back(n);
}
таким образом вы можете сначала пройти через любое разделение символов (если они есть), а затем по умолчанию вернуться к захвату целых чисел и добавлению их в список, если они этого не сделают (AKA - конец списка)