Jak převést char[4] na na uint32_t? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jak převést char[4] na na uint32_t? – C / C++ – Fórum – Programujte.comJak převést char[4] na na uint32_t? – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
oxidián0
Grafoman
11. 2. 2015   #1
-
0
-

Načetl jsem 4 bajty z binárního souboru: "\000\000\000\020" string reprezentuje číslo (pozici v souboru).

Jak převést n na uint32_t abych dostal offset?
 

  uint32_t header_offset;
  .... 
  char n[4];
  size_t in;
  in = fread(n, 4, 1, fp);
  if (!in)
    return -2;
  header_offset = (uint32_t ) n; // get 4 bytes string to integer

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 2. 2015   #2
-
0
-

no jelikoz to vypada na big endian, tak prinejmensim  header_offset = ntohl(*((uint32_t *)n));

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 2. 2015   #3
-
0
-

A ve standardním C něco není? Já jen že to asi nemám na počítači píse mi to undefined reference to `ntohl'|

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 2. 2015   #4
-
0
-

no musis se mrknout na google, v jakem hlavickovem souboru to je a pripadne jaka je nahrada pro tvuj prohlizec...

urcite to neni v zakladu, je to zavisly na procesoru a tak

nebo to holt prohazet  - na netu jsou ukazky, jak se da vymenit byte order - nicmene  ntohl  to muze i nechat tak jak to je, pokud je procesor big endian

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BDS+3
Věrný člen
11. 2. 2015   #5
-
0
-

#3 oxidián
můžeš to udělat sám: 

unsigned int SwapUINT(unsigned int v)
{
  unsigned int i,r;
  for (i=0; i<4; i++) *((unsigned char *)&r + i) = *((unsigned char  *)&v + (3 - i));
  return r;
}
Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
KIIV
~ Moderátor
+43
God of flame
11. 2. 2015   #6
-
0
-

#5 BDS
no to uz by lip vypadalo:



#define BSWAP32(n) ((n) >> 24) | (((n) << 8) & 0x00FF0000L) | (((n) >> 8) & 0x0000FF00L) | ((n) << 24)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
BDS+3
Věrný člen
11. 2. 2015   #7
-
0
-

#6 KIIV
:) pravda

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #8
-
0
-

BDS: ale nefunguje mi to správně.  Dostal jsem číslo 2969117184 a to je příliš vysoké. Očekávám že offset by mohl být několik desítek bytů.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
11. 2. 2015   #9
-
0
-

Něco mi uniká. Proč nemohu zkopírovat kód ze stránky jako normální člověk?

Nemohl bys to poslat na externí link?

Tohle se fakt číst nedá:

#define BSWAP32(n) ((n) &gt;&gt; 24) | (((n) &lt;&lt; 8) &amp; 0x00FF0000L) | (((n) &gt;&gt; 8) &amp; 0x0000FF00L) | ((n) &lt;&lt; 24)

Tak jestli jsem do dopře opsal tak mi to hlásí:

 

#define BSWAP32(n) ((n) << 24) | (((n) >> 8) & 0x00FF0000L) | (((n) >> 8) & 0x0000FF00L) | ((n) << 24)header_offset = SwapUINT(n); // get 4 bytes string to integer
header_offset = SwapUINT(n);
header_offset = BSWAP32(n);

warning: passing argument 1 of 'SwapUINT' makes integer from pointer without a cast

note: expected 'unsigned int' but argument is of type 'char *'|

invalid operands to binary << (have 'char *' and 'int')|

Nahlásit jako SPAM
IP: 78.45.199.–
BDS+3
Věrný člen
11. 2. 2015   #10
-
0
-

#8 oxidián
určitě ta funkce funguje správně

samozřejmě taky můžeš použít makro od KIIV, nebo taky: 

unsigned int SwapUINTfromChars(unsigned char n[])
{
 return(
 n[0] * 0x01000000 +
 n[1] * 0x010000 +
 n[2] * 0x0100 +
 n[3]);
}
Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
BDS+3
Věrný člen
11. 2. 2015   #11
-
0
-

#9 oxidián
asi nepoužíváš prohlížeč jako normální člověk :D

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #12
-
0
-

Hodnotu char[4] jsem posílal: je "\000\000\000\020" bez uvozovek

Nahlásit jako SPAM
IP: 78.45.199.–
BDS+3
Věrný člen
11. 2. 2015   #13
-
0
-

#9 oxidián
 'unsigned int' but argument is of type 'char *'|

nemůžeš měnit char* na int

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
BDS+3
Věrný člen
11. 2. 2015   #14
-
0
-

uint32_t header_offset;
  .... 
  //char n[4];
  unsigned int val;
  fread(&val, 4, 1, fp);
  ...
  header_offset = BSWAP32(val); 

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #15
-
0
-

Poslední funkce funguje skvěle (SwapUINTFromChar), dík.

PS: Používám Firefox v32.0.1

Nahlásit jako SPAM
IP: 78.45.199.–
BDS+3
Věrný člen
11. 2. 2015   #16
-
0
-

#15 oxidián
funguje, protože očekává pole charů, ne int. Ty předešlé fungují taky, ale předával si jim nesprávný parametr!

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #17
-
0
-

Já? Spíš ty, ne? Já to pouze opsal jak si to udělal ty.

Nahlásit jako SPAM
IP: 78.45.199.–
BDS+3
Věrný člen
11. 2. 2015   #18
-
0
-

#17 oxidián

kdyby si to opsal tak si to měl udělat takto:

  uint32_t header_offset;
  .... 
  char n[4];
  size_t in;
  in = fread(n, 4, 1, fp);
  if (!in)
    return -2;
  header_offset = BSWAP32(*(unsigned int*)n); 

nebo ještě lépe jak jsem napsal v #14:

unsigned int val;
  fread(&val, 4, 1, fp); //(načítat přímo do intu)
  ...
  header_offset = BSWAP32(val);

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #19
-
0
-

Teď jsem zjistil, že ta hlavička je v little-endian. Mění se tím něco?

Nahlásit jako SPAM
IP: 78.45.199.–
BDS+3
Věrný člen
11. 2. 2015   #20
-
0
-

#19 oxidián
tak to nemusíš přehazovat na big

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #21
-
0
-

Já nevím, já tomu vůbec nerozumím. Snažím se přečíst data z hlavičky BMP souboru, ale nevyznám se ani v té tabulce* bytů natož kde má být správná pozice. Takže z toho co ste mi tu napsali nemám nic protože nevím co je správný výsledek.

Poznámka: nesedí mi to co čtu v té tabulce s tím co čtu v souboru bmp v hex editoru.

Soubor mi začíná dvěma byty BM identifikující soubor BMP: 424D Pak tam má být velikost hlavičky 4 byty je tam napsáno 3600 0003 když to převedu na kalkulačce z HEX do DEC tak výjde číslo přes 900 Megabyte, což je nesmysl, soubor rgb 4096x4096 má zabírat kolem 49 megabyte.

edit:

A offset má v souboru: 0000 3600

ještě jednou to opíšu celé:

424D 3600 0003 0000 0000 3600 0000

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
11. 2. 2015   #22
-
0
-

Tak mi to nesedí. Zase mi vychází to číslo 905969664 nevím proč. A to čtu správně pozici header_offset od 10 bytu (správná hodnota by měla být "6\000\000").

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 2. 2015   #23
-
0
-

nicmene 0x03000036 dava 50331702 coz uz tech 49MB bude.. kazdopadne to uz vypada na little endian a bude ti stacit nacist to rovnou jako uint

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
11. 2. 2015   #24
-
0
-

Nevím ale kde bereš těch 0x03000036  Takové číslo tam není. Jestli myslíš 03 0000 0000 36 tak to je omyl - velikost souboru má být podle dokumentace na wiki 3600 0003 - tedy byty 02-05 by měli dávat velikost souboru. Další 4 byty jsou vyhrazeny pro aplikaci (to jsou ty podtržené) a poslední 4 mají být header_offset

Lépe přiložím odkaz:

http://oi62.tinypic.com/2rcopoo.jpg

Připojen obrázek.

Nahlásit jako SPAM
IP: 78.45.199.–
oxidián0
Grafoman
11. 2. 2015   #25
-
0
-

Počkat, když upravím příkaz fseek na pozici +1: tak mi to dá zajimavý výsledek:

fseek (fp, result->header_offset_position+1, SEEK_SET);

"\000\000\000("

Což je header_offset 40 a to by už bylo v pořádku. Takže problém byl asi v tom, že offset je kde končí předchozí sekce (na 10 bytu), ale následující sekce je offset +1

(11 byte čili 11,12,13,14 je ten header_offset).

Nahlásit jako SPAM
IP: 78.45.199.–
BDS+3
Věrný člen
11. 2. 2015   #26
-
0
-
Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
BDS+3
Věrný člen
11. 2. 2015   #27
-
0
-

#24 oxidián
0x03000036 je na offset pozici 2 ve formátu 0x36000003

Nahlásit jako SPAM
IP: 31.47.99.–
W11 :)
oxidián0
Grafoman
11. 2. 2015   #28
-
0
-

Aha, takže vy ti čísla čtete pozpátku! Snad už vás chápu.

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
11. 2. 2015   #29
-
0
-

precti si pojem little a big endian.. 

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 42 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý