Jump to content
  • Announcements

    • Xmat

      Pravidlo pro postování v TTT

      Do sekce Tipy, triky, tutoriály nepatří žádné dotazy.   Postujte sem vaše návody, tipy a různé další věci jež uznáte za vhodné sdělit zdejšímu osazenstvu, ale veškeré dotazy směřujte do sekce Všeobecná diskuse.
    • Replik

      Seznam návodů a důležitých témat v této sekci

      Pro lepší přehlednost jsem vytvořil tento seznam, který vás, méně zkušené, lépe provede touto sekcí. Věřím, že zde najdete, co hledáte. Vypsané jsou návody, které jsou oficiálně uznané jako návody. Běžné diskuze, které neposkytují postupy a rady zvěřejněny nejsou.   Instalace vlastního MaNGOS Serveru Díky těmto návodům budete (měli by jste být) schopni vytvořit a následně spustit váš vlastní server. Nastavení je pro verze s i bez datadisku.   Instalace MaNGOS Serveru (bez datadisku TBC) - Autor Benny Instalace MaNGOS Serveru (s datadiskem TBC) - Autor Malfik Instalace MaNGOS Serveru v prostředí Linux - Autor charlie Instalace MaNGOS Serveru v prostředí Linux - Autor kupkoid   Chyby a jejich řešení při přihlašování k serveru - Autor Cybe   Zálohování uživatelských dat   Dávkový soubor (BAT soubor) pro vytvoření SQL záloh - Autor Replik   Kompilování - tvoření vlastních release (revizí)   Tvorba kompilací pro Win32 (MangoScript) - Autor bLuma   Ostatní - těžko zařaditelné, ale neznamená to, že nejsou dobré   VIP Systém - Autor charlie Tvorba Webových stránek pro MaNGOS - Autor zahuba Tvorba teleportačních NPC (MangoScript) - Autor Replik Registrační web (původně předělaná SPORA) Funkční pro Antrix i MaNGOS - Autor Replik Nastavení a spuštění Minimanager pro MaNGOS - Autor BlackMartin Nastavení MaNGOS Website - Autor Artorius   Samozřejmě jsou zde i jiné návody, ale tyto jsou nejvíce používané, proto věřím, že vám budou nápomocné. Tuto sekci budeme upravovat podle potřeby. Pokud by jste něco nenašli nebo si nevěděli rady, hledejte na fóru a teprve potom založte vlastní topik. Pokud nějaký autor vytvoří kvalitní návod a chtěl by ho zveřejnit i v tomto seznamu, doporučuji, aby mi napsal zprávu skrze PM.   Díky a přeji hezký den na WoWResource   Replik
    • Aristo

      Příspěvky tam, kde nemají co dělat

      Dodržujte zákaz přispívání do topiků s repaky pokud si to zakladatelé nepřejí!! Opakované psaní příspěvků bude trestáno warnem.
    • Aristo

      Používání spoilerů

      Poslední dobou má většina uživatelů fora zvláštní nutkání postovat extrémně dlouhé texty nebo kódy, které zabírají v nejedenom případu i 80% obsahu celé stránky a hodně tak zvedají nepřehlednost v topiku. Chtěl bych všechny uživatele požádat, aby při postování citací, jakýchkoliv kódů, errorů, atp... delších než 30 řádků používali funkci spoileru.   Funkci vyvoláte příkazem [spoiler] text [/spoiler]   Ukázka:  
Sign in to follow this  
Spichy

[Otázka] C++ předání dat ze souboru do struktury

Recommended Posts

Zdravíčko.

Snažím se získat data ze souboru do struktury, ale nevím, jak vytvořit array, když předem neznám délku příchozích dat.

 

 

Blok dat

... v prvních 4 bajtech je jméno headeru v další 4 je délka a zbytek je list souborů, které jsou oddělené mezerou
00 58 45 54 4D 9E 00 00 00 74 69 6C 65 73 65 74 5C 64 75 73
6B 77 61 6C 6C 6F 77 20 6D 61 72 73 68 5C 64 75 73 6B 77 61
6C 6C 6F 77 72 6F 63 6B 6C 69 67 68 74 65 72 2E 62 6C 70 00
74 69 6C 65 73 65 74 5C 64 75 73 6B 77 6F 6F 64 5C 64 75 73
6B 77 6F 6F 64 64 69 72 74 32 2E 62 6C 70 00 74 69 6C 65 73
65 74 5C 65 6C 77 79 6E 6E 5C 65 6C 77 79 6E 6E 67 72 61 73
73 62 61 73 65 2E 62 6C 70 00 74 69 6C 65 73 65 74 5C 65 6C
77 79 6E 6E 5C 65 6C 77 79 6E 6E 67 72 61 73 73 73 68 61 64
6F 77 2E 62 6C 70 00
....

 

 

kód:

struct MTEX
{
char sign[4];
uint32 byte_size;
unsigned char filelist;
};
...

stringstream buffer;
ifstream tempFile("template.adt", ios::in | ios::binary);
...
MTEX tempFileMtex;

...
tempFile.read((char *)&tempFileMtex, sizeof(MTEX));
tempFile.close();
...

Struktura s unsigned charem zaznamená pouze prvních 8 bajtů

Napadlo mě použít stringstream, který získá potřebná data, ale svou velikostí zasahuje do dalších datových bloků.

Předem děkuji za rady :)

Share this post


Link to post
Share on other sites

Kdyz mluvime o definici "nezname" velikosti, lze pouzit:

 

int * ukazatel;
int velikost;
ukazatel = new (nothrow) int [velikost];
if (ukazatel == 0) {
// Problem s pridelovanim pameti.
};

 

(nothrow) = kdyz prirazovani pameti selze, tak se nastavi na NULL

 

Nejsem C++ odbornik, spise takova lamka, radeji pockam na nekoho zkusenejsiho...

Edited by raxume

Share this post


Link to post
Share on other sites

vektor by byl dobrý, pokud by šlo o blok dat pro array, tady jsem potřeboval použít buffer pro text s neurčenou délkou.

 

EDIT:

Tak jsem to vyřešil. Přepsal jsem to do OOP, přidal templates pro zmenšení kódu.

Snippet:

 

 

 

template<typename T> T ReadInFile()  
{
 T ret;
 _mInFile.read((char*)&ret, sizeof(T));
 mInFilePos = (int)_mInFile.tellg();
 return ret;
}
template<typename T> void ReadInFile(T& var, int size = 0)
{
 int s = size > 0 ? sizeof(var) : size;
 _mInFile.read((char*)&var, s);
 mInFilePos = (int)_mInFile.tellg();
}
...
struct MTEX
{
uint32 signature;
int size;
char* fileList[1024];
};
...
mVerData = ReadInFile<MVER>();
mHdrData = ReadInFile<MHDR>();
int mTexDataSize  = (int)ReadInFile<uint32>(mHdrData.ofsMtex + 24); //24 bytes = MVER(12) + MHDR hdr(4) + MHDR size(4) + MHDR flags(4)
ReadInFile<MTEX>(mTexData, mTexDataSize);
...

 

 

 

Stále se zajímám, zda je možný jiný způsob, který by více šetřil paměť.

Díky, Spichy.

Edited by Spichy

Share this post


Link to post
Share on other sites

Co ti brání použít přístup, který doporučuje použit raxume? Netuším v jakém formátu jsou následná data uložena, ale můžeš si uložit na první pozici jeden int, který říká kolik následuje bytes a potom ten počet přečíst do dynamicky alokovaného pole.

 

Jinak pole bytes se dá v pohodě konvertovat do struktury. http://stackoverflow.com/questions/8082652/typecasting-from-byte-to-struct

  • Upvote 2

Share this post


Link to post
Share on other sites

Jde o soubory *.ADT, ze hry World of Warcraft (World/Maps/). Abych pravdu řekl, nenapadá mě způsob jakým využít nothrow, osobně si myslím, že je jednodušší načíst data rovnou jako char, jelikož data udávají cestu k texturám uložené v MPQ.(Tileset\Wetlands\Wetlandsdirt01.blp,...) Daná data ze souboru ukládám do několika struktur, abych je mohl později editovat a upravená data uložit do nového souboru.

Share this post


Link to post
Share on other sites

To (nothrow) je jen vec navic, nastavi to hodnotu toho pole na NULL,kdyz to selze, nic vic. On mluvi o tom dynamickem poli celkove.

Edited by raxume
  • Upvote 1

Share this post


Link to post
Share on other sites

Jde o to, že nevím jak deklarovat strukturu tak, aby to pobral read a načetl data do určené struktury správně. Když definuji délku charu pomocí konstruktoru char se nenaplní daty.. Možná jsem na to šel špatně.

Share this post


Link to post
Share on other sites

Nerozumím problému. Když budeš mít strukturu a v ní ukazatel na pole typu byte, tak prostě vytvoříš novou strukturu a alokuješ dynamické pole a ukazatel uložíš to té struktury?

 

Tady máš spoustu příkladů pro práci se strukturami.

  • Upvote 2

Share this post


Link to post
Share on other sites

Snažíš se načíst blok dat s nepravidelnou strukturou (proměnné délky řetězců) do přesně definované struktury, to ti prostě nepůjde. V zásadě máš několik možností, jak to řešit... Načíst to jako blok dat a pak pracovat s odkazy na začátky řetězců (nepamatuji si, jak jsou ty odkazy realizovány v těch souborech, jestli to je na index/offset do toho chunku). Pokud je to offset, tak ti tohle může pro čtení vyhovovat, pro případné změny to už je trochu problém. Pokud je to index, tak můžeš mít blok dat a vybudovat si přístupový index nebo ještě lépe si to rovnou převést do vektoru. Ale to musíš udělat ručně, postupným procházením toho bloku.

  • Upvote 2

Share this post


Link to post
Share on other sites

Aha, to je přesně to co jsem potřeboval vědět..

MTEX udává zero-terminated odkazy k *.BLP, MMDX udává zero-terminated odkazy k *.M2, které se v mapě nachází. MMID pak udává offset který referuje pro MDDF blok s doodads,.

 

Zkusím načíst blok do bufferu a s 0x00 explodovat data do vektoru, pak dám vědět. Zatím děkuji.

 

Edit:

char * ReadInFile(int pos, int len)
{
 char * ret = new char[len];
 _mInFile.seekg(pos);
 _mInFile.read(ret, len);
 _mInFile.seekg(mInFilePos);
 return ret;
}
...
struct MTEX
{
 uint32 signature;
 int size;
//char* fileList[1024];
 std::vector<std::string> filenames;
};
...
void AdtFile::LoadMTEX(int len)
{
 mTexData.signature = 'XETM';
 mTexData.size = len;
 char * buffer = ReadInFile(mHdrData.ofsMtex + 28, len);
 vector<string> vec;
 stringstream ss;
 for(int i = 0; i < len; i++)
 {
if(buffer[i] != 0x00)
  ss << buffer[i];
else {
  vec.push_back(ss.str());
  ss.str("");
  ss.clear();
}
 }
 mTexData.filenames = vec;
 for(vector<string>::iterator iter = mTexData.filenames.begin(); iter != mTexData.filenames.end(); ++iter)
   printf("%s \n", *iter);
}

 

Output:

Tileset\Wetlands\Wetlandsdirt01.blp
Tileset\TirisFall\TirisFallDirtRock07.blp
Tileset\TirisFall\TirisFallRockyMudGrass.blp
Tileset\TirisFall\TirisFallRockyMudGrassHighlight.blp
Tileset\TirisFall\TirisfallShore.blp
Tileset\RedRidge\RedridgeRockRoadBase.blp
Tileset\Elwynn\ElwynnDirtBase2.blp
Tileset\TirisFall\TirisFallgrass01.blp
Tileset\Duskwood\DuskwoodRockGravel.blp
Tileset\Deadwind Pass\DeadwindPassRockBase.blp

 

Děkuji mockrát :)

Edited by Spichy
  • Upvote 2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×