[C++] Specjalne znaki char jako oddzielacze nazw w plikach

Witam!

Mam pewien problem z plikami. Zapisuję do nich różne nazwy i potem chciałbym je wczytać do stringów - ale nie tak hurtowo tylko: 1 nazwa w pliku - 1 miejsce w wektorze. Nie wiem tylko jak pooddzielać te nazwy w plikach, żeby można było zrobić coś takiego:

for(...)

A eskejpować tego znaku zwyczajnie nie możesz?

Co to znaczy escapować znak :?: Że jak ktoś wprowadzi taki znak do nazwy, to zostanie on zamieniony np. na ‘\t’ :?:

Jeśli plik nie musi być odczytywalny przez człowieka to może jako separator użyć ‘\0’?

Z klawiatury da się wklepać każdy znak.

Więc jeżeli chcesz odczytywać za pomocą getline() to nie ma innego sposobu niż eskejpowanie jak to nazwał Wasacz - polegające na poprzedzeniu jakiegoś znaku jakimś innym. Tak jak cudzysłów w napisach w języku C eskejpującym znakiem jest znak ‘’.

Zastanów się nad innym sposobem zapisu/odczytu.

najpierw binarny zapis liczby int - długość napisu a potem właśnie taka ilość znaków stanowiących napis.

Czyli tego znaku już się nie da napisać na klawiaturze, i to co podał nr47 , jest dobrym rozwiązaniem, tak :?: (Zresztą moje z ‘\a’ i ‘\f’ chyba też)… :?:

I jak to potem do stringu wklepię :?: Będę musiał rezerwować tablice char, bo funkcje ostream::get, ostream::getline, nie mogą zapisywać do stringów tylko do nich właśnie (lub jakichś innych, ale one są tutaj nieistotne teraz). I potem z tych tablic wszystko kopiować.

W skrócie coś w tym rodzaju:

void zapisz(ostream &s,char *buf)

Zrobiłem to wg Twojego pomysłu [alex], ale nieco inaczej - nie mogłem postawić liczb w tym pliku samym co dane bo czasem te wszystkie dane trzeba wyświetlić użytkownikowi, a on nie potrzebuje widzieć tam jakichś liczb. Zapisałem liczby do innego pliku. Potem w danej funkcji te liczby odczytałem do zmiennych i teraz robię coś takiego (w pliku dane są pooddzielane ‘\0’):

for(short int i = 0 ; i < zmienna ; i++)

To po chińskiego ci w takim przypadku tamten drugi plik?

1 funkcja - odczytuje plik znak po znaku.

2 funkcja - odczytuje pierwsze plik z liczbami, liczby lądują jako argument w konstruktorze/funkcji składowej resize wektora, potem z pliku z tekstami wczytuje wartości do wektorów, w pętli jak w moim poprzednim poście. Chodzi o to, że ta funkcja musi wyświetlić potem te wektory i przy każdym postawić numer: 1, 2, 3 itd. - użytkownik musi wybrać jeden.

Nie potrzebujesz tych liczb, vector ma metodę push_back()

Owszem nieco szybciej wychodzi jeżeli od razu podasz rozmiar wektora a potem wypełniasz danymi, z tym że jak musisz odczytać plik aby ten rozmiar pobrać natychmiast tracisz cały zysk a nawet o wiele więcej niż zyskasz na podaniu rozmiaru od razu.

Nie wspominam już o tym że jak użytkownik zmieni plik tekstowy pozostawiając plik z liczbami bez zmian, dopiero będzie kaszana w programie.

Resize wektora to tylko jeden przykład. Muszę mieć liczbę danych danego typu bo użytkownik musi podać numer o jaki mu chodzi.

Wiem, ale nie widziałem jeszcze takiego programu, co jak mu się posuwa pliki, albo pomiesza się w nich to sam się odbuduje :slight_smile: Za modyfikację pliku człowiek zabiera się wtedy, kiedy wie jak dany program działa - przynajmniej ja tak myślę.

Tak ci się tylko wydaje. Jak zobaczy że w notepadzie nie widać krzaczków to natychmiast rwie się modyfikować. I nawet nie licz że zajrzy do instrukcji obsługi.

Być może, ale jak już pisałem ja muszę mieć liczbę gdzieś indziej, żeby użytkownik jej nie widział. Mogę przy odczytywaniu pliku, w trybie “bez liczb” usunąć te liczby, ale może pobawię się w to później. A zresztą: przecież nawet jakby liczby były w tym samym pliku co i teksty to i tak ktoś może dopisać tekst bez zmiany liczby…

Dobra a teraz właściwa treść postu:

Mam problem z ze znakiem ‘\0’ (i tym podobnymi, poprzedzanymi ukośnikiem). W jednej funkcji zapisuję dane do pliku:

sStrWyjsc << "\t" << tytul << "\n\n" << "\tDni tygodnia: \0";

Czy masz plik otwarty w trybie binarnym?

Nie, ale z tego co pamiętam, to pliki otworzone w ios::binary dotyczą tylko ‘\n’ i ‘\r’…

Dotyczy również “\0”.

Zresztą jak chcesz zapisywać ten znak (’\0’) to nie radzę korzystać z operatora przesunięcia.

Nie opisano tego w standardzie więc każdy kompilator robi “jak chce”.

Spróbuj zapisać:

plik<<"Ala\0ma\0kota"; [/code]

Program po niektórych kompilatorach zapisze do pliku tylko Ala.

Aha to wybiorę inny znak, np. ‘\b’, tylko wtedy np. Visual wyświetla ostrzeżenie, że jest to nierozpoznany escapowany znak, ale to chyba nic ważnego :?:

EDIT:

No i dalej tak samo - zarówno w ios::binary jak i bez…

EDIT2:

Zgodny ze standardem kompilator jak zapisze takie pliki escapowane do pliku :?: Jako spację :?: Bo ‘\0’ Visual wcale nie zapisuje - tzn. nie można nigdzie zobaczyć, gdzie on w pliku jest…

Aby zobaczyć takie znaki musisz przeglądać plik binarnie.

To wcześniej to była moja wina - pracowałem ze strumieniem z flagą błędu failbit :smiley:

[alex - wielkie dzięki za pomoc. Otworzyłem plik binarnie i każdy ‘\0’ dla pewności zapisuję put’em - wszystko pięknie działa. Jeszcze raz thx :slight_smile:

Szkoda, że w książkach tak szczegółowo tego openmode binarnego nie opisują…