Форум программистов, компьютерный форум CyberForum.ru

Прочитать бинарник картинки через std::cin - C++

Восстановить пароль Регистрация
 
 
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
03.11.2013, 15:32     Прочитать бинарник картинки через std::cin #1
Здравствуйте дорогие форумчане!
У меня возникла такая не тривиальная задача, вот собственно в чем фишка:
Нужно написать на С++ программу котрая получит файл из html формы(в данном случае это картинка) и мне в стандартный поток ввода приходит бинарное содержимое этой картинки.
Если кому интересно зачем я это делаю

Изначально задача состоит в том, чтобы получить картинку через html форму в С++ программе перекодировать в формат BASE64. И вывести ее на веб сранице как картинку, через уже известную нам строку BASE64.
С тем чтобы перекодировать буфер данных в BASE64 у меня проблем не возникло, но вот читать такие данные через стандартные потоки ввода доставило мне не мало проблем.

Проблема возникла в том, что при чтении бинарника картинки все данные считать не удается. Я читать это все уже пробовал кучей способов, лучший результат был когда я считал 1 кб из 5 кб. Когда читаю не картинку, а текстовый файл все работает четко читаю и по 5 мб без проблем.
Моё предположение, что из-за формата картинки при чтении данных встречается последовательность битов которая означает конец входных данных. Еще возможно из-за очень большой длинны строки, она переваливает за 1 кб она как-то урезается, но тогда она должна была бы по идее переносться на следующую строку, чего на деле не происходит.

Если вы знаете как возможно прочитать эти все данные через стандартные потоки ввода или как можно подменить потоки ввода чтобы это все читалось, вообщем если есть любые идеи, буду рад вас послушать.

Код прилагаю. Знаю что все это костыльно смотрится, но марафет буду наводить потом, когда справлюсь с сзадачей.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <string>
#include <stdlib.h>
#include <locale.h>
 
int main(int argc, char* argv[], char* env[])
{
    setlocale(LC_ALL, "Russian"); 
    std::string tmp;
    int size = atoi(getenv("CONTENT_LENGTH")); // Размер получаемых данных
    //Здесь я отрезаю не нужную мне информацию 
    std::getline(std::cin,tmp);
    size -= tmp.size()+1;
    std::getline(std::cin,tmp);
    size -= tmp.size()+1;
    std::getline(std::cin,tmp,':');
    size -= tmp.size()+1;
    std::string type;
    std::getline(std::cin,type);
    size -= type.size()+1;
    std::getline(std::cin,tmp);
    size -= tmp.size()+1;
    std::string str;
    str.reserve(size);
    
    int last; // здесь Я запоминаю размер последней строки, т.к. там в конце еще будет строка разделяющая данные html форм
    // А вот зесь начинается самое интересное, тут то и нужно прочесть бинарник
    // Здесь я уже 2 дня танцую с бубном 
    while(str.size() < size)
    {
        std::getline(std::cin,tmp);
        str += tmp + '\n';
        last += tmp.size()+2; // здесь + 2 чтобы убарть \n с прошлой строки
    }
 
    for(int i = 0; i < last; i++)
        str.pop_back();
 
    std::cout << "Content-type: text/html\n\n";
    std::cout << "<!DOCTYPE html>\n";
    std::cout << "<html>\n";
    std::cout << "<head>\n";
    std::cout << "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1251\">\n";
    std::cout << "<title>Base64</title>\n";
    std::cout << "</head>\n";
    std::cout << "<body>\n";
    std::cout << str;
    std::cout << "Размер файла: " << str.size() << " байт<br>\n";
    std::cout << "</body>\n";
    std::cout << "</html>\n";
    return 0;
}

P.S: Прошу не предлагать использовать никаких сервисов для перекодировки в BASE64. Нужно именно то, что я пытаюсь сделать.

P.P.S: Знаю что С++ система ввода здесь будет работать медленне чем Си-шные scanf(), printf(), особенно на больших данных и знаю что это даже очень заметно замедляет программу, но сейчас это мне не важно.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.11.2013, 15:32     Прочитать бинарник картинки через std::cin
Посмотрите здесь:

Как исправить ошибку с std::cin C++
C++ Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream
Из scanf в std::cin C++
C++ std::cin
C++ Не работает std::cout || std::cin
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
03.11.2013, 22:10  [ТС]     Прочитать бинарник картинки через std::cin #21
Здесь не в размере считываемых данных проблема, я только что попробовал увеличить size в 8 раз, результат не поменялся
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ninja2
 Аватар для ninja2
230 / 186 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
03.11.2013, 22:17     Прочитать бинарник картинки через std::cin #22
Цитата Сообщение от Maxim Petruck Посмотреть сообщение
Мне кажется что из-за текстового режима передачи данных они приходят не до конца. Я просто пробовал проходить по streambuf-у cin-a и это всё-равно ничего не дало.
Да какая разница? Я например считывал изображения с интернета в текстовую строку, а потом ее записывал в бинарном режиме и все нормально приходило. Правда без всяких cin и cout, а даже с cin и cout работало, я ее выводил в консоль токо она не бинарная была.
ТС выведи в консоль то что тебе пришло, если выведеться куча символов и консоль запикает, то строка у тебя не бинарная передаеться, а если выведеться строчка, то бинарная.

Добавлено через 1 минуту
Да не может быть походу бинарная строка.

Добавлено через 21 секунду
А как ты определяешь что у тебя не все данные приходят? Если ты их даже на диск не сохраняешь. По каким признакам определил ошибку?

Добавлено через 2 минуты
Я вообще проблему не вижу, ну пришла к тебе строка? И откуда ты увидел что она не вся пришла или поврежденная?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.11.2013, 22:21     Прочитать бинарник картинки через std::cin
Еще ссылки по теме:

Локаль в std::cin.getline (вижуал с++) C++
Std::cin, символ новой строки C++
C++ Как выполнять std::cin в LOOP ?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
03.11.2013, 22:21  [ТС]     Прочитать бинарник картинки через std::cin #23
Bingo, спасибо всем за ответы! _setmode() помог, я перевел поток в бинарный режим и все заработало!
Yandex
Объявления
03.11.2013, 22:21     Прочитать бинарник картинки через std::cin
Ответ Создать тему
Опции темы

Текущее время: 03:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru