C problem - čitanje iz datoteke

poruka: 16
|
čitano: 2.258
|
moderatori: XXX-Man, vincimus
1
+/- sve poruke
ravni prikaz
starije poruke gore
12 godina
neaktivan
offline
C problem - čitanje iz datoteke

Poz svima.

Imam jedan problem sa jednim programčićem iz C-a. Inače radim u Javi, i nisam baš upoznat sa C-om.

Ovo je source funkcije koja mi "šteka":

int new_cmd(wchar_t *fname) {
    int argc,retc;
    wchar_t outfile[MAX_PATH];
    wchar_t cmd[MAX_PATH];
    wchar_t infile[MAX_PATH];
    FILE *h;
    TCHAR buff[1024];
    memset(buff,0,sizeof(buff));

    // pocetak
    wprintf(L"$IHIS2CMD> START\n");
    // otvori
    h = _wfopen(fname,L"rt");
    if(h == NULL) {
        wprintf(L"$IHIS2CMD> ERROR reading [%s]\n",fname);
        wprintf(L"$IHIS2CMD> END\n");
        return(1); //*!!! (0)
    }
    outfile[0] = '\0';
    cmd[0] = '\0';
    infile[0] = '\0';
   argc = fwscanf(h,L"%s %s %s",outfile,cmd,infile);
    fclose(h);
    if(argc < 2) {
        wprintf(L"$IHIS2CMD> WARN unable to read file [%s].\n", fname);
        return(1);
    }

    // procitali smo parametre idemo dalje
    wprintf(L"$IHIS2CMD> EXEC [%s, %s, %s] (%d) ...\n", outfile,cmd,infile,argc);
    retc = appCmd(outfile, cmd, infile);
    wprintf(L"$IHIS2CMD> RETURN [%s]\n", (retc == EXIT_SUCCESS ? L"OK" : L"ERR"));

    // kraj
    if(!DeleteFile(fname)) {
        wprintf(L"$IHIS2CMD> ERROR deleting [%s]\n",fname);
        wprintf(L"$IHIS2CMD> END\n");
        return(1); //*!!! (0)
    }
    wprintf(L"$IHIS2CMD> END\n");
    return(1);
}
Obratite pozornost na boldani redak gdje se koristi funkcija fwscanf. Pročitao sam dokumentaciju te funkcije i piše da čita iz nekog streama u neke varijable prema zadanom formatu.

Problem je u tome da to ne radi na Windows 7 mašinama (na nekim radi, na nekima ne). U file-u iz kojeg se čitaju ti parametri (outfile, cmd, infile) uredno stoje navedeni stringovi koji se trebaju pročitati. Ono što on pročita(dakle na mašinama na kojima to NE radi), output iz command prompta:

$IHIS2CMD> START
$IHIS2CMD> EXEC [ ■C, , ] (3) ...
A ono što piše u datoteci je:

C:\Temp\rez.txt GETDATA c:\temp\123456.xml

Dakle ova 3 stringa bi trebala pisati gore u onoj zagradi ( EXEC[ , , ] ), a on ih pročita krivo, kao da čita u krivom enkodingu...

 

Ima li netko ideju u čemu je problem?

Moj PC  
0 0 hvala 0
17 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke

Probaj napisati:

argc = fwscanf(h,L"%ls %ls %ls",outfile,cmd,infile);

umjesto obicnih stringova.

 

Uz to, koji je koding datoteke?

Perhaps today IS a good day to die. PREPARE FOR RAMMING SPEED!
12 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke

Datoteku stvara taj isti program (to je kao neki nacin komunikacije preko datoteke kad se program vrti u SERVER mode-u), evo funkcije:

int appCall(wchar_t *serverdir,wchar_t *outfile,wchar_t *cmd, wchar_t *infile) {
    wchar_t srvfile[MAX_PATH];
    FILE *f;
    struct _stat fileStat;

    wprintf(L"$IHIS2CMD> CALL [%s, %s, %s] ...\n", outfile,cmd,infile);
    // upisi poziv
   wsprintf(srvfile,L"%s\\%s",serverdir,L"0001.ih2"); //fali kastanje zadnja 2 parametra u (LPSTR)
    f = _wfopen(srvfile,L"wt,ccs=UNICODE");
    if(f == NULL) {
        wprintf(L"Unable to open cmd file [%s]\n", srvfile);
        return(999);
    }
    fwprintf(f,L"%s %s %s\n", outfile, cmd, infile);
    fclose(f);

    // cekaj da nestane cmd dat
    while(!_wstat(srvfile,&fileStat)) { // dok god file postoji = 0
        Sleep(1000);
    }

    // kraj
    return(EXIT_SUCCESS);
}
U komentaru tog boldanog reda sam napisao da fali kast parametara u pozivu funkcije wsprintf, ali opet, to nebi trebalo imat veze, pošto ta funkcija određuje putanju do datoteke.

Red ispod boldanog reda je onaj u kojem se definira encoding.

Ajmo ljudi, savjeti, ideje? :)

12 godina
neaktivan
offline
C problem - čitanje iz datoteke

Da li trebam buildati u 64bitnu verziju za 64bitne platforme ili moze raditi i 32bitni exe na 64bitnoj platformi. Isto tako imam jedan dll za komunikaciju sa citacem kartica i neznam da li bi mi trebala njegova 64 bitna verzija?

Poruka je uređivana zadnji put pet 30.8.2013 13:08 (vasso123).
Moj PC  
0 0 hvala 0
17 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke

Onda je problem u kodiranju. Usput receno, takvo postavljanje unicodea nije prenosivo, radit ce samo na Windowsima.

Probaj koristiti neki vanjski library, recimo ICU za hendlanje unicode datoteka.

 

Nije nuzno potrebno, jedino sto u tom slucaju ne mozes koristiti sve sto ti 64-bita nudi.

Perhaps today IS a good day to die. PREPARE FOR RAMMING SPEED!
15 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
vasso123 kaže...
Problem je u tome da to ne radi na Windows 7 mašinama (na nekim radi, na nekima ne). U file-u iz kojeg se čitaju ti parametri (outfile, cmd, infile) uredno stoje navedeni stringovi koji se trebaju pročitati. Ono što on pročita(dakle na mašinama na kojima to NE radi), output iz command prompta:

$IHIS2CMD> START
$IHIS2CMD> EXEC [ ■C, , ] (3) ...
A ono što piše u datoteci je:

C:\Temp\rez.txt GETDATA c:\temp\123456.xml

Dakle ova 3 stringa bi trebala pisati gore u onoj zagradi ( EXEC[ , , ] ), a on ih pročita krivo, kao da čita u krivom enkodingu...

 

Ima li netko ideju u čemu je problem?

Byte Order Mark. To su prva dva znaka koja ti fwscanf pročita i zapne na njima. Pošto ti je datoteka vrlo vjerojatno UTF-16LE kodirana, ovako napravi:

 

Pri čitanju otvori datoteku u binarnom modu:

fh = _wfopen(fname, L"rb");

 

Zatim preskoči BOM:

fseek(fh, 2, SEEK_CUR);

 

I onda čitaj dalje normalno:

argc = fwscanf(fh, L"%s %s %s", outfile, cmd, infile);

 

_wfopen iz VS2005 CRT bi trebao detektirati i preskočiti BOM, problem je samo što ja koristim MinGW pa nemam pojma koja točno  funkcija se zapravo i linka u datoteku, ali ono što znam je da mi zapinje (u tekstualnom modu, bez ručnog preskakanja BOM-a), baš kao i tebi.

 

Food for thoughts:

http://stackoverflow.com/questions/5205252/reading-and-parsing-simple-unicode-text-files-in-visual-c

http://www.i18nguy.com/unicode/c-unicode.html

 

Evo i testne datoteke ako se netko želi igrati:

http://www.mediafire.com/download/a93b6n97098dmdo/fwtest.txt

What Andy giveth, Bill taketh away.
Poruka je uređivana zadnji put ned 1.9.2013 4:29 (rustweaver).
12 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
rustweaver kaže...

Zatim preskoči BOM:

fseek(fh, 2, SEEK_CUR);

Ovaj SEEK_CUR ne trebam nigdje definirati?

17 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
vasso123 kaže...

Ovaj SEEK_CUR ne trebam nigdje definirati?

http://www.cplusplus.com/reference/cstdio/fseek/

 

Position used as reference for the offset. It is specified by one of the following constants defined in<cstdio> exclusively to be used as arguments for this function:
SEEK_CUR - Current position of the file pointer

 

S tim da je kod tebe u pitanju <stdio.h> posto radis u C-u, a ne C++-u.

Perhaps today IS a good day to die. PREPARE FOR RAMMING SPEED!
12 godina
neaktivan
offline
C problem - čitanje iz datoteke

Hvala decki sad mi ispravno cita :)

 

Medjutim sad imam drugi problem. Radim u NetBeansima sa Cygwinom, pokusavam i sa MinGW-om.

Kad buildam sa Cygwinom, javlja mi ovo:

ihis2.h:34:19: fatal error: tchar.h: No such file or directory

i prekine se daljnja kompajlacija.

 

Sa MinGW-om mi se uspjesno kompajlira exe, ali kad pokrenem exe, i kad treba doci do komunikacije sa citacom kartica program se srusi. Nije mi jasno zasto? Kao da nije ispravno linkan dll?

Moj PC  
0 0 hvala 0
17 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
vasso123 kaže...

Hvala decki sad mi ispravno cita :)

 

Medjutim sad imam drugi problem. Radim u NetBeansima sa Cygwinom, pokusavam i sa MinGW-om.

Kad buildam sa Cygwinom, javlja mi ovo:

ihis2.h:34:19: fatal error: tchar.h: No such file or directory

i prekine se daljnja kompajlacija.

 

Sa MinGW-om mi se uspjesno kompajlira exe, ali kad pokrenem exe, i kad treba doci do komunikacije sa citacom kartica program se srusi. Nije mi jasno zasto? Kao da nije ispravno linkan dll?

Kako to mislis "buildas sa Cygwinom"? Cygwin nije kompajler, to je compatibility layer za Windowse koji omogucava koristenje Unix-like okruzenja na istima.

Vjerojatno u tom slucaju buildas s gcc-om.

tchar.h je header specifican samo za Windowse i samo na njima se koristi, Unix - ne.

http://stackoverflow.com/questions/4168748/tchar-h-not-found-on-cygwin?rq=1

 

Jesi li uopce debugirao program? xD

Perhaps today IS a good day to die. PREPARE FOR RAMMING SPEED!
Poruka je uređivana zadnji put pet 30.8.2013 17:18 (1domagoj1).
15 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
vasso123 kaže...
Sa MinGW-om mi se uspjesno kompajlira exe, ali kad pokrenem exe, i kad treba doci do komunikacije sa citacom kartica program se srusi. Nije mi jasno zasto? Kao da nije ispravno linkan dll?

Ruši ti se jer si gotovo sigurno pozvao neku funkciju iz traženog dll-a sa neispravnim argumentima. Pokreni program u debuggeru, ne moraš ni postaviti breakpointe GDB će ti automatski reći na kojoj se liniji koda program srušio. Kada nađeš koja je to linija dobro sve provjeri jer negdje nešto pogrešno radiš. Pročitaj dokumentaciju za funkciju na kojoj ti se ruši kako ne bi bilo nejasnoća.

 

Greška je gotovo sigurno dobar stari invalid page fault :D Imaj na umu da je to C a ne Java, znači da sve moraš lijepo provjeriti i sâm temeljito obaviti error handling, jer C neće ništa za tebe sâm napraviti. Nadam se da znaš koristiti debugger.

What Andy giveth, Bill taketh away.
Poruka je uređivana zadnji put pet 30.8.2013 17:42 (rustweaver).
15 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
1domagoj1 kaže...

Kako to mislis "buildas sa Cygwinom"? Cygwin nije kompajler, to je compatibility layer za Windowse koji omogucava koristenje Unix-like okruzenja na istima.

Vjerojatno u tom slucaju buildas s gcc-om.

Pa no, na to i misli. Cygwin ima svoj vlastiti port GCC-a koji se u nekim detaljima razlikuje od MinGW GCC-a (prateće biblioteke 'n' stuff).

 

Pitanje koje sada tu mene zanima je zašto Cygwin? Rušenje može biti prouzročeno i nekompatibilnošću među bibliotekama. Ako biblioteka koju koristi za komunikaciju sa čitačem kartica ovisi o nekoj specifičnosti cygwina onda je to odgovor na pitanje zašto se program kompajliran MinGW-om ruši.

What Andy giveth, Bill taketh away.
12 godina
neaktivan
offline
C problem - čitanje iz datoteke

Dakle, kao sto sam rekao sa Cygwinom mi se nece kompajlirat zbog tog windows headera. Kako je ovaj programer koji je napisao taj program, kompajlirao sa cygwinom, nije mi jasno.

Sa mingw-om medjutim, mi se rusi ostatak programa. Komunikacija sa citacem definitivno radi, dakle nije do dll-a. Recimo vidim da mi se rusi zbog koristenja neke funkcije za usporedjivanje  stringova, zamjenim je sa nekom drugom, i onda mi se program srusi negdje malo dalje. Nisam debugirao program jer citac nije na mom kompu.

Javim vam sutra eventualni napredak, hvala puno na pomoci :)

Moj PC  
0 0 hvala 0
12 godina
neaktivan
offline
C problem - čitanje iz datoteke

@rustweaver

Mi mozes objasnit zasto se datoteka spremi, kako ti kazes u UTF-16LE encodingu na Win7. Tj. zasto se taj problem ne pojavljuje na Win XP-u?

Moj PC  
0 0 hvala 0
15 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
vasso123 kaže...

@rustweaver

Mi mozes objasnit zasto se datoteka spremi, kako ti kazes u UTF-16LE encodingu na Win7. Tj. zasto se taj problem ne pojavljuje na Win XP-u?

Evo upravo sam testirao svašta, ovo je par zapažanja

(WinXP i MinGW kompajler dvije različite verzije 3.4.2 i 4.6.1)

 

1. Na samom početku prije includeanja bilo kojeg headera treba definirati makro UNICODE (ako to ne napraviš budeš dobio ANSI verzije nekih funkcija a to ne želiš):

#define UNICODE

 

2. između fopen i _wfopen nema nikakve razlike osim što _wfopen za argumente prima wide stringove (pa možeš otvarati datoteke sa egzotičnim imenima).

 

3. css=UNICODE i ostali specifikatori encodinga nemaju baš nikakvog utjecaja, fopen i _wfopen potpuno ignoriraju to

 

4. isto tako fwprintf iz nekog razloga ispravne wide stringove pretvara u ANSI stringove, to sam provjerio i sa string literalima i sa ispisivanjem wchar_t polja. U oba slučaja izvorni string ima željeni encoding (UTF-16LE) a fwprintf ga u ispisu pretvara u ANSI string, wsprintf funkcija nema taj problem i kada sam napravio ovo:

 

wchar_t text[512] = {0};
wsprintf(text, L"%s %s %s", L"C:\\Temp\\rez.txt", L"GETDATA", L"c:\\temp\\123456.xml");
fwrite(text, 1, sizeof(t), fh);

 

Dobio sam točno ono što sam i htio, wsprintf je formatirani UTF-16 tekst spremio u polje 'text', a fwrite je potom u datoteku ispisao sirovi sadržaj tog polja bez ikakvih konverzija. Rezultat: u datoteci se našao UTF-16 kodiran tekst. Nedostatak je što se time ne ispisuje byte order mark (koji označava je li riječ o little endian ili big endian rasporedu bajtova), ali on bi se mogao ručno ispisati na početak same datoteke (za little endian, dakle x86, to su dva bajta: 0xFF, 0xFE).

 

Ako bih morao nagađati zašto fwprintf radi konverziju iz wchar_t u char, rekao bih da je to zato što fopen i _wfopen ignoriraju specifikator koji označava željeni encoding datoteke. Pokušao sam stvarno svakakve kombinacije, čak sam i bio potpuno uklonio specifikator i rezultat je uvijek isti. Zanimljivo je da i fprintf (dakle ANSI verzija) može također ispisivati wide znakove ako se iskoristi "%S" specifikator formata (za razliku od malog "%s"), ali se također onda dogodi već spomenuta konverzija iz wchar_t u char.

 

Razlog za takvu zbrku može biti ili neki makro koji sam propustio definirati na početku datoteke, ili jednostavno problem sa runtime bibliotekom. Možda Visual Studio linka druge funkcije iz druge runtime biblioteke pa se tamo ne pojavljuju ove bizarnosti, treba provjeriti, kao što rekoh ovo je testirano sa MinGW kompajlerom.

 

Napomena slučajnim prolaznicima: ovo ovdje je sve vezano uz nestandardne API-je usko vezane uz specifičnosti Windows runtime biblioteka, od portabilnosti ovdje nema ni 'p'.

What Andy giveth, Bill taketh away.
Poruka je uređivana zadnji put sri 4.9.2013 13:32 (rustweaver).
15 godina
neaktivan
offline
Re: C problem - čitanje iz datoteke
vasso123 kaže...

kako ti kazes u UTF-16LE encodingu na Win7.

Vidim da ti je naziv nepoznat pa ću ti ga objasniti:

 

UTF - Unicode Transformation Format

16 - 16 bita, odnosno dva bajta po znaku

LE - Little endian, označava raspored bajtova kakav se koristi na x86 procesorima recimo

 

http://www.joelonsoftware.com/articles/Unicode.html

What Andy giveth, Bill taketh away.
1
Nova poruka
E-mail:
Lozinka:
 
vrh stranice