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

question-closed Cpp strumień+buforowanie

Object Storage Arubacloud
+1 głos
262 wizyt
pytanie zadane 17 listopada 2015 w C i C++ przez niezalogowany
zamknięte 17 listopada 2015

Witam.

Potrzebuję pobierać dane z pliku przy pomocy strumienia.

Dane muszą być buforowane (nie mogę pobierać wszystkiego naraz)

Stworzyłem takie coś:

wxFile ppp;
	ppp.Open( wxT("pg/ppp.txt"), wxFile::read );
	
	while ( !ppp.Eof() )
		{
		char ppp1[2];
		ppp.Read( ppp1, 2 );
		wxMessageBox( ppp1 );
		}
	ppp.Close();

Jednak wxMessagebox wyświetla mi 3 znaki (pierwsze 2 są prawidłowe ostatni to zawsze litera "b")

Dlaczego tak się dzieje?

kolejna sprawa to: jeśli rozmiar pliku będzie np 103b a ja ustawię bufor na 10b.

!ppp.Eof()

Gdy pętla będzie na 100b pozostaną 3b czy nie załaduje mi kolejnych 7b jakiś smieci z RAMU ?

EDIT:

Tak wygląda komunikat messagemox'a a zawartość pliku ppp.txt:

ala ma kota
kot ma ale

ppp

komentarz zamknięcia: OT

3 odpowiedzi

0 głosów
odpowiedź 17 listopada 2015 przez furas Maniak (53,800 p.)
wybrane 17 listopada 2015
 
Najlepsza

Niektóre funkcje rozpoznają długość tekstu po znaku '\0' postawionym na końcu. Może zrób tablicę większą o jeden znak i wstaw na końcu '\0'.

---

Albo używaj wxString jeśli możesz.

---

Funkcja `Read` zwraca informację ile znakow udalo jej się wczytać 

int ilosc = ppp.Read( ppp1, 10);

http://docs.wxwidgets.org/trunk/classwx_file.html#a411aefd67cf2e33812a06380f973b850

komentarz 17 listopada 2015 przez niezalogowany
wxStringa nie mogę użyć, ponieważ mam otwarty strumień:

wxOutputStream *out = ftp.GetOutputStream("filename");

do out docelowo będą przesyłane pliki textowe i img

właśnie ze strumienia "wxFile ppp;"

całość misi być buforowana aby aplikacja się nie wieszała w przypadku przesyłania większego pliku.

EDIT:

Miałbyś może jakiś przykład wysyłania ze strumienia do strumienia z zastosowaniem buforowania ? nie musi być wxwidgets (jeśli oczywiście robiłeś kiedyś taki manewr)
komentarz 17 listopada 2015 przez niezalogowany
napisz jeszcze jak wstawić takie 0 binarne do tablicy ?
komentarz 17 listopada 2015 przez furas Maniak (53,800 p.)
edycja 17 listopada 2015 przez furas
char ppp1[11]; // z miejscem na zero

int ilosc = ppp.Read(ppp1, 10);

ppp1[ilosc] = '\0';
// lub
ppp1[ilosc] = 0;

wxMessageBox(ppp1);

inne_ppp.Write(ppp1, ilosc);

 

komentarz 17 listopada 2015 przez niezalogowany
ok wielkie dzięki zaczynam kumać :)

powiedz mi tylko czy do tablicy char mogę ładować np zbuforowany plik obrazu np *.png ?

a następnie wysyłać go buforowo ?

chodzi oczywiście o tablicę stworzoną w sposób jaki podałeś wyżej
komentarz 18 listopada 2015 przez niezalogowany
edycja 18 listopada 2015

Cała funkcja wysyłania na ftp z buforowaniem, wypada się podzielić rozwiązaniem z innymi.

Może się komuś kiedyś przydać.

Dzięki za pomoc.

//--- wysyłanie strony na FTP
void DlgSendFtp::jsz_sendftp(const wxString& pgname)
	{
	//--- zmienne cfg
	wxString ftp_host;
	wxString ftp_user;
	wxString ftp_pass;
	wxString ftp_dir;
	
	wxTextFile file;
	file.Open( wxT("ftp.cfg") );
	ftp_host = file.GetLine(0);
	ftp_user = file.GetLine(1);
	ftp_pass = file.GetLine(2);
	ftp_dir = file.GetLine(3);
	
	file.Close();
	
	wxFTP ftp;
	ftp.SetPassive( true );
	ftp.SetUser( ftp_user );
	ftp.SetPassword( ftp_pass );
	ftp.Connect( ftp_host );
	ftp.ChDir( ftp_dir );
	
	wxDir dir( "pg/"+pgname+"/" ); //--- katalog ze stronkami
	ftp.ChDir( pgname );
	
	wxString filename;
	bool cont = dir.GetFirst(&filename);
	while ( cont )
		{
		//--- wysyłanie pliku na serwer
		wxOutputStream *remote_file = ftp.GetOutputStream( filename );
		
		wxFile local_file;
		local_file.Open( wxT("pg/"+pgname+"/"+filename ), wxFile::read );
		
		int buf_size = 1024; //--- rozmiar bufora, maxymalny
		
		char buf[buf_size];
		int len; //--- rozmiar jaki udalo sie pobrac
		while ( !local_file.Eof() )
			{
			len = local_file.Read( buf, buf_size );
			remote_file->Write(buf, len);
			}
		local_file.Close();
		delete remote_file;
		//--- END wysylanie pliku na serwer
		
		cont = dir.GetNext(&filename);
		}
	ftp.Close();
	}

EDIT:

Wypada także wyjaśnić sprawę zera binarnego.

Tak jak koledzy napisali należy stosować 0 binarne gdy chcemy załadować tablicę do jakiegoś komponentu (ja bardzo często podglądam co jest w zmiennych przy pomocy messageboxa)

W takim przypadku należy zastosować /0.

Jeśli natomiast ładujemy tablicę do strumienia (a strumień to jakiś plik binarny) wtedy nie wolno stosować 0 binarnego oczywiście można wyliczyć ile charów z tablicy załadować do strumienia(można bardzo prosto się pomylić i zwalić cały strumień).

+1 głos
odpowiedź 17 listopada 2015 przez draghan VIP (106,230 p.)

Tak jak koledzy piszą, dziwne zachowanie wxMessageBox jest spowodowane brakiem zera kończącego napis.
Same dane są wczytywane poprawnie, szwankuje jedynie ich wypisywanie - wxMessageBox nie widzi zera kończącego, więc pisze znaki z pamięci dopóty, dopóki na nie nie trafi lub nie spowoduje segmentation fault.

Żeby dane były poprawnie wyświetlane, musisz zwiększyć bufor o jeden znak i wpisać tam ręcznie zero - a właściwe dane i tak zawsze wpisywać tylko w dwie pierwsze komórki tablicy. W ten sposób poprawny napis zostanie wyświetlony przez wxMessageBox.

    wxFile ppp;
    ppp.Open( wxT("ppp.txt"), wxFile::read );

    char ppp1[3];
    ppp1[2] = '\0';
    while ( !ppp.Eof() )
    {
        if(ppp.Read( ppp1, 2 ) == 1) ppp1[1] = '\0';
        wxMessageBox(ppp1);
    }
    ppp.Close();

A powiedz mi, co dokładnie chcesz zrobić, może (jutro, bo dziś muszę już spadać) pomogę? :)

0 głosów
odpowiedź 17 listopada 2015 przez hit02 Nałogowiec (33,970 p.)
Moim zdaniem powinieneś dodać jeszcze zero binarne (\0) na końcu stringa.

Litera "b" i  zero za nią moim zdaniem jest tylko "śmieciem" z pamięci.

Co do drugiego pytania, to ta funkcja nie zapisze kolejnych 7 bajtów, więc najpewniej pozostanie tam poprzedni string. Funkcja zwraca ci ilość wczytanych bajtów, więc dzięki temu możesz wstawić \0 w odpowiednim miejscu.
komentarz 17 listopada 2015 przez niezalogowany
Nie za bardzo mogę mieszać w buforze, bo to będzie przesyłanie ze strumienia do strumienia.

EDIT: Wysyłane będą pliki textowe i img
komentarz 17 listopada 2015 przez furas Maniak (53,800 p.)
To co powiedział hit02 - dostajesz inforamcję, że wczytało 7 bajtów i wstawiasz '\0' w odpowiednie miejsce aby dało się wypisać w MessageBox. A jak będziesz bufor musiał wysłać gdzieś dalej to też musisz wysłać tylko 7 bajtów a nie 10 bo  byś wysłał ze śmieciami - dlatego wstawienie tam '\0' też nie przeszkodzi.

Potrzebujesz zmiennej do przechowywania informacji ile danych jest aktualnie w buforze.

Podobne pytania

+1 głos
1 odpowiedź 159 wizyt
0 głosów
1 odpowiedź 307 wizyt
pytanie zadane 17 października 2020 w Java przez amtrax Dyskutant (9,630 p.)
+1 głos
2 odpowiedzi 135 wizyt

92,654 zapytań

141,543 odpowiedzi

319,952 komentarzy

62,022 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!

...