Odczyt danych z tablicy BYTE-ów

0

Witam,
Mam plik tekstowy, z którego wydobywam dane przy pomocy bufora. Dane są typu BYTE. Mam pytanie jak sprawnie wydobywać te zmienne (int, double etc.), które są rozdzielone różnymi separatorami? Jak w ogóle wydobywać takie dane?
Z góry dziękuję za naprowadzenie.

1
BYTE tab[123];

// załóżmy że jest wartość double na offsecie 40

double d = *((double*)&tab[40]);
0

To co podał @Azarien wyżej to rozwiązanie które zadziała pod każdym znanym mi kompilatorem ale jednak jest zadeklarowane jako UB (osobiście nie mam oporów z użyciem takiego rodzaju UB).
Może stwórz pewna strukturę i wczytuj bezpośrednio do struktury.

0

to nie jest UB. co najwyżej "implementation dependent", ale wiemy jakie to jest "implementation" i nie ma prawa nie działać.

0
Azarien napisał(a):
BYTE tab[123];

// załóżmy że jest wartość double na offsecie 40

double d = *((double*)&tab[40]);

Huhu, mocne! ;-) Dziękuję bardzo! Zaraz wypróbuję.

_13th_Dragon napisał(a):

Może stwórz pewna strukturę i wczytuj bezpośrednio do struktury.

A mógłbyś jeszcze napisać przykład takiego rozwiązania? Bo nie za bardzo wiem o czym piszesz :/.

Mam jeszcze jedno pytanie: Czasami muszę wiedzieć gdzie jest koniec wiersza (znak '\n') - ale co jeśli plik byłby zapisany w UNICODE? Bo jeśli jest w ANSI to takie znak jest zapisany na 1 BYTE i mogę sobie porównać byte[i] == '\n' a czy jest jakiś odpowiednik na porównanie w UNICODE?

0

Dokładnie tak jak pobierasz zawartość tej tablicy tab dokładnie tak samo pobieraj zawartość struktury.
Ponieważ różnych sposobów pobrania istnieje nieskończenie wiele to prawdopodobieństwo że mój przykład ci pomoże równy 1/nieskończoność - czyli zero.
Podaj jak pobierasz - pokaże jak przerobić.
Jeżeli zapisujesz double binarne to nie możesz polegać na wierszach, ponieważ bajt o wartości 13 może być jednym z osmu bajtów tegoż double.
Musisz zmienić podejście, przed każdą "zmienną" porcją danych zapisz/odczytaj jej rozmiar.

0

<quote>Mam jeszcze jedno pytanie: Czasami muszę wiedzieć gdzie jest koniec wiersza (znak '\n') - ale co jeśli plik byłby zapisany w UNICODE? Bo jeśli jest w ANSI to takie znak jest zapisany na 1 BYTE i mogę sobie porównać byte[i] == '\n' a czy jest jakiś odpowiednik na porównanie w UNICODE?</QUOTE>

No zaraz. To mówimy o pliku binarnym czy tekstowym? Dlaczego w pliku binarnym miałbyś interesować się końcem wiersza?

0
_13th_Dragon napisał(a):

Podaj jak pobierasz - pokaże jak przerobić.

Obecnie testuję windowsowską funkcję CreateFile tj. coś w stylu:

	wstring file_name = L"check.csv";
	HANDLE hFile = CreateFile(file_name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);

	if(hFile == INVALID_HANDLE_VALUE)
		{
		cout << "brak dostępu do pliku!!!" << endl;
		getchar();
		return 0;
		}

	const unsigned buff_size = 100;
	BYTE buff[buff_size];
	DWORD dwNumBytes;

	ReadFile(hFile, buff, buff_size, &dwNumBytes, NULL);

Rozważałem również funkcję read z ifstream (nie wiem co lepsze/wygodniejsze).

Ogólnie to problem jest taki, że mam plik z dużą ilością danych a pierwszy wiersz jest opisem kolumn więc muszę go najpierw wywalić.
Druga rzecz to najpierw muszę sprawdzić ile w ogóle jest tych danych - więc muszę ściągnąć wszystkie dane i zliczyć wszystkich znaków '\n'.
Kolejna rzecz to utworzenie odpowiedniej wielkości bufora - by jakaś struktura nie dostała części danych - chociaż to raczej nie powinno być problemem, bo wystarczy zrobić wielkość buffora jako: sizeof()*N(?)

_13th_Dragon napisał(a):

Jeżeli zapisujesz double binarne to nie możesz polegać na wierszach, ponieważ bajt o wartości 13 może być jednym z osmu bajtów tegoż double.

Tyle, że ja nie zapisuję nic binarnie. Plik mam tekstowy :/. W dodatku są różne separatory (śmieci), ale to chyba nie problem.

_13th_Dragon napisał(a):

Musisz zmienić podejście, przed każdą "zmienną" porcją danych zapisz/odczytaj jej rozmiar.

Nie jestem pewny czy dobrze rozumie. Na szczęście dane (poza pierwszym wierszem) powinny być równe - tzn. ilość zapisanych zmiennych, oddzielonych separatorami, powinna być taka sama.

0

<quote="1092003">

Mam jeszcze jedno pytanie: Czasami muszę wiedzieć gdzie jest koniec wiersza (znak '\n') - ale co jeśli plik byłby zapisany w UNICODE? Bo jeśli jest w ANSI to takie znak jest zapisany na 1 BYTE i mogę sobie porównać byte[i] == '\n' a czy jest jakiś odpowiednik na porównanie w UNICODE?</QUOTE>

No zaraz. To mówimy o pliku binarnym czy tekstowym? Dlaczego w pliku binarnym miałbyś interesować się końcem wiersza?

No właśnie tu jest problem. Bo mówimy o pliku tekstowym, który odczytuję z użyciem bufora (windowsowską funkcją CreateFile). I ona kopiuje plik do tablicy typu BYTE (tak przynajmniej mam w książce).

0

Czyli te wartości są zapisane tekstowo, a nie binarnie? W takim razie sposoby podane powyżej tego nie dotyczą.
Skorzystaj z tego: http://www.cplusplus.com/reference/cstdio/sscanf/ lub z tego: http://www.cplusplus.com/reference/sstream/stringstream/

MichalSx napisał(a):

Rozważałem również funkcję read z ifstream (nie wiem co lepsze/wygodniejsze).

Na serio nie widzisz co jest wygodniejsze?

0

Możesz podać przykład takiego pliku?
Bo z tego co powiedziałeś na 75% @ly000 ma racje, potrzebujesz przekazać fragment wiersza do jednego z:

  1. atof
  2. strtod
  3. sscanf
  4. istringstream
0
_13th_Dragon napisał(a):

Możesz podać przykład takiego pliku?
Bo z tego co powiedziałeś na 75% @ly000 ma racje, potrzebujesz przekazać fragment wiersza do jednego z:

  1. atof
  2. strtod
  3. sscanf
  4. istringstream

@_13th_Dragon a orientujesz się co jest najszybsze z wymienionych przez Ciebie metod?

0

Zależy od implementacji.

0

Ale w jakim sensie? Bo jak mam funkcję np. strtod to chyba ciężko ją jakoś inaczej użyć niż wrzucając do niej tablicę znaków.
Jedyne miejsce, gdzie dostrzegam możliwość różnego zaimplementowania to istringstream, gdzie mogę przekazywać krótszy lub dłuższy bufor - czy o tym piszesz?

0

Nie, piszę o różnych kompilatorach i różnych środowiskach.
36 min - czekałeś na odpowiedź, zaś napisanie testu który sprawdzi to dla twego kompilatora może zając max 5 min.
Ja nie rozumiem tej manii marnowania swego i cudzego czasu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1