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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
#1

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

03.11.2013, 15:32. Просмотров 898. Ответов 22
Метки нет (Все метки)

Здравствуйте дорогие форумчане!
У меня возникла такая не тривиальная задача, вот собственно в чем фишка:
Нужно написать на С++ программу котрая получит файл из 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(), особенно на больших данных и знаю что это даже очень заметно замедляет программу, но сейчас это мне не важно.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.11.2013, 15:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Прочитать бинарник картинки через std::cin (C++):

Не воспринимает ни std::cout, ни std::cin. Вобщем ничего из std. Также не понимает iostream - C++
Здравствуйте! Я хотел начать изучать язык C++. Набрал литературы. Установил Microsoft Visual C++ 2005 Express Edition. Образ диска...

Не работает std::cout || std::cin - C++
#include &quot;Account.h&quot; #include &lt;string&gt; #include &lt;iostream&gt; using std::cout; Account :: Account(int startBalance) { ...

std::cin - C++
const int MAX = 256; int main() { char buf; std::cout&lt;&lt;(std::cin&gt;&gt;buf); return 0; } Я в консоли вижу странный вывод...

Из scanf в std::cin - C++
Как тоже самое сделать с помощью std::cin? printf(&quot;Введите автора %d книги.\n&quot;,i+1); scanf(&quot;%31s &quot;,ar.author); ...

Очистка (блокировка) std::cin - C++
Здравствуйте. Такой вопрос. Программа отрисовывает в консоль поле раз в n секунд несколько раз подряд (что-то типа анимации). В течение...

Как исправить ошибку с std::cin - C++
помогите у меня пропускает последующие вводы если вводишь знак или букву вот код std::cout&lt;&lt;&quot;A: &quot;; std::cin&gt;&gt;AA; ...

22
grizlik78
Эксперт С++
1963 / 1456 / 118
Регистрация: 29.05.2011
Сообщений: 3,015
03.11.2013, 21:51 #16
Ну, на самом деле есть способ. Вот так мой пример будет работать нормально с любыми файлами:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <fstream>
#include <fcntl.h>
 
int main()
{
    _setmode(_fileno(stdin), _O_BINARY);
    std::ofstream out("result.dat", std::ios::binary);
    int c;
    while ( (c = std::cin.get()) !=EOF)
        out.put(c);
    return 0;
}
1
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
03.11.2013, 22:01 #17
отут от:
C++
1
2
char *str = new char[size+1];
std::cin.read(str,size);
Попробуй заменить size на 900000, мб будет работать без ошибок.
Это если ты говоришь у тебя бинарная строка в cin, то при встрече 0 она оборвется и возможно реальный размер ее ты не увидешь.

Добавлено через 2 минуты
Ладно экспериментируй, ну ты явно напутал там что то с размером буфера, если с ошибками сохраняет.
0
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
03.11.2013, 22:07  [ТС] #18
Цитата Сообщение от ninja2 Посмотреть сообщение
Автору наверно нужно сначала сохранить файл на диск в бинарном режиме
К сожалению нельзя, нужно его именно напрямик переработать, без лишних "телодвижений".

Цитата Сообщение от ninja2 Посмотреть сообщение
А что ты думаешь делать с изображением дальше?
Мне нужно изображение где-то в памяти разместить не важно в каком виде, а потом я его возьму и перекодирую в строку.

Цитата Сообщение от ninja2 Посмотреть сообщение
Затем считай его в бинарном режиме и сможешь вычислить реальный размер который изображение будет занимать
Мне даже так известен размер входных данных, я ориентируясь на них и так пытаюсь считывать данные.
Мне кажется что из-за текстового режима передачи данных они приходят не до конца. Я просто пробовал проходить по streambuf-у cin-a и это всё-равно ничего не дало.
0
grizlik78
Эксперт С++
1963 / 1456 / 118
Регистрация: 29.05.2011
Сообщений: 3,015
03.11.2013, 22:09 #19
Цитата Сообщение от Maxim Petruck Посмотреть сообщение
Мне кажется что из-за текстового режима передачи данных они приходят не до конца.
Скорее всего так и есть. Что ж, пробуй _setmode().
0
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
03.11.2013, 22:10 #20
Цитата Сообщение от Maxim Petruck Посмотреть сообщение
Мне даже так известен размер входных данных, я ориентируясь на них и так пытаюсь считывать данные.
ну так в чом проблема read(file, size); и все должно работать.
0
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
03.11.2013, 22:10  [ТС] #21
Здесь не в размере считываемых данных проблема, я только что попробовал увеличить size в 8 раз, результат не поменялся
0
ninja2
231 / 187 / 7
Регистрация: 26.09.2012
Сообщений: 2,018
Завершенные тесты: 1
03.11.2013, 22:17 #22
Цитата Сообщение от Maxim Petruck Посмотреть сообщение
Мне кажется что из-за текстового режима передачи данных они приходят не до конца. Я просто пробовал проходить по streambuf-у cin-a и это всё-равно ничего не дало.
Да какая разница? Я например считывал изображения с интернета в текстовую строку, а потом ее записывал в бинарном режиме и все нормально приходило. Правда без всяких cin и cout, а даже с cin и cout работало, я ее выводил в консоль токо она не бинарная была.
ТС выведи в консоль то что тебе пришло, если выведеться куча символов и консоль запикает, то строка у тебя не бинарная передаеться, а если выведеться строчка, то бинарная.

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

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

Добавлено через 2 минуты
Я вообще проблему не вижу, ну пришла к тебе строка? И откуда ты увидел что она не вся пришла или поврежденная?
1
Maxim Petruck
0 / 0 / 0
Регистрация: 03.11.2013
Сообщений: 12
03.11.2013, 22:21  [ТС] #23
Bingo, спасибо всем за ответы! _setmode() помог, я перевел поток в бинарный режим и все заработало!
0
03.11.2013, 22:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.11.2013, 22:21
Привет! Вот еще темы с ответами:

std::cin & switch case - C++
Всем привет. Вообщем проблема такая: while(val) { int choice; std::cin &gt;&gt; choice; switch(choice) { case 1: ...

Локаль в std::cin.getline (вижуал с++) - C++
собственно выводит в консоль нормально, а вот после считывания с консоли в символьный массив попадают крокозябры: #include &quot;stdafx.h&quot; ...

Как выполнять std::cin в LOOP ? - C++
Хочу сделать что то вроде командной строки. 1ый раз читает и выполняет нормально, но следующий раз вижу что ждет от меня ввода, но ни...

std::cin Debug Access failed - C++
Решил начать программировать в visual studio 2012 и сразу наткнулся на какую-то непонятную ошибку вот код: #include &quot;stdafx.h&quot; ...


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

Или воспользуйтесь поиском по форуму:
23
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru