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

zamiana strumieni na string

+1 głos
496 wizyt
pytanie zadane 23 lipca 2015 w C i C++ przez Pan Kulomb Pasjonat (18,630 p.)
edycja 23 lipca 2015 przez Pan Kulomb

Witam, chciałbym aby deklaracje funkcji wyglądały następująco:

string write_word(Word value);
Word read_word(string converted);

Nie wiem jak się pozbyć strumieni. Mogą być wewnątrz funkcji.

template <typename Word>
ostream& write_word( ostream& outs, Word value )
  {
  for (unsigned size = sizeof( Word ); size; --size, value >>= 8)
    outs.put( static_cast <char> (value & 0xFF) );
  return outs;
  }
 
1
2
3
4
5
6
7
template <typename Word>
istream& read_word( istream& ins, Word& value )
  {
  for (unsigned size = 0, value = 0; size < sizeof( Word ); ++size)
    value |= ins.get() << (8 * size);
  return ins;
  }

1 odpowiedź

+1 głos
odpowiedź 5 sierpnia 2015 przez Bartek85 Mądrala (7,440 p.)
wybrane 8 sierpnia 2015 przez Pan Kulomb
 
Najlepsza

Okej, mam pytanie dla pewnosci zrozumienia problemu.

Chciałbyś "zserializować" typ generyczny "Word" do postaci bajtów w stringu, a później wykonać operację odwrotną?

Jeżeli tak to jest kilka rzeczy dla których ten mechanizm nie będzie działał poprawnie i uniwersalnie:

1) Dla typów przekazanych przez wartość

  • Typ atomowy - da się to wykonać
  • Typ obiektowy nie zawierający w sobie obiektów dynamicznych - da się to wykonać
  • Typ obiektowy zawierający w sobie obiekty dynamiczne - NIE da się wykonać

2) Dla typów wskaźnikowych nie da się tego wykonać.

Twoja obecna implementacja jest równiez nie odporna na przypadki które podałem.

Poniższy kod powinien działać dla typów prostych oraz dla typów obiektowych przekazanych przez wartość i nie zawiarających w sobie elementów dynamicznych.

template <typename T>
std::string write_word(T value)
{	
	unsigned int sizeOfType = sizeof(T);
	const char* pSrc = reinterpret_cast<const char*>(&value);	
	std::string output(pSrc, sizeOfType);
	return output;
}

template <typename T>
T read_word(const std::string& s)
{
	T output;
	unsigned int sizeOfType = sizeof(T);
	size_t sizeOfInputData = s.size();
	if (sizeOfType != sizeOfInputData)
		throw std::exception("Incorrect input data!");
	memcpy(&output, s.data(), sizeof(T));
	return output;
}
komentarz 6 sierpnia 2015 przez Pan Kulomb Pasjonat (18,630 p.)
Na razie wystarczą typy atomowe. Problem jest w pozbyciu się ostream oraz istream
komentarz 8 sierpnia 2015 przez Bartek85 Mądrala (7,440 p.)
Proponowane rozwiązanie w edytowanej odpowiedzi.
komentarz 8 sierpnia 2015 przez Pan Kulomb Pasjonat (18,630 p.)
Dzięki!

read_word działa dopiero po zamianie funkcji na void i umieszczeniu T& w argumentach
komentarz 8 sierpnia 2015 przez Bartek85 Mądrala (7,440 p.)
Hm... to nie powinno mieć żadnego znaczenia. Moje rozwiązanie powinno działać na 99,9%. Jakiego kompilatora używasz? Rozumiem, że zmieniłeś prototyp funkcji na template void read_word(const std::string& s, T& output); Tak?
komentarz 8 sierpnia 2015 przez Pan Kulomb Pasjonat (18,630 p.)
tak, kompilator to gcc 4.7.? lub 4.8.?

Podobne pytania

0 głosów
1 odpowiedź 695 wizyt
pytanie zadane 19 marca 2016 w Systemy operacyjne, programy przez 0xf Dyskutant (8,180 p.)
0 głosów
1 odpowiedź 576 wizyt
pytanie zadane 1 kwietnia 2016 w Systemy operacyjne, programy przez bartolinciu Dyskutant (7,580 p.)
0 głosów
4 odpowiedzi 2,249 wizyt
pytanie zadane 31 lipca 2015 w C i C++ przez MaTT Początkujący (450 p.)

93,765 zapytań

142,721 odpowiedzi

323,372 komentarzy

63,359 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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...