Avaleht
uus teema   vasta Tarkvara »  Programmeerimine »  [C] file i/o probleem. Loe failist, parsi, kirjuta faili. märgi kõik teemad loetuks
märgi mitteloetuks
vaata eelmist teemat :: vaata järgmist teemat
Hinnavaatlus :: Foorum :: Uudised :: Ärifoorumid :: HV F1 ennustusvõistlus :: Pangalink :: Telekavad :: HV toote otsing
autor
sõnum Saada viide sõbrale. Teata moderaatorile
otsing:  
R A T
HV veteran
R A T

liitunud: 21.04.2004




sõnum 11.03.2008 09:35:36 [C] file i/o probleem. Loe failist, parsi, kirjuta faili. vasta tsitaadiga

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
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
XYZ
HV Guru
XYZ

liitunud: 05.11.2001




sõnum 11.03.2008 09:39:28 vasta tsitaadiga

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
vaata kasutaja infot saada privaatsõnum
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 11.03.2008 13:29:53 vasta tsitaadiga

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)
fputs(&mark,ofp);


Milleks kogu järgnevat koodilõiku üldse vaja on?
c:
  1.  
  2. pos=0;
  3. mark=txt[pos];
  4. fputs("\nmdelete ",ofp);
  5. //printf("\nmdelete ");
  6. do{
  7.   mark=txt[pos++];
  8.   if (pos>=PATHLEN) {
  9.     fputs(&mark,ofp);
  10.     //printf("%c", mark);  //Kui välja kommenteerida outputfile kogu projektist, siis saaab printima täpselt õiget rida
  11.   }
  12. } while(mark); // rea lõpumärk]*/
  13.  


Siin sa sulged while() loopi sees nii sisend kui väljundfaili, mida sa arvatavasti ei soovi.
c:
  1.  
  2. while (!feof(fp)) {
  3.   /* ... */
  4.   fclose(ofp);
  5.   fclose(fp);
  6. } 
  7.  


Lisaks ei kontrolli sa seda, mida fgets() tagastab.
Kommentaarid: 33 loe/lisa Kasutajad arvavad:  :: 0 :: 0 :: 33
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
R A T
HV veteran
R A T

liitunud: 21.04.2004




sõnum 11.03.2008 15:08:02 vasta tsitaadiga

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 icon_exclaim.gif 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 icon_biggrin.gif

_________________
Jogani pogani pooh
Kommentaarid: 32 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 30
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 11.03.2008 15:29:13 vasta tsitaadiga

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
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
R A T
HV veteran
R A T

liitunud: 21.04.2004




sõnum 11.03.2008 16:58:15 vasta tsitaadiga

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 icon_biggrin.gif


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
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
troglodyte
Kreisi kasutaja
troglodyte

liitunud: 09.08.2002




sõnum 11.03.2008 18:06:13 vasta tsitaadiga

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:
printf("%s", txt + 14);


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
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
R A T
HV veteran
R A T

liitunud: 21.04.2004




sõnum 11.03.2008 23:39:46 vasta tsitaadiga

Massiivid on tuttav teema, delfis ikka kasutan neid icon_smile.gif
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 icon_biggrin.gif
Sellepärast muidu tööasja C-s teengi, et asi veits selgemaks saaks - harjutamine teeb meistriks icon_smile.gif

Delphis oleks see programm mul arvatavasti 5 korda valmis tehtud, aga miks minna otse, kui saab ringiga icon_razz.gif

_________________
Jogani pogani pooh
Kommentaarid: 32 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 30
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
sammalhäbe
HV kasutaja

liitunud: 18.08.2003




sõnum 21.03.2008 12:12:07 vasta tsitaadiga

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
vaata kasutaja infot saada privaatsõnum
R A T
HV veteran
R A T

liitunud: 21.04.2004




sõnum 22.03.2008 16:42:10 vasta tsitaadiga

Ma väga viksilt koodi ei teinud jah, kuid siiski kõik töötab ja on testimise läbinud icon_smile.gif
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 icon_smile.gif

_________________
Jogani pogani pooh
Kommentaarid: 32 loe/lisa Kasutajad arvavad:  :: 0 :: 1 :: 30
tagasi üles
vaata kasutaja infot saada privaatsõnum mine selle kasutaja kodulehele
näita postitusi alates eelmisest:   
uus teema   vasta Tarkvara »  Programmeerimine »  [C] file i/o probleem. Loe failist, parsi, kirjuta faili.
[vaata eelmist teemat] [vaata järgmist teemat]
 lisa lemmikuks
näita foorumit:  
 ignoreeri teemat 
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.