Odczyt danych z tablicy BYTE-ów

Odpowiedz Nowy wątek
2014-12-14 17:39
MichalSx
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.

Pozostało 580 znaków

2014-12-14 19:38
1
BYTE tab[123];
 
// załóżmy że jest wartość double na offsecie 40
 
double d = *((double*)&tab[40]);

Pozostało 580 znaków

2014-12-14 19:45
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.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-12-14 19:53
0

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

@Endrju, nie tak dawno podawał fragment dokumentacji na ten temat, może jeszcze raz się wypowie. - _13th_Dragon 2014-12-14 19:58
char jest wyjęte spod "strict aliasing". - Azarien 2014-12-14 21:01
ale double - nie - _13th_Dragon 2014-12-14 21:02
No oczywiście, że to jest UB. Łamie strict aliasing. T * -> char * można. W drugą stronę nie. To jest to "w drugą stronę". (3.10.10) - Endrju 2014-12-14 21:02

Pozostało 580 znaków

2014-12-14 20:06
Zimny Terrorysta
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)](http://4programmers.net/Forum/1091980):
> 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?

Pozostało 580 znaków

2014-12-14 20:27
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.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2014-12-14 21:02
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?

Pozostało 580 znaków

2014-12-14 21:04
MichalSx
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.

Pozostało 580 znaków

2014-12-14 21:06
MichalSx
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).

Pozostało 580 znaków

2014-12-14 21:26
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?

edytowany 2x, ostatnio: ly000, 2014-12-14 21:28

Pozostało 580 znaków

2014-12-14 21:33
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

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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