praegune kellaaeg 16.06.2024 01:37:59
|
Hinnavaatlus
:: Foorum
:: Uudised
:: Ärifoorumid
:: HV F1 ennustusvõistlus
:: Pangalink
:: Telekavad
:: HV toote otsing
|
|
autor |
sõnum |
|
R A T
HV veteran
liitunud: 21.04.2004
|
11.03.2008 09:35:36
[C] file i/o probleem. Loe failist, parsi, kirjuta faili. |
|
|
Tere,
Üritan tööl ühte scripti teha, mis tirib ftp serverist faililisti (.bat failiga), seejärel lüüakse käima c-s tehtud programm, mis selle listi ette võtab.
Seejärel valmistatakse järgmine bat fail, mis hiljem peaks ühendama ftp serverisse ja deleteb ära failid, mis olid varasemalt programmiga genereeritud batchis.
ehk siis, sisendfail on failiridadega, ala
c:\test1.sap
c:\test2.sap
Sellest tehakse
...ftp connect...
mdelete test1.sap
mdelete test2.sap
..ftp bye
Terve eilse päeva sai asjaga jamatud.
PrintF-iga õnnestus kogu sisu ekraanil kuvada, kui kui faili kirjutamine juurde teha, hakkas kinni jooksma.
Kompiilib kenasti.
Kas on mingid piirangud file i/o kasutuses?
Põhimõtteliselt võiksin asja ju kuidagi teistmoodi lahendada (delphi, kix), aga kuna olen 1 kursuse tudeng, siis tahaks ikka c-s asja ära teha, et kooliülesannete tegemiseks kogemusi saada. File I/O on suhteliselt oluline.
Minu kribatud kood on siin:
#include <stdio.h> // standardne sisend-väljund
#include <conio.h> // klaviatuur-kuvar
int main(void)
{
FILE *fp=fopen("test.txt", "r");
FILE *ofp=fopen("delete.txt", "wb");
const char *USERNAME="FTPKASUTAJANIMI"; // <- FTP USER
const char *PASSWORD="FTPPAROOL"; // <- FTP PAROOL
const char *HOMEDIR="C:\\Data\\test";
const int MAXRIDA=240;
const int PATHLEN=14;
char *txt="piix KÜLL";
char mark;
int i=0;
int pos=0;
if(fp==NULL){
printf("Sisendfaili avamine ebaõnnestus\n");
return 1;
}
if(ofp==NULL){
printf("Väljundfaili avamine ebaõnnestus\n");
return 1;
}
else{
//Kirjuta väljundfaili sisselogimisinfo
fputs("open FTP.IP.PEAKS.OLEMA.SIIN\n",ofp); //<-- FTP IP
fputs(USERNAME,ofp);
fputs("\n",ofp);
fputs(PASSWORD,ofp);
fputs("\ncd ..\ncd export\ncd plant0003\nbinary\nhash\nprompt\nlcd ",ofp);
fputs(HOMEDIR,ofp);
// kordus faili lõpuni
while (!feof(fp)) {
//Järgnev rida tekitab probleemi:
fgets(txt, MAXRIDA, fp); //<- KUI SEE ÄRA VÕTTA SIIS KÕIK JOOKSEB (aga ei saa whilest välja)
pos=0;
mark=txt[pos];
fputs("\nmdelete ",ofp);
//printf("\nmdelete ");
do{
mark=txt[pos++];
if (pos>=PATHLEN) {
fputs(&mark,ofp);
//printf("%c", mark); //Kui välja kommenteerida outputfile kogu projektist, siis saaab printima täpselt õiget rida
}
} while(mark); // rea lõpumärk]*/
//Kirjuta lõppfail ja sulge failid.
fputs("\nbye\n",ofp);
fclose(ofp);
fclose(fp);
}
}
printf("\nVajuta suvalist nuppu, et lõpetada...");
getch();
return 0;
}
|
_________________ Jogani pogani pooh |
|
Kommentaarid: 32 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
1 :: |
30 |
|
tagasi üles |
|
|
XYZ
HV Guru
liitunud: 05.11.2001
|
11.03.2008 09:39:28
|
|
|
c juurde käib IDE-s ka debugger, sinu lihtsa programmi puhul ei tohiks mingit raskust olla sellega järgi vaadata, mis seda kinni jooksutab. Tõenäoliselt oled mõne loogikavea teinud (näiteks jääb lõputusse tsüklisse....).
|
|
Kommentaarid: 81 loe/lisa |
Kasutajad arvavad: |
|
:: |
3 :: |
12 :: |
56 |
|
tagasi üles |
|
|
troglodyte
Kreisi kasutaja
liitunud: 09.08.2002
|
11.03.2008 13:29:53
|
|
|
Siin sa annad fputs() funktsioonile char tüüpi muutja aadressi ehk üsna suvalise aadressi kuskilt programmi mälust (mis ei ole seotud txt poolt viidatava mälualaga, kuid mulle tundub et sa eeldad seda)
Milleks kogu järgnevat koodilõiku üldse vaja on?
c:
|
pos=0; mark=txt[pos]; fputs("\nmdelete ",ofp); //printf("\nmdelete "); do{ mark=txt[pos++]; if (pos>=PATHLEN) { fputs(&mark,ofp); //printf("%c", mark); //Kui välja kommenteerida outputfile kogu projektist, siis saaab printima täpselt õiget rida } } while(mark); // rea lõpumärk]*/
|
Siin sa sulged while() loopi sees nii sisend kui väljundfaili, mida sa arvatavasti ei soovi.
c:
|
while (!feof(fp)) { /* ... */ fclose(ofp); fclose(fp); }
|
Lisaks ei kontrolli sa seda, mida fgets() tagastab.
|
|
Kommentaarid: 33 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
0 :: |
33 |
|
tagasi üles |
|
|
R A T
HV veteran
liitunud: 21.04.2004
|
11.03.2008 15:08:02
|
|
|
troglodyte - esimese quotetud käsuni programm ei jõuagi (panin debug teated igalepoole vahele, nooltega näidatud reast edasi ei minda.
Ka ei satuta lõpmatu loopini.
teises quotes nullitakse ära loendur (pos) ja mark väärtuseks antakse laetud rea (mida praegu miskipärast ei laeta) sümbol positisioonil pos.
Posi suurust hiljem suruendatakse, kuni on kogu rida läbi käidud.
While osas mitte ei suleta faili, vaid kontrollitakse, kas oleme jõudnud "fp" faili lõppu (feof) Kui see ei vasta tõele siis jätkatakse.
fgets tagastab rea "txt" muutujasse ja sealt loetakse sümbolid ükshaaval välja (txt[pos]). Igat rida loetakse seni, kuni muutuja "mark" omab mingit sisu (st, ei ole jõutud rea lõppu)
Kõige imelikum ongi see, et kõik töötas kenasti, kuni lisasin failiväljundi. Kuid kuidas on seotud faili väljund sisendfailist lugemisega?
Üritan nüüd debuggeriga midagi jamada, kuid üldjoontes ei ole ma sellest suurt midagi abi saanud.
Tavaliselt teen Delphi-s programme, seal ei kompiili ära ja kõik, C aga kompiilib ka vigaseid programme
_________________ Jogani pogani pooh |
|
Kommentaarid: 32 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
1 :: |
30 |
|
tagasi üles |
|
|
troglodyte
Kreisi kasutaja
liitunud: 09.08.2002
|
11.03.2008 15:29:13
|
|
|
tsitaat: |
teises quotes nullitakse ära loendur (pos) ja mark väärtuseks antakse laetud rea (mida praegu miskipärast ei laeta) sümbol positisioonil pos.
Posi suurust hiljem suruendatakse, kuni on kogu rida läbi käidud. |
Kuid milleks? Tegu on ju tühja tööga?
tsitaat: |
While osas mitte ei suleta faili, vaid kontrollitakse, kas oleme jõudnud "fp" faili lõppu (feof) Kui see ei vasta tõele (!) siis jätkatakse. |
Vaata while() loopi blokki tähelepanelikumalt - mõlemad descriptorid suletakse enne järgmise tsükli algust!
tsitaat: |
fgets tagastab rea "txt" muutujasse ja sealt loetakse sümbolid ükshaaval välja (txt[pos]). Igat rida loetakse seni, kuni muutuja "mark" omab mingit sisu (st, ei ole jõutud rea lõppu)
Kõige imelikum ongi see, et kõik töötas kenasti, kuni lisasin failiväljundi. Kuid kuidas on seotud faili väljund sisendfailist lugemisega? |
char *txt = "piix KÜLL" viitab fikseeritud pikkusega/konstantsele (10 baiti) mälujupile ning sõlutvalt opsüsteemist/kompilaatorist hakkab seda ülekirjutades huvitavaid asju juhtuma. Tee näiteks char buf[MAXRIDA+1] ka loe andmed sinna.
|
|
Kommentaarid: 33 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
0 :: |
33 |
|
tagasi üles |
|
|
R A T
HV veteran
liitunud: 21.04.2004
|
11.03.2008 16:58:15
|
|
|
1) mul on tarvis mitte tervet rida laadida, vaid esimesed 14 märki jäetakse vahele, peale mida 1 haaval kirjutatakse faili. (Niipalju kui aru olen saanud, puuduvad basic io all stringi manipuleerimiseks käsud)
2) Aga mis sel viga on? (rebisin 3 rea peale ümber, et lihtsam oleks aru saada)
do{mark=txt[pos++];
if (pos>=14){printf("%c", mark);}
} while(mark);
3) see char oli tegelikult "*txt" aga ma läksin mingiaeg närvi ja katsetasin nii, et defineerisin sisu ennem ära. Kas mitte * ei tee seda pikkusevärki automaatseks?
EDIT: Nii, su jutus oli siiski point sees, ma panin txt chari pikkuseks 240, peale seda tuli välja, et while sattus tõesti loopi.
Kurjam, enam ma ei mõista, kuidas ma ta varem siis sain printf-ide abil täiesti kenasti kuvama konsooli selle teksti, millest ma bati tahan
Nuni, sain jälle kuvama kõik kenasti, sellise koodiga:
while (!feof(fp)) {
printf("Loeme Rea\n");
fgets(txt, 200, fp);
pos=0;
mark=txt[pos];
//fputs("\nmdelete ",ofp);
printf("\nmdelete ");
do{
mark=txt[pos++];
if (pos>=14) {
//fputs(&mark,ofp);
printf("%c", mark);
}
} while(mark); // rea lõpumärk]*/
} |
_________________ Jogani pogani pooh |
|
Kommentaarid: 32 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
1 :: |
30 |
|
tagasi üles |
|
|
troglodyte
Kreisi kasutaja
liitunud: 09.08.2002
|
11.03.2008 18:06:13
|
|
|
R A T kirjutas: |
1) mul on tarvis mitte tervet rida laadida, vaid esimesed 14 märki jäetakse vahele, peale mida 1 haaval kirjutatakse faili. (Niipalju kui aru olen saanud, puuduvad basic io all stringi manipuleerimiseks käsud) |
Stringitöötlus funktsioonide definitsioonid asuvad string.h failis tavaliselt.
tsitaat: |
2) Aga mis sel viga on? (rebisin 3 rea peale ümber, et lihtsam oleks aru saada)
do{mark=txt[pos++];
if (pos>=14){printf("%c", mark);}
} while(mark);
|
Kogu selle tsükli võiks asendada lihtsa jupiga:
tsitaat: |
3) see char oli tegelikult "*txt" aga ma läksin mingiaeg närvi ja katsetasin nii, et defineerisin sisu ennem ära. Kas mitte * ei tee seda pikkusevärki automaatseks? |
Ei tee automaatseks - * näitab, et tegu on lihtsalt viitega kuhugi mälupiirkonda. Mälupiirkond tuleks enne aga eraldada näiteks malloc funktsiooni abil.
Ühesõnaga uuri veidi pointeriaritmeetika, massiivide ja mälueralduse kohta.
|
|
Kommentaarid: 33 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
0 :: |
33 |
|
tagasi üles |
|
|
R A T
HV veteran
liitunud: 21.04.2004
|
11.03.2008 23:39:46
|
|
|
Massiivid on tuttav teema, delfis ikka kasutan neid
Proovin homme koodi korda teha, see txt+14 on vabsee hea variant!
Aga samas mul pole vaja printida, vaid faili salvestada - Ise kasutasin:
fputs(&mark,ofp);
Kas siis peaks järelikult kasutama:
fputs(txt+14,ofp);
Või viskab selle peale errori?
Mul pole praegu projekti kaasas, kodus ei viitsi sellega jamada
Sellepärast muidu tööasja C-s teengi, et asi veits selgemaks saaks - harjutamine teeb meistriks
Delphis oleks see programm mul arvatavasti 5 korda valmis tehtud, aga miks minna otse, kui saab ringiga
_________________ Jogani pogani pooh |
|
Kommentaarid: 32 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
1 :: |
30 |
|
tagasi üles |
|
|
sammalhäbe
HV kasutaja
liitunud: 18.08.2003
|
21.03.2008 12:12:07
|
|
|
veel viisakam oleks enne kontrollida ka, kui pikk txt on, enne selle pointerile 14 otsa lajatamist
fputs( (strlen(txt) >= 14) ? txt + 14 : "", ofp);
üldiselt oleks kõige universaalsem ja mugavam ikkagi kasutada üldse fprintf-i
ja soovitav oleks lugeda pointerite ja pointeraritmeetika kohta mingit kirjatükki,
sest kui seda endale päris selgeks ei tee, siis jäädki kobama. mõni asi töötab, mõni ei tööta...
googelda pointer arithmetic c++ vms ja paar resulti nt:
http://www.augustcouncil.com/~tgibson/tutorial/ptr.html
http://www.augustcouncil.com/~tgibson/tutorial/arr.html
http://www.softwareacademy.de/cpplernen/?cpp=Arrays,%20Pointers%20and%20References&ziel=Pointer%20Arithmetic
enamus tudengeid kes siin küsivad C kohta ongi hädas just pointeraritmeetikaga tegelikult.
C kohta on üks hea raamat kah, Lepiksoni "programmeerimine C keeles". usutavasti on ka seal pointerid lahti seletatud
Delphis on tõesti jah, pointerivärk lihtsamaks tehtud ja mõnevõrra ära peidetud, seal sellega väga kergelt jalga ei tulista
|
|
Kommentaarid: 2 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
0 :: |
2 |
|
tagasi üles |
|
|
R A T
HV veteran
liitunud: 21.04.2004
|
22.03.2008 16:42:10
|
|
|
Ma väga viksilt koodi ei teinud jah, kuid siiski kõik töötab ja on testimise läbinud
Suur tänu, võtan kindlasti antud artiklid ette!
Tundus olevat väga hästi ja visuaalselt seletatud olevat.
Suur tänu kõigile, kes abistasid.
Hetkel asi on töös ja osaleb soome ja eesti vahelises infovahetuses tuulegeneraatorite tootmises
_________________ Jogani pogani pooh |
|
Kommentaarid: 32 loe/lisa |
Kasutajad arvavad: |
|
:: |
0 :: |
1 :: |
30 |
|
tagasi üles |
|
|
|
lisa lemmikuks |
|
|
sa ei või postitada uusi teemasid siia foorumisse sa ei või vastata selle foorumi teemadele sa ei või muuta oma postitusi selles foorumis sa ei või kustutada oma postitusi selles foorumis sa ei või vastata küsitlustele selles foorumis sa ei saa lisada manuseid selles foorumis sa võid manuseid alla laadida selles foorumis
|
|
Hinnavaatlus ei vastuta foorumis tehtud postituste eest.
|