• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zmienna string, a plik binarny. Dziwne znaki po odczytaniu

Object Storage Arubacloud
0 głosów
250 wizyt
pytanie zadane 13 marca 2018 w C i C++ przez Łukasz Wasilewski Mądrala (5,190 p.)

Cześć,

pracuję właśnie nad systemem który będzie zapisywał wcześniej przygotowane mapy w edytorze do pliku binarnego.

Konstrukcja pliku składa się z nagłówka, który wygląda tak:

struct mapFileHeader
{
	int numOfTitleChars;
	int mapWidth;
	int mapHeight;
	int numOfObjets;
};

Pierwsza zmienna zapisana do pliku określa ilość znaków składających się na tytuł mapy, który zapisywany jest od razu po zapisaniu headera:

// header
file.write((char *)(&mapHeader), sizeof(mapFileHeader));	

// map title
file.write((char *)mapName.c_str(), strlen(mapName.c_str()));

Następnie, gdy próbuję odczytać tytuł swojej mapy:

char* src = new char[mapHeader.numOfTitleChars];
file.read((char *)src, mapHeader.numOfTitleChars * sizeof(char));
mapName = string(src);

cout << "mapname: " << mapName << ", " << string(src) << endl;
delete src;

Otrzymuję coś takiego: 

Edit: Poprzednio się nie wrzucił, podsyłam. :) 

Nazwa mapy powinna być "My Map", co sugeruje, że może odczytuje za dużo bitów? 

Siedzę już nad tym trochę, dlatego będę wdzięczny za pomoc.  

1 odpowiedź

+2 głosów
odpowiedź 13 marca 2018 przez monika90 Pasjonat (22,940 p.)
wybrane 13 marca 2018 przez Łukasz Wasilewski
 
Najlepsza
Pewnie odczytany łańcuch znaków nie jest zakończony zerem, więc zamiast tego

mapName = string(src);

zrób tak

mapName = string(src, mapHeader.numOfTitleChars);

albo tak

mapName.assign(src, mapHeader.numOfTitleChars);

 

A tak w ogóle, to nie ma potrzeby alokowania pomocniczej tablicy, można wczytać tekst od razu do stringa:

mapName.resize(mapHeader.numOfTitleChars);

file.read(&mapName[0], mapName.size());
komentarz 13 marca 2018 przez Łukasz Wasilewski Mądrala (5,190 p.)

Faktycznie, teraz gdy wspomniałeś o zerze, pamiętam, że string kończy się '\0'.

Dziękuję za pomoc. smiley

1
komentarz 13 marca 2018 przez mokrowski Mędrzec (155,460 p.)
std::string wbrew swej nazwie, może przetrzymywać dane binarne bezpośrednio. Dopiero wykonując na nim c_str(), dostajesz "string w stylu C" czyli terminowany zerem. To może być wygodne lub niebezpieczne w zależności od tego jakie dane binarne są w nim umieszczone (może tam być przecież wiele '\0'). Masz metodę size() na obiekcie std::string, pobierającą ilość tychże danych.

Podobne pytania

0 głosów
1 odpowiedź 1,167 wizyt
0 głosów
1 odpowiedź 1,821 wizyt
pytanie zadane 27 września 2017 w C i C++ przez B0nkers Początkujący (310 p.)
0 głosów
5 odpowiedzi 1,649 wizyt
pytanie zadane 13 września 2015 w Rozwój zawodowy, nauka, praca przez Matieusz Nowicjusz (120 p.)

92,551 zapytań

141,393 odpowiedzi

319,523 komentarzy

61,936 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...