#c #stringstream
#c #строковый поток
Вопрос:
В приведенной ниже игрушечной программе я пишу и считываю вектор удвоений с помощью stringstream. Однако, как я могу записать v как вектор (округленный) uint в ss, чтобы при считывании w вывод программы был равен 3?
#include <sstream>
#include <vector>
#include <iostream>
int main() {
std::vector<double> v = {0.1, 1.2, 2.6};
std::vector<double> w;
std::stringstream ss;
ss.write(const_cast<char*>(reinterpret_cast<const char*>(amp;v.at(0))), v.size() * sizeof(v.at(0))); // Here it should cast v first into uint an then into char
for(int i = 0; i < v.size(); i) {
double val; // It should be uint val
ss.read(reinterpret_cast<char*>(amp;val), sizeof(val));
w.push_back(val);
};
std::cout<<w.at(2)<<std::endl;
return 0;
}
Комментарии:
1. Что вы подразумеваете под «округлением»? Я предполагаю, что вы имеете в виду «не усеченный, а округленный с x.5». Правильно?
2. @Yunnosch Да, это то, что я имею в виду.
3. Вы можете перебирать свой вектор, округляя каждое значение по очереди, а затем записывать его в строковый поток как uint. Затем вы считываете обратно uints из строкового потока, преобразуя каждый в double для добавления к вашему новому вектору. Трудно понять, чего еще вы ожидаете.
4. @john Это похоже на ответ, но как мне его реализовать?
5. поскольку ваши числа имеют только одну цифру после
.
, вы можете рассмотреть возможность сохранения всех чисел с коэффициентом10
и использовать целые числа вместо чисел с плавающей запятой
Ответ №1:
Этот код считывает вектор, округляет значения и записывает их по одному за раз. Обратное при чтении из потока.
#include <sstream>
#include <vector>
#include <iostream>
#include <cstdint>
#include <cmath>
int main() {
std::vector<double> v = {0.1, 1.2, 2.6};
std::vector<double> w;
std::stringstream ss;
for(int i = 0; i < v.size(); i) {
uint64_t val = static_cast<uint64_t>(std::round(v.at(i)));
ss.write(const_cast<char*>(reinterpret_cast<const char*>(amp;val)), sizeof(val));
}
for(int i = 0; i < v.size(); i) {
uint64_t val;
ss.read(reinterpret_cast<char*>(amp;val), sizeof(val));
w.push_back(static_cast<double>(val));
};
std::cout<<w.at(2)<<std::endl;
return 0;
}
Кажется очень простым, не уверен, чего еще вы могли ожидать.
Обратите внимание, что преобразование a double
в a uint64_t
может привести к переполнению.
Ответ №2:
Предполагая, что вы хотите «округлить», как в «округлении от x.5», вы можете использовать
std::cout<<(unsigned int)(w.at(2) 0.5)<<std::endl;
Он использует смещение 0,5 для сдвига усечения и приводит к округлению по желанию.
Результат (использования этой строки в показанной вами программе)
3
Комментарии:
1. …как я могу записать (и прочитать) вектор удвоений как вектор (округленный) uint …
2. Пожалуйста, опишите желаемый эффект (для данного образца ввода), который вы хотите увидеть, если вы «записываете (и считываете) вектор удвоений как вектор (округленный) uint». Кажется, я неправильно понял ваш вопрос. Потому что «чтобы результат программы был равен 3» — это то, что я предлагаю здесь.
3. Я хочу, чтобы v было записано в ss как вектор uint. Затем, когда w считывается из ss, оно должно быть w={0, 1, 3}
4. Какое значение
ss
вы ожидаете после «v записывается в ss как вектор uint»?