2016-01-05 11 views
8

Czytam plik tekstowy ASCII. Jest on określony przez rozmiar każdego pola, w bajtach. Na przykład. Każdy wiersz składa się z 10 bajtów dla jakiegoś ciągu, 8 bajtów dla wartości zmiennoprzecinkowej, 5 bajtów dla liczby całkowitej i tak dalej.C++ uzyskać rozmiar (w bajtach) EOL

Mój problem polega na czytaniu znaku nowej linii, który ma zmienną wielkość w zależności od systemu operacyjnego (zwykle 2 bajty dla okien i 1 bajta dla systemu Linux, jak sądzę).

Jak mogę uzyskać rozmiar znaku EOL w C++?

Na przykład w Pythonie mogę zrobić:

len(os.linesep) 
+4

Jeśli otwierasz plik w trybie tekstowym, znaki nowej linii zawsze powinny być po prostu "\ n" ", niezależnie od zakończenia linii natywnej. Czy naprawdę potrzebujesz znać natywny ciąg EOL? – Badministrator

+0

Czy zagwarantowano, że plik został zapisany w tym samym systemie operacyjnym, w którym znajduje się twój kod, na którym się czyta? Jeśli tak, po prostu otwórz plik w trybie tekstowym (nie binarnym). – dxiv

Odpowiedz

0

nie jestem pewien, że tłumaczenie ma miejsce, gdy myślisz, że jest. Spójrz na poniższy kod:

ostringstream buf; 
buf<< std::endl; 
string s = buf.str(); 
int i = strlen(s.c_str()); 

Po tym uruchomieniu w systemie Windows, i == 1. Zatem definicja końca końca w standardzie to 1 znak. Jak skomentowali inni, jest to znak "\ n".

+0

Ten kod jest nieprawidłowy, ponieważ biblioteka CRT lib nie zamienia '\ n' na' \ r \ n' dla buforów w pamięci, ale robi to dla plików i konsoli. –

+0

Tutaj demonstrujesz problem, z którym mam do czynienia. C++ konwertuje "\ n" na znak specyficzny dla os podczas zapisu do pliku/konsoli, ale nie do bufora. – jramm

+0

@jramm Nie sądzę, żebyś wyjaśnił swój problem wystarczająco dobrze. '\ n' nie musi (i tak naprawdę nie może) być zakodowane, gdy jest zapisane w buforze. Ale kiedy piszemy ten bufor do pliku otwieranego w trybie * text *, '' '' '' '' '' '' '' '' '' '' 'n" będzie automatycznie tłumaczone na dowolną platformę. Następnie, jeśli otworzysz ten sam plik w trybie _text_ i go odtworzysz, sekwencja nowej linii zostanie ponownie przetłumaczona na '\ n'. Tak więc przynajmniej dla mnie nie jest jasne, dlaczego musisz znać kodowanie '\ n' w pliku na dysku. – dxiv

1

Zaszczytnym sposobem jest odczytanie linii.

Teraz ostatni znak powinien być \n. Rozbierz to. Następnie spójrz na poprzednią postać. Będzie to albo \r albo coś jeszcze. Jeśli jest to \r, usuń go.

Dla plików tekstowych Windows [ascii], nie ma żadnych innych możliwości.

Działa to, nawet jeśli plik jest mieszany (np. Niektóre linie to \r\n, a niektóre to tylko \n).

Możesz wstępnie to zrobić w kilku liniach, aby upewnić się, że nie masz do czynienia z czymś dziwnym.

Po tym, wiesz już, czego się spodziewać w przypadku większości plików. Ale metoda ta jest ogólnie niezawodna. W systemie Windows można zaimportować plik z systemu Unix (lub odwrotnie).

+0

Połowa nitpick, ale trudno jest "odczytać linię", nie wiedząc wcześniej, co oznacza terminator linii. Na przykład Twój przepis nie działa dla terminatorów '\ r', a także dla kolejnych pustych linii zapisanych jako' \ r \ n \ n \ n', które zostały zaobserwowane w Windows-land. – dxiv

+1

@dxiv Metoda działa przeciwko '\ r \ n \ n \ n' (np.' \ R \ n \ n \ n') - to po prostu tryb mieszany, jak już wspomniałem [z rzędu nie występuje problem]. Nie widziałem tylko pliku '\ r' w ciągu ponad 20 lat [jeśli kiedykolwiek, i przekonwertowałem pliki z tysiącami plików].Nieczytelne przez wiele programów, ponieważ teraz przyjmują [przynajmniej] nową linię. Wypróbuj DOS 'type file' na jednym ;-) Myślę, że nawet MS nie obsługuje ich więcej. "\ r" jest prawidłowe [jako nieterminator] przy rozpoczęciu_ linii (np. przechwycone wyjście postępu). Widziałem o wiele więcej (np. '\ Rpgm ma 56% ukończone \ rpgm zostało zrobione 57 %') –

+0

@CraigEstey - Old school Mac to tylko \ r. Zobacz wikipedia: https://en.wikipedia.org/wiki/Newline – user3690202

Powiązane problemy