Доброго времени суток.
Пытаюсь считать изображение в массив символов:
CFile m_BodyFile;
size_t inbuflen = 0;
long textSize = 0;
long id = 2;
m_BodyFile.Open("H:\\img.jpg", CFile::modeReadWrite);
inbuflen = m_BodyFile.GetLength();
m_BodyFile.SeekToBegin();
char* inbuf = new char [inbuflen+1];
inbuf[inbuflen]='\0';
UINT count = m_BodyFile.Read(inbuf,inbuflen*sizeof(char));
... файл весит 5481 байт, функция Read возвращает значение 5481, однако в inbuf записывается только 4 символа и длина этой строки равна 4. Не могу понять почему функция не считывает весь файл.
Здравствуйте, cupuyc., Вы писали:
C>... файл весит 5481 байт, функция Read возвращает значение 5481, однако в inbuf записывается только 4 символа и длина этой строки равна 4. Не могу понять почему функция не считывает весь файл.
Пятым символом в файле идёт 0. Для сишной строки это интерпретируется как конец.
Нельзя бинарные файлы рассматривать как С-строки. Ноль в конце буфера — бесполезен. Используй std::vector.
Здравствуйте, Nikе, Вы писали:
N>Здравствуйте, cupuyc., Вы писали:
C>>... файл весит 5481 байт, функция Read возвращает значение 5481, однако в inbuf записывается только 4 символа и длина этой строки равна 4. Не могу понять почему функция не считывает весь файл.
N>Пятым символом в файле идёт 0. Для сишной строки это интерпретируется как конец.
N>Нельзя бинарные файлы рассматривать как С-строки. Ноль в конце буфера — бесполезен. Используй std::vector.
спасибо за ответ. А можно код вызова функции Read c вектором?
Здравствуйте, Хреннос, Вы писали:
Х>Здравствуйте, cupuyc., Вы писали:
C>>спасибо за ответ. А можно код вызова функции Read c вектором?
Х>Даже я умею:
Х>std::vector<char> inbuf( inbuflen ); Х>UINT count = m_BodyFile.Read( &inbuf[0], inbuflen * sizeof(char) );
C>однако в inbuf записывается только 4 символа
туда записалось именно столько, сколько вернула функция Read, просто вы плохо проверили, что записано в этой строчке
C> и длина этой строки равна 4
ее длина больше. просто вы остановились на символе с кодом 0. это особенность отображения Си строк. чтобы посмотреть массив в студии, можно ввести в окне Watch такое: "inbuf,40". студия покажет первые 40 байт из строки
2/13/2014 4:11 PM, cupuyc. пишет:
> спасибо за ответ. А можно код вызова функции Read c вектором? http://www.cplusplus.com/
Ну и почитай хотя бы Страуструпа.
Здравствуйте, cupuyc., Вы писали:
C>Доброго времени суток.
C>... файл весит 5481 байт, функция Read возвращает значение 5481, однако в inbuf записывается только 4 символа и длина этой строки равна 4. Не могу понять почему функция не считывает весь файл.
Там всё считывается, просто ты не правильно интерпретируешь результат. Это потому, что в данном конксте не надо воспринимать char как символ потом, что это байт и значение этого байта могут быть от 0 до 255. Поэтому и работать тебе надо с ним как с байтом.
Убедись, что файл открыт в бинаром режиме, вместо char* inbuf используй std::vector<unsigned char>, ну и вместо CFile я бы использовал std::ifstream ибо нефиг!
Здравствуйте, cupuyc., Вы писали:
C> m_BodyFile.Open("H:\\img.jpg", CFile::modeReadWrite); C>... файл весит 5481 байт, функция Read возвращает значение 5481, однако в inbuf записывается только 4 символа и длина этой строки равна 4. Не могу понять почему функция не считывает весь файл.
Выше ответили: "Пятым символом в файле идёт 0."
Поэтому для бинарных файлов CFile::modeRead|CFile::typeBinary.
Здравствуйте, Nikе, Вы писали:
N>Здравствуйте, Хреннос, Вы писали:
Х>>std::vector<char> inbuf( inbuflen ); Х>>UINT count = m_BodyFile.Read( &inbuf[0], inbuflen * sizeof(char) );
N>При нулевом размере файла — упадёт.
Зависит от реализации, в т.ч. и метода Read.
&inbuf[0], скорее всего, не упадет, а если Read реализован оптимально, то при нулевом размере буфера он к переданному указателю обращаться не будет — что есть хорошо.
N>Зачем делать inbuflen * sizeof(char) — не понятно. Не зачёт
Здравствуйте, Nikе, Вы писали:
N>Здравствуйте, Хреннос, Вы писали:
Х>>Зависит от реализации, в т.ч. и метода Read. Х>>&inbuf[0], скорее всего, не упадет
N>Что значит — скорее всего? Обращаться к невалидному элементу — нельзя.
Обращаться нельзя, ага. А вот брать адрес — можно.
"Скорее всего" означает ровно то, что означает: в большинстве реализаций std::vector взятие адреса от невалидного элемента не приведет к падению программы. Просто адрес будет левый (возможно, нулевой).
Если обращение по этому адресу не происходит, то и падения не будет (тут зависит от реализации Read).
Я не говорю, что этот код кристально-правильный и так и надо писать в продакшене. Это всего лишь минимальный пример без обработки ошибок. Но вы — молодец, я вами восхищаюсь, заметили потенциальную ошибку и написали.
Здравствуйте, Хреннос, Вы писали:
Х>>>&inbuf[0], скорее всего, не упадет N>>Что значит — скорее всего? Обращаться к невалидному элементу — нельзя. Х>"Скорее всего" означает ровно то, что означает: в большинстве реализаций std::vector взятие адреса от невалидного элемента не приведет к падению программы. Просто адрес будет левый (возможно, нулевой).
STLport, например, в отладочной сборке бросит исключение:
Здравствуйте, McQwerty, Вы писали:
MQ>STLport, например, в отладочной сборке бросит исключение:
И правильно сделает.
Не считаю нужным снабжать двухстрочный пример обработкой ошибок. Подразумевается, что топикстартер сам ошибки обработает, причем именно так, как надо ему.
Я бы, например, вообще с ошибкой выходил из функции сразу после получения нулевой длины файла — не доходя до создания вектора и чтения в него. Ибо нефиг.
Но вы оба мо-лод-цы.
Здравствуйте, Vzhyk, Вы писали:
V>2/13/2014 4:11 PM, cupuyc. пишет:
>> спасибо за ответ. А можно код вызова функции Read c вектором? V>http://www.cplusplus.com/ V>Ну и почитай хотя бы Страуструпа.
в наше время говорить "хотя бы" о книге с довольно-таки мутными (ИМХО) разглагольствованиями на 1200 с чем-то страниц ....
впрочем, какую именно книгу ты имел в виду? а то у него две: очередное издание "Языка программирования" и вот эта http://www.stroustrup.com/programming.html (не знаю, как в переводе ее назвали)
Of course, the code must be complete enough to compile and link.
2/14/2014 11:10 AM, Lorenzo_LAMAS пишет:
> в наше время говорить "хотя бы" о книге с довольно-таки мутными (ИМХО) > разглагольствованиями на 1200 с чем-то страниц ....
Логично, лучше здесь спросить, нафига читать-то.
Здравствуйте, Vzhyk, Вы писали:
V>2/14/2014 11:10 AM, Lorenzo_LAMAS пишет:
>> в наше время говорить "хотя бы" о книге с довольно-таки мутными (ИМХО) >> разглагольствованиями на 1200 с чем-то страниц .... V>Логично, лучше здесь спросить, нафига читать-то.
как видишь, вполне логично — он спросил, и ему ответили.
читать, конечно, полезно. но если ты не понял, о чем был мой комментарий — мне понравилось твое "хотя бы" в
отношении книги Страуструпа, которая совершенно монструозна и по объему и по манере изложения.
впрочем, конечно, мне неведомо — давно ли ты эту книгу видел и какое издание читал, если читал.
Of course, the code must be complete enough to compile and link.
2/14/2014 11:58 AM, Lorenzo_LAMAS пишет:
> впрочем, конечно, мне неведомо — давно ли ты эту книгу видел и какое > издание читал, если читал.
До 3-его все. Имхо, самая адекватная была в свое время.
Зачем сжатые данные, упакованные в контейнер .jpg тупо
копировать в буфер? Используйте libjpeg для распаковки.
Не знаю как с этим в win, на *nix-ах код будет выглядеть так:
Но и это не всё. Для воспроизводства изображения с Xlib,
мне понадобилось к количеству компоннетов в пикселе- cinfo.output_components, добавлять
четвёртый и инициализировать его 0xff. И переворачивать весь массив так, что первый char компонент из
каждой последовательной тройки ставился на третье место, третий на первое, иначе изображение получалось
в формате BGR, а не RGB, который ожидали функции Xlib-а.
2/16/2014 12:57 AM, Ops пишет:
> V>http://www.cplusplus.com/ > Не надо это советовать, там ересь встречается.
Не, форум и писатели здесь восхитительны.