| | |
| Stránka: 1 z 1
| [ Príspevkov: 14 ] | |
Autor | Správa |
---|
Registrovaný: 20.10.08 Prihlásený: 12.04.13 Príspevky: 29 Témy: 9 | Napísal AM-JP: 03.05.2012 18:15 | |
|
ahojte, začínam s C a potreboval by som poradiť ako zadať do funkcie fscanf parametre aby mi program správne načítaval reťazce zo súboru. V súbore budú 4 reťazce za sebou oddelené bodkočiarkou. Skúšal som niečo na spôsob tohto alebo rôzne modifikácie tých parametrov ale nikdy mi to nechce ísť.
Kód: FILE *fp; char *b_name = NULL, *b_descr = NULL, *b_passwd = NULL, *b_map = NULL; fp = fopen("levels.dat","r"); while((fscanf(fp, "%a;%a;%a;%a\n", b_name,b_descr,b_passwd,b_map)) != EOF){
ďakujem za každú radu
|
|
Registrovaný: 11.01.09 Prihlásený: 24.04.24 Príspevky: 1385 Témy: 9 Bydlisko: Hrinova | Napísal Fico: 03.05.2012 19:49 | |
|
Najprv ta upozornim na par chyb v tvojom kode, ktorym by si sa mal vyvarovat:
1.) char *nieco = NULL ti vyhradi v pamati miesto IBA pre smernik na typ char, cize povacsine 4 bajty. Do takejto premennej ( na adresu, kam ukazuje ) nemozes ukladat retazec dlhsi ako jeden znak, pretoze na to nemas miesto. Mozes sem priradit akurat adresu nejakej inej premennej typu char*. Dalsia vec je, ze don hned priradil NULL a do tejto pamate uz vobec nemozes zapisovat, program ti spadne s chybou. Ak chces vytvorit miesto pre nejaky retazec, tak mozes to spravit aj tymto sposobom ako ty, teda takto: char *nieco; ale potom musis alokovat potrebnu pamat napr pomocou funkcie malloc. Inak to mozes spravit takto: char nieco[10]; Vtedy uz mozes pomocou tejto premennej ( pomocou adresy, ktoru uchovava ) uchovavat povedzme nejaky retazec.
2.) Funkcia fscanf nema formatovaci parameter %a, vsetky dostupne najdes v prirucke pre funkciu fscanf.
Teraz riesenie pre tvoj problem:
Kód: #include <stdio.h> #include <stdlib.h>
/* funkcia pre vypis chyby a ukoncenie programu */ static void printError( char *msg ) {
printf( "* Error - %s\n", msg ); exit( EXIT_FAILURE );
}
int main() {
FILE *in; char first[30], second[30], third[30], fourth[30];
/* otvorenie suboru; v pripade chyby halt */ in = fopen( "data.dat", "r" ); if ( in == NULL ) printError( "Can not find a specified file." );
/* nacitanie dat zo suboru */ fscanf( in, "%[^;];%[^;];%[^;];%[^;]", first, second, third, fourth );
/* vypis dat */ printf( "- %s\n- %s\n- %s\n- %s\n", first, second, third, fourth );
/* clean up */ close( in ); return 0;
} Obsah suboru data.dat: Kód: jeden;dva;tri;styri
Viac o parametri %[^ vo funkcii fscanf si mozes precitat tu: http://beej.us/guide/bgc/output/html/multipage/scanf.html
|
|
Registrovaný: 20.10.08 Prihlásený: 12.04.13 Príspevky: 29 Témy: 9 | Napísal autor témy AM-JP: 03.05.2012 23:55 | |
|
ďakujem...veľmi mi to pomohlo..už som si myslel že to už ani nespravím...ešte raz ďakujem
|
|
Registrovaný: 21.05.09 Prihlásený: 24.01.17 Príspevky: 12 Témy: 3 |
Zdravím. Riešim rovnaký problém a tu sú moje poznatky:
fscanf( in, "%[^;];%[^;];%[^;];%[^;]", first, second, third, fourth );
som musel opraviť na
fscanf( in, "%s[^;];%s[^;];%s[^;];%s[^;]", first, second, third, fourth );
bez tých "s" mi nabehla iba čierna obrazovka. Keď však spustím program a zavolám túto funkciu, vypíše mi " STATUS_ACCESS_VIOLATION ".
Prosím, vedel by mi niekto pomôcť?
Ďakujem.
|
|
Registrovaný: 11.01.09 Prihlásený: 24.04.24 Príspevky: 1385 Témy: 9 Bydlisko: Hrinova | Napísal Fico: 04.05.2012 11:52 | |
|
Napis presny kod, ktory kompilujes a kompilator, ktory pouzivas ( kod vloz do znacky code, aby sa to lepsie citalo ). Ak pridas tie %s, tak ti to nevypise spravne, nacita sa hned cele slovo po prvy "biely" znak, musi to byt bez znaku 's'. Ako vyzera tvoj vstupny subor?
|
|
Registrovaný: 21.05.09 Prihlásený: 24.01.17 Príspevky: 12 Témy: 3 |
Už som prišiel na chybu. Problém bol v tom, že za posledným reťazcom nebol znak ";" . Keď som tam namiesto neho zadal "\n" a odstránil tie "s"-ká, program nabehol. Ospravedlňujem sa za otravovanie, ďakujem za pomoc, každý musel nejako začať.
|
|
Registrovaný: 20.10.08 Prihlásený: 12.04.13 Príspevky: 29 Témy: 9 | Napísal autor témy AM-JP: 05.05.2012 1:22 | |
|
ešte by som mal jeden problém, ktorý sa mi vyskytol keď to chcem ďalej použiť. tie údaje mám v súbore na viac riadkov ale neviem sa odpichnúť ako správne spraviť ten jeden riadok...údaje chcem uložiť do spájaného zoznamu ale neviem sa odpichnúť od jednej položky...problémom asi bude tá pamäť cez malloc...a neviem prečo mi to tak robí..dal som si tam aj výpis obsahov tých premenných a vypísať mi to vypíše tak ako mám v súbore ale za tým mám siahodlú hlášku kompilátora. jediné na čo som ja prišiel je že keď som nenačítal nič do premennej pred odkazom na ďalšiu položku zoznamu tak mi to hlásenie nevypísalo..tu je môj kód
Kód: #include <stdio.h> #include <stdlib.h> #include <string.h>
typedef struct osoba{ char* meno; char* priezvisko; char* vek; char* zivotopis; struct osoba *dalsia_osoba; }ZOZNAM; ZOZNAM* osoby;
void load_data();
int main(int argc, char** argv) { load_data(); return (EXIT_SUCCESS); }
void levels_init(){ FILE *fp; char b_meno[100], b_priezvisko[100], b_vek[100], b_zivotopis[1000];
osoby = (ZOZNAM*)malloc(sizeof(ZOZNAM*)); fp = fopen("osoby.dat","r"); fscanf(fp, "%[^;];%[^;];%[^;];%[^\n]\n", b_meno,b_priezvisko,b_vek,b_zivotopis); osoby->meno = (char*)malloc(sizeof(char)*(strlen(b_meno)+1)); osoby->priezvisko = (char*)malloc(sizeof(char)*(strlen(b_priezvisko)+1)); osoby->vek = (char*)malloc(sizeof(char)*(strlen(b_vek)+1)); osoby->zivotopis = (char*)malloc(sizeof(char)*(strlen(b_zivotopis)+1)); osoby->dalsia_osoba = (ZOZNAM*)malloc(sizeof(ZOZNAM*)); strcpy(osoby->meno,b_meno); strcpy(osoby->priezvisko,b_priezvisko); strcpy(osoby->vek,b_vek); strcpy(osoby->zivotopis,b_zivotopis);
printf("%s\n",osoby->meno); printf("%s\n",osoby->priezvisko); printf("%s\n",osoby->vek); printf("%s\n",osoby->zivotopis); free(osoby); fclose(fp); }
a toto je to hlásenie Kód: *** glibc detected *** /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis: double free or corruption (out): 0x08899018 *** ======= Backtrace: ========= /lib/i386-linux-gnu/libc.so.6(+0x73e42)[0xb7680e42] /lib/i386-linux-gnu/libc.so.6(fclose+0x154)[0xb7670384] /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis[0x8048721] /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis[0x804851f] /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb76264d3] /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis[0x8048481] ======= Memory map: ======== 08048000-08049000 r-xp 00000000 08:05 652917 /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis 08049000-0804a000 r-xp 00000000 08:05 652917 /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis 0804a000-0804b000 rwxp 00001000 08:05 652917 /home/baran/NetBeansProjects/Vypis/dist/Debug/GNU-Linux-x86/vypis 08899000-088ba000 rwxp 00000000 00:00 0 [heap] b75d9000-b75f5000 r-xp 00000000 08:05 1045413 /lib/i386-linux-gnu/libgcc_s.so.1 b75f5000-b75f6000 r-xp 0001b000 08:05 1045413 /lib/i386-linux-gnu/libgcc_s.so.1 b75f6000-b75f7000 rwxp 0001c000 08:05 1045413 /lib/i386-linux-gnu/libgcc_s.so.1 b760c000-b760d000 rwxp 00000000 00:00 0 b760d000-b77ac000 r-xp 00000000 08:05 1065304 /lib/i386-linux-gnu/libc-2.15.so b77ac000-b77ae000 r-xp 0019f000 08:05 1065304 /lib/i386-linux-gnu/libc-2.15.so b77ae000-b77af000 rwxp 001a1000 08:05 1065304 /lib/i386-linux-gnu/libc-2.15.so b77af000-b77b2000 rwxp 00000000 00:00 0 b77c5000-b77c9000 rwxp 00000000 00:00 0 b77c9000-b77ca000 r-xp 00000000 00:00 0 [vdso] b77ca000-b77ea000 r-xp 00000000 08:05 1044541 /lib/i386-linux-gnu/ld-2.15.so b77ea000-b77eb000 r-xp 0001f000 08:05 1044541 /lib/i386-linux-gnu/ld-2.15.so b77eb000-b77ec000 rwxp 00020000 08:05 1044541 /lib/i386-linux-gnu/ld-2.15.so bf959000-bf97a000 rw-p 00000000 00:00 0 [stack]
ešte taký ilustračný súbor s dátami
http://ulozto.sk/xp5gEhX/osoby-dat
|
|
Registrovaný: 11.01.09 Prihlásený: 24.04.24 Príspevky: 1385 Témy: 9 Bydlisko: Hrinova | Napísal Fico: 05.05.2012 9:06 | |
|
Chyba je tu:
Kód: osoby = (ZOZNAM*) malloc( sizeof( ZOZNAM* ) ); 1.) ak alokujes miesto pre strukturu, nemozes povedat kompilatoru, ze chces miesto pre smernik na strukturu, pretoze ty chces celu strukturu, nie smernik, cize v sizeof bude iba sizeof( ZOZNAM ), co je velkost potrebna pre celu strukturu. sizeof( ZOZNAM* ) je iba velkost pre smernik. 2.) nie je to sice chyba, ale navratovu hodnotu z malloc netreba pretypovavat v jazyku C. Je lepsie sa tomu zlozvyku vyhnut. Dovod som pisal v tejto teme. Spravny tvar teda vyzera nejako takto ( nezabudni na osetrenie v pripade, ze sa nepodarilo alokovat pamat ): Kód: osoby = malloc( sizeof( ZOZNAM ) ); if ( osoby == NULL ); { printf( " ******* ERROR *********\n\n" ); exit(1); } Takze podla tohto si oprav vsetky riadky, kde pouzivas malloc a hlavne tam, kde alokujes miesto pre dalsiu strukturu. Aby si v programe nedostaval memory leaks ( uniky pamate, ak neuvolnis pamat, ktoru si alokoval ), nezabudni uvolnit aj polozky struktury ZOZNAM, nie len samotnu strutkturu, cize dopln este toto: Kód: printf("%s\n",osoby->meno); printf("%s\n",osoby->priezvisko); printf("%s\n",osoby->vek); printf("%s\n",osoby->zivotopis); free( osoby->meno ); free( osoby->priezvisko ); free( osoby->vek ); free( osoby->zivotopis ); free( osoby->dalsia_osoba ); osoby->dalsia_osoba = NULL;
free(osoby); osoby = NULL; fclose(fp);
|
|
Registrovaný: 20.10.08 Prihlásený: 12.04.13 Príspevky: 29 Témy: 9 | Napísal autor témy AM-JP: 05.05.2012 12:40 | |
|
doplnil som kód o to testovanie na NULL a zistil som že mi akosi vôbec nechce žiadnu pamäť alokovať..hocičo som skúšal alokovať a testovať to na NULL tak mi stále vojde do tej podmienky...a napríklad keď to netestujem tak mi dovolí akosi určité množstvo zapísať...a pri väčšom už hádže chyby...a podobne mi to robí keby som to ani nealokoval...skúšal som to prekladať aj cez terminál a gcc a nie cez prostredie a to isté...žeby bola chyba v operačnom systéme že mi nechce prideľovať pamäť alebo ako? lebo nič iné ma nenapadá
|
|
Registrovaný: 11.01.09 Prihlásený: 24.04.24 Príspevky: 1385 Témy: 9 Bydlisko: Hrinova | Napísal Fico: 05.05.2012 12:45 | |
|
Mas to urcite takto?
Kód: if ( osoby == NULL ); nie napr takto? Kód: if ( osoby = NULL ); V druhom pripade je vysledok operacie priradenia stale nenulove cislo ( true ). Inak, ak si upravis vsetko tak, ako som ti napisal, musi ti to fungovat spravne, nakolko mne to ide dobre ( tiez mam linux ) a valgrind mi nehlasi ziaden leak. // pre uplnost ti radsej pisem cely kod: Kód: #include <stdio.h> #include <stdlib.h> #include <string.h>
typedef struct osoba{ char* meno; char* priezvisko; char* vek; char* zivotopis; struct osoba *dalsia_osoba; }ZOZNAM;
ZOZNAM* osoby;
void load_data();
int main(int argc, char** argv) { load_data(); return (EXIT_SUCCESS); }
void load_data() { FILE *fp; char b_meno[100], b_priezvisko[100], b_vek[100], b_zivotopis[1000];
osoby = malloc( sizeof( ZOZNAM ) ); if ( osoby == NULL ) { printf( " ******* ERROR *********\n\n" ); exit(1); } fp = fopen("osoby.dat","r"); fscanf(fp, "%[^;];%[^;];%[^;];%[^\n]\n", b_meno,b_priezvisko,b_vek,b_zivotopis); osoby->meno = malloc( sizeof(char) * (strlen(b_meno) + 1) ); osoby->priezvisko = malloc(sizeof(char)*(strlen(b_priezvisko)+1)); osoby->vek = malloc(sizeof(char)*(strlen(b_vek)+1)); osoby->zivotopis = malloc(sizeof(char)*(strlen(b_zivotopis)+1)); osoby->dalsia_osoba = malloc(sizeof(ZOZNAM)); strcpy(osoby->meno,b_meno); strcpy(osoby->priezvisko,b_priezvisko); strcpy(osoby->vek,b_vek); strcpy(osoby->zivotopis,b_zivotopis);
printf("%s\n",osoby->meno); printf("%s\n",osoby->priezvisko); printf("%s\n",osoby->vek); printf("%s\n",osoby->zivotopis); free( osoby->meno ); free( osoby->priezvisko ); free( osoby->vek ); free( osoby->zivotopis ); free( osoby->dalsia_osoba ); osoby->dalsia_osoba = NULL;
free(osoby); osoby = NULL; fclose(fp);
}
|
|
Registrovaný: 20.10.08 Prihlásený: 12.04.13 Príspevky: 29 Témy: 9 | Napísal autor témy AM-JP: 05.05.2012 15:26 | |
|
ďakujem...ale prehodil som si systém a už mi to konečne ide...keby si vedel aký som šťastný že to fičí jak má....ešte raz ďakujem
|
|
Registrovaný: 06.05.12 Prihlásený: 20.05.13 Príspevky: 2 Témy: 0 | Napísal aktyX: 06.05.2012 9:58 | |
|
zdravim.. potreboval by som pomoc. nechal som sa inspirovat tymto poslednym pridanym zdrojakom, no nieco som aj tak spravil zle a pri komplilacii mi pise error. nevie mi niekto pomoct?
Kód: typedef struct level { char name[20]; char description[20]; char password[20]; char map[100]; struct level *dalsiLevel; }LEVEL;
LEVEL *levely;
LEVEL *levels_init(void) {
FILE *subor; char name[20]; char description[20]; char password[20]; char map[100]; levely = malloc (sizeof (LEVEL)); if (levely == NULL) { printw ("*******ERROR*******\n\n"); exit(1); } subor = fopen ("levels.dat.txt", "r");
if ((subor = fopen ("levels.dat.txt", "r")) == NULL ) { printf("neni"); } fscanf (subor, "%[^;];%[^;];%[^;];%[^\n]\n, name, description, password, map"); levely->name = malloc (sizeof (char) * (strlen(name)+1)); levely->description = malloc (sizeof (char) * (strlen(description)+1)); levely->password = malloc (sizeof (char) * (strlen (password)+1)); levely->map = malloc (sizeof(char) * (strlen (map)+1)); levely->dalsiLevel = malloc (sizeof (LEVEL));
vypis kompilatora Kód: /cygdrive/C/Users/pato/Desktop/TheProject/levels.c: In function ‘levels_init’: /cygdrive/C/Users/pato/Desktop/TheProject/levels.c:55:5: warning: too few arguments for format /cygdrive/C/Users/pato/Desktop/TheProject/levels.c:55:5: warning: too few arguments for format /cygdrive/C/Users/pato/Desktop/TheProject/levels.c:57:18: error: incompatible types when assigning to type ‘char[20]’ from type ‘void *’ /cygdrive/C/Users/pato/Desktop/TheProject/levels.c:58:25: error: incompatible types when assigning to type ‘char[20]’ from type ‘void *’ /cygdrive/C/Users/pato/Desktop/TheProject/levels.c:59:22: error: incompatible types when assigning to type ‘char[20]’ from type ‘void *’ /cygdrive/C/Users/pato/Desktop/TheProject/levels.c:60:17: error: incompatible types when assigning to type ‘char[100]’ from type ‘void *’
|
|
Registrovaný: 11.01.09 Prihlásený: 24.04.24 Príspevky: 1385 Témy: 9 Bydlisko: Hrinova | Napísal Fico: 06.05.2012 10:10 | |
|
Kod patri do znacky code, takto to je necitatelne...
Chybu si mal okrem toho, ze si z premennych spravil retazec:
Kód: fscanf (subor, "%[^;];%[^;];%[^;];%[^\n]\n, name, description, password, map"); v tom, ze kolega pred tebou mal v strukture LEVEL iba smerniky na typ char, tzn pouzil dynamicku alokaciu. Ty nepouzivas smerniky, ale polia, cize nemusis alokovat pamat pomocou malloc, polia uz maju svoju pamat vyhradenu. Uprav si to takto: Kód: LEVEL *levels_init(void) {
FILE *subor;
char name[20]; char description[20]; char password[20]; char map[100];
levely = malloc (sizeof (LEVEL)); if (levely == NULL) { printw("*******ERROR*******\n\n"); exit(1); }
subor = fopen ("levels.dat.txt", "r");
if ((subor = fopen ("levels.dat.txt", "r")) == NULL ) { printf("neni"); }
fscanf(subor, "%[^;];%[^;];%[^;];%[^\n]\n", name, description, password, map); levely->dalsiLevel = malloc (sizeof (LEVEL));
return 0;
}
/* Uz ked clovek opisuje, tak aspon poriadne */
|
|
Registrovaný: 06.05.12 Prihlásený: 20.05.13 Príspevky: 2 Témy: 0 | Napísal aktyX: 06.05.2012 10:46 | |
|
aha jasne. dikes
uz som zistil ako pridat kod do kodu
|
|
| Stránka: 1 z 1
| [ Príspevkov: 14 ] | |
Podobné témy | Témy | Odpovede | Zobrazenia | Posledný príspevok |
---|
| c++ citanie zo suboru v Assembler, C, C++, Pascal, Java | 2 | 1986 | 24.09.2012 20:08 S1RuP | | citanie zo suboru: pascal v Assembler, C, C++, Pascal, Java | 3 | 704 | 24.04.2009 21:14 juho | | Štruktúra, čítanie zo súboru [C] v Assembler, C, C++, Pascal, Java | 2 | 434 | 18.04.2015 9:26 ado130 | | PHP citanie z TXT suboru v PHP, ASP | 6 | 1060 | 12.06.2010 10:54 kexo | | C# čítanie jedného riadka z textového súboru v Assembler, C, C++, Pascal, Java | 4 | 517 | 27.06.2014 14:08 walther | | USB kluce formatovane na FAT32 vs NTFS v Ostatné zariadenia | 8 | 3530 | 21.12.2014 12:53 4040 | | citanie kodu v PHP, ASP | 2 | 431 | 14.01.2011 20:42 slebo | | Periferne citanie v Voľný čas a hobby | 7 | 753 | 10.09.2012 10:19 dixi | | C++ Čítanie ŠPZ v Assembler, C, C++, Pascal, Java | 4 | 595 | 28.03.2017 19:08 void | | citanie textu odzadu v PHP, ASP | 2 | 810 | 14.06.2009 23:13 pa3ck | | Tablet na citanie v Mobilné zariadenia | 0 | 201 | 16.09.2014 19:12 florq | | Citanie MIME emailu v PHP, ASP | 11 | 600 | 19.08.2010 13:26 Merlin_sk | | Čítanie textu stránok v Ostatné | 1 | 512 | 09.04.2012 1:18 shaggy | | CITANIE CD A DVD [ Choď na stránku: 1, 2 ] v Optické zariadenia | 45 | 3272 | 16.07.2008 16:20 andrejko99 | | Citanie HDD cez USB v Pevné disky a radiče | 1 | 404 | 30.12.2010 16:30 walther | | Efektívne čítanie príkazov - C v Assembler, C, C++, Pascal, Java | 13 | 712 | 28.12.2013 16:06 BX |
| Nemôžete zakladať nové témy v tomto fóre Nemôžete odpovedať na témy v tomto fóre Nemôžete upravovať svoje príspevky v tomto fóre Nemôžete mazať svoje príspevky v tomto fóre
|
|