Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Tavujen tulkitseminen int-tyyppisenä tietona

Oskuz [05.02.2015 19:28:44]

#

Miten tekisin seuraavan:

int a = muunna_luvuksi("1234",sizeof(int));

Eli a:n arvo ei olisi 1234 vaan muistipaikassa a:n tavujen arvot olisi 41,42,43 ja 44? Ja toisaalta miten sen voi tehdä toisin päin?

peran [05.02.2015 20:09:19]

#

Mikäli käytät C:tä, niin silloinhan arvot ovat juuri siten taulukossa, kuten yrität tehdä.

Kyseessä vaan tulostetaan numeroina eikä merkkeinä.

int i;
char a[]="1234";
printf ("%s",a);
for(i=0,i<strlen(a);i++) {
     printf ("%i ",a[i]);
}
printf("\n");

Koodi on viitteellinen, eikä testattu. Eikä ehkä ole puhdasta C:tä.

Metabolix [05.02.2015 20:12:41]

#

peran, varmaan tarkoitus oli kuitenkin saada ne tavut sijoitettua yhteen int-muuttujaan.

Tässä on kolme tapaa muunnokseen molempiin suuntiin.

#include <algorithm>
#include <string.h>
#include <stdio.h>

int main() {
	// esimerkkidata
	typedef char int_str_t[sizeof(int)];
	int_str_t s = {'1', '2', '3', '4'}, sa, sb, sc;
	int i = 0x34333231, ia, ib, ic;

	// memcpy
	memcpy(&ia, s, sizeof(int));
	memcpy(sa, &i, sizeof(int));

	// std::copy_n
	std::copy_n(s, sizeof(int), (char*)&ib);
	std::copy_n((const char*)&i, sizeof(int), sb);

	// sijoitus
	ic = *(const int*)s;
	*(int*)sc = 0x34333231;

	// malliksi vielä tulostus
	printf("%#10x %#10x %#10x\n", ia, ib, ic);
	printf("%.4s %.4s %.4s\n", sa, sb, sc);
}

Muista, että joissain koneissa on eri tavujärjestys ja eri määrä tavuja int-muuttujassa.

peran [05.02.2015 20:21:19]

#

Metabolix kirjoitti:

peran, varmaan tarkoitus oli kuitenkin saada ne tavut sijoitettua yhteen int-muuttujaan.

Joo, varmaan ymmärsin väärin.

jalski [05.02.2015 21:03:51]

#

Tukeeko C unionia? Itse jättäisin laskemisen ja tavujärjestyksestä huolehtimisen kääntäjälle.

Esim PL/I:llä kävisi huomattavasti Metabolixin esimerkkiä yksinkertaisemmin:

dcl 1 char_byte union,
      2 chars char(4),
      2 bytes (0:3) fixed bin(8) unsigned,
      2 dword fixed bin(32) unsigned;


chars = '1234';
put skip list (chars, hex(dword));

Metabolix [05.02.2015 21:16:42]

#

jalski kirjoitti:

Tukeeko C unionia? Itse jättäisin laskemisen ja tavujärjestyksestä huolehtimisen kääntäjälle.

Millä tavalla tämä vaikuttaa sen paremmin laskemiseen kuin tavujärjestykseenkään verrattuna yllä näyttämääni sijoitukseen? Pystytkö PL/I:n unionissa itse vaikuttamaan siihen, tuleeko tavuista '1234' luku 0x31323334 (big endian) vai 0x34333231 (little endian)? C:ssä tämä ei ainakaan onnistu, vaan luvut ovat järjestelmäriippuvaisessa muodossa.

Ja kyllä, C tukee myös unioneja. Niistä ei ole tässä hyötyä. C:ssä tavujen kopiointi muuttujasta toiseen (ilman lopettavaa nollatavua) on niin hankalaa, että siinä aukeaa taas paikka monelle uudelle virheelle kopioitavan määrän suhteen.

jalski [05.02.2015 21:36:21]

#

Metabolix kirjoitti:

Pystytkö PL/I:n unionissa itse vaikuttamaan siihen, tuleeko tavuista '1234' luku 0x31323334 (big endian) vai 0x34333231 (little endian)? C:ssä tämä ei ainakaan onnistu, vaan luvut ovat järjestelmäriippuvaisessa muodossa.

Itse asiassa kyllä, lisäämällä muuttujan perään "littleendian" tai "bigendian" attribuutti. Tässä laittamalla ykköstason union määrittelyn jälkeen attribuutti, vaikuttaa se koko unioniin.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta