Приведите вектор и запишите его в строковый поток C

#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»?