| 
			| 
					
						| spiage 
								Гость
 | 
								|  | «  : 16-08-2004 02:11 »  |  | 
 
 Привет! Столкнулся с такой проблемой при побайтном чтении файла: char c;ifstream ifile("foo.dat", ios::in | ios::binary);
 ifile >> c;
Так вот - если код символа > 128, то число получается отрицательным Для преобразования приходится делать так: int i = (int)(unsigned char)c;Если использовать сразу unsigned char, то чтение идет неверное... Есть ли у кого мысли по этому поводу? (Мне действительно необходимо ПОБАЙТНОЕ чтение, работаю напрямую с DBF) И еще вопрос - можно ли на С++ работать при file I/O сразу со структурой, как в Паскале? Или все же нет такой встроеной возможности? ICQ для связи: 127834898 Пример: typeRec = record
 i: byte;
 s:string[12];
 w:word;
 end;
 var
 f: file of Rec;
 r: Rec;
 begin
 ........
 read(f, r);
 ........
 end.
 |  
						| 
								|  |  
								| « Последнее редактирование: 30-11-2007 22:26 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #1 : 16-08-2004 05:03 »  |  | 
 
 Так вот - если код символа > 128, то число получается отрицательным
 Для преобразования приходится делать так:
 
 Мне действительно необходимо ПОБАЙТНОЕ чтение
 
 попробуй объявить не char  c, а: UCHAR c; или BYTE c;  :arrow:  И еще вопрос - можно ли на С++ работать при file I/O сразу со структурой, как в Паскале?
 
 может и нет, не знаю. Наверное надо будет самому писать класс, который будет делать то, что нужно |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| spiage 
								Гость
 | 
								|  | « Ответ #2 : 16-08-2004 07:31 »  |  | 
 
 У меня было: Если использовать сразу unsigned char, то чтение идет неверное...
 
 Ты посоветовал: попробуй объявить не char c, а:
 
 UCHAR c;
 
 или
 
 BYTE c;
 
   Но я все равно поверил (видно сказывается привычка Windows-пользователя бить в барабаны и устраивать пляски, в надежде, что все получится     ) Все равно глючит   Проскакивает через байт... А по поводу чтения структур есть у меня мысль, что через указатель с размером, равным структуре, вполне можно проделать такую штуку... Лишь бы компилятор порядок следования элементов в структуре не нарушал... |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #3 : 16-08-2004 07:41 »  |  | 
 
 spiage, конэчно можно. вот тебе примерчик. #include <fstream>#pragma pack(push,1)
 struct s
 {
 int i;
 long l;
 float f;
 s() i(10), l(20), f(40)
 {}
 };
 
 void main()
 {
 std::fstream fs( "pr.bin", std::ios::binary | std::ios::out | std::ios::in );
 if(!fs.is_open())
 return;
 s ss;
 fs.write( (char *)&ss,  sizeof(ss));
 fs.read((char *)&ss,  sizeof(ss));
 return;
 }
 #pragma pack(pop)
 
 |  
						| 
								|  |  
								| « Последнее редактирование: 30-11-2007 22:28 от Алексей1153++ » |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #4 : 16-08-2004 07:42 »  |  | 
 
 и вот эти строчки помогут с твоей проблеммкой #pragma pack(push,1).....
 #pragma pack(pop)
 
 |  
						| 
								|  |  
								| « Последнее редактирование: 30-11-2007 22:29 от Алексей1153++ » |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #5 : 16-08-2004 07:43 »  |  | 
 
 можешь спросить меня что эта прагма делает   |  
						| 
								|  |  
								|  |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| spiage 
								Гость
 | 
								|  | « Ответ #6 : 16-08-2004 08:21 »  |  | 
 
 А вот так  почему? BYTE c;cout << ifile.tellg() << endl;
 ifile >> c;
 cout << ifile.tellg() << endl;
 
Ответ: |  
						| 
								|  |  
								| « Последнее редактирование: 30-11-2007 22:29 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #7 : 16-08-2004 08:29 »  |  | 
 
 можно весь пример а не только вом это
 BYTE c;
 cout << ifile.tellg() << endl;
 ifile >> c;
 cout << ifile.tellg() << endl;
 
 чем инитится с?
 где обявление ifile?
 просто возникают вопросы
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| spiage 
								Гость
 | 
								|  | « Ответ #8 : 16-08-2004 08:32 »  |  | 
 
 #ifndef BYTEtypedef unsigned char BYTE;
 #endif
 ...
 ifstream ifile(FileName.c_str(), ios::in | ios::binary);
 BYTE c;
 ...... (несколько _удачных_ чтений в "с")
 cout << ifile.tellg() << endl;
 ifile >> c;
 cout << ifile.tellg() << endl;
 ifile.close();
 |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| spiage 
								Гость
 | 
								|  | « Ответ #9 : 16-08-2004 09:16 »  |  | 
 
 Нет, вы представте - я поменял  на только в одном месте (где "пролет над байтом" был), и все нормально стало... Похоже, что это глюк компилятора... (Пользовался С++Builder 6.0 Build 10.155, Windows 2003 Enterprise Server) |  
						| 
								|  |  
								| « Последнее редактирование: 30-11-2007 22:30 от Алексей1153++ » |  Записан | 
 |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #10 : 16-08-2004 09:27 »  |  | 
 
 spiage, я тебе и говорил, что от этих новшеств - аля << и >> я давно отказался, мне понятнее работа  ifile.get(c), ifile.read(c, sizeof(c)), ifile.write(c, sizeof(c)) |  
						| 
								|  |  
								|  |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| Алексей++ 
								глобальный и пушистыйГлобальный модератор    Offline 
								Сообщений: 13
								
								
								
								
								
							 | 
								|  | « Ответ #11 :  16-08-2004 09:37 »   |  | 
 
 spiage,     , вот такой я невнимательныйPu , а  что эта прагма делаетъ?   |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| Pu 
								Большой босс    Offline 
								78
								
								
								
								
								
							 | 
								|  | « Ответ #12 : 16-08-2004 09:55 »  |  | 
 
 Алексей1153,  прагма указывает на сколько при операциях чтения записи делать выравнивание. если не указать единичку то char вместо 1 байта считает и запишет 4 байта, тк в виндах по умолчанию выравнивание по двойному слову. Я на эту фигню нарвался еще давненько когда с доса пересел под винду. подробнее ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1033/vclang/html/_PREDIR_pack.htm
 |  
						| 
								|  |  
								|  |  Записан | 
 
 Насколько я опытен? Достаточно, чтобы понимать, что дураков нельзя заставить думать по–другому, но недостаточно, чтобы отказаться от попыток это сделать.(с) Артур Джонс
 |  |  | 
	| 
			| 
					
						| spiage 
								Гость
 | 
								|  | « Ответ #13 : 16-08-2004 10:02 »  |  | 
 
 А так хотелось по-умному...   |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| npak | 
								|  | « Ответ #14 : 16-08-2004 13:59 »  |  | 
 
 spiage, очень странный эффект случился с реализацией istream на MS МЫ 6.0 -- даже при установке режима чтения binary оператор >> перескакивает через байты конца строки.  Возможно, это причина твоей проблемы.
 Можно сделать вот как:
 #ifndef BYTE
 typedef unsigned __int8 BYTE;
 #endif
 
 BYTE & operator >> (istream & inf, BYTE & b) { inf.read((char *)&b,1); return b; }
 
 При таком задании байта и оператора чтения оператор >> не перескакивает через концы строк.
 
 Этот пример показывает технику чтения-записи структур в потоки.  При создании своего класса/структуры надо определить свои операторы << и >> для них.  Правда, предложенный Pu способ прямой записи содержимого структуры через read(p, sizeof(*p)) не подходит для структур и классов, содержащих указатели.
 |  
						| 
								|  |  
								|  |  Записан | 
 
 |  |  | 
	| 
			| 
					
						| spiage 
								Гость
 | 
								|  | « Ответ #15 : 17-08-2004 02:21 »  |  | 
 
 npak, Твой вариант подошел, работает вполне нормально без pragma pack(1), и даже с установленной в настройках компилятора Data alignment = Quorted Word (если я правильно понял - это аналог pragma pack(8 )) Теперь можно к сказанному тобой добавить, что "странная" реализация istream не только на MS VS 6.0 но и на Borland C++Builder 6.0 У меня есть предположение  :idea: , что это из-за того, что в STL::iostream в шаблоне basic_istream реализация operator>> дана только для одного 8-и битного типа - для типа char, который является знаковым по дефолту... А учитывая, что эта ошибка проявляется вполне произвольно, думаю, что глюк где-то в реализации... 8) Если будет время - полезу в кишки STL...  :new_shot:  А по хорошему лучше бы вставить в стандарт операцию с бесзнаковым символом    |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	|  |