Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Koulutehtävä: Tiedoston luku ja tallennus

Shooter99 [29.10.2012 14:39:37]

#

Moi!

Eli tehtävän anto oli tehdä 2 x txt tiedostoja joissa on 10x10 taulukko liukunumeroina 1 2 3...99 100.
Nämä tiedostot piti lukea ja laskea yhteen eli.

mata.txt luku[0][0] + matb.txt luku[0][0] = summa.usr luku[0][0]
mata.txt luku[0][1] + matb.txt luku[0][1] = summa.usr luku[0][1]
mata.txt luku[0][2] + matb.txt luku[0][2] = summa.usr luku[0][2]

jne jne...

Koodini on alla oleva...
Kysymys koodin jälkeen...

#include <stdio.h>
    int main()
    {
      int eka_matriisi[10][10];
      int toka_matriisi[10][10];
      int neliot[10][10];

      int x, y;

      FILE *luku_tied;
      FILE *kirj_tied;


      if((luku_tied = fopen("mata.txt", "r")) == NULL) {
        printf("Tiedoston avaus epäonnistui (mata.txt).");
        return 0;
      }
      else {
        for(y = 0; y < 10; y++) {
          for(x = 0; x < 10; x++) {
            if(x == 9) {
              fscanf(luku_tied, "%d", &eka_matriisi[y][x]);
            }
            else {
              fscanf(luku_tied, "%d,", &eka_matriisi[y][x]);
            }
          }
        }
      }

    fclose(luku_tied);


      if((luku_tied = fopen("matb.txt", "r")) == NULL) {
        printf("Tiedoston avaus epäonnistui (matb.txt).");
        return 0;
      }
      else {
        for(y = 0; y < 10; y++) {
          for(x = 0; x < 10; x++) {
            if(x == 9) {
              fscanf(luku_tied, "%d", &toka_matriisi[y][x]);
            }
            else {
              fscanf(luku_tied, "%d,", &toka_matriisi[y][x]);
            }
          }
        }
      }

    fclose(luku_tied);


    for(y = 0; y < 10; y++) {
      for(x = 0; x < 10; x++) {
        neliot[y][x] = 0;
        neliot[y][x] = eka_matriisi[y][x] + toka_matriisi[y][x];
      }
    }


    if((kirj_tied = fopen("summa.usr" , "w")) == NULL) {
      printf("Tiedoston avaus epäonnistui (save.txt).");
    }
    else {
      for(y = 0; y < 10; y++) {
        for(x = 0; x < 10; x++) {
          if(x == 9) {
            fprintf(kirj_tied, "%d\n", neliot[y][x]);
          }
          else {
            fprintf(kirj_tied, "%d, ", neliot[y][x]);
          }
        }
      }
     }

    fclose(kirj_tied);
    return 0;
}

Onko mahdollista avata yhdellä fopenilla 2 eri tiedostoa ?

Kyseinen koodi toimii kyllä täysin oikein mutta mietin jotta onko sitä mahdollista lyhentää ???

Mod. korjasi oikeat kooditagit!

reino [29.10.2012 15:55:48]

#

Ei ole mahdollista avata yhdellä fopenilla kahta tiedostoa, mutta sisennyksiä voisit korjata vielä vähän, vaikka ne ovat kyllä paremmat kuin edellisissä koodeissasi. Miksi edes haluaisit koodista lyhyemmän, vaikka se toimii hyvin? Hyvä tapa lyhentää koodia on poistaa turhia välejä ja rivinvaihtoja.

Miksi muuten tiedostopääte on .usr ja mitä kääntäjää käytät?

User137 [29.10.2012 16:00:13]

#

Voit käyttää kahta fopenia, ja luku_tied1, luku_tied2.

En muista tarkkaan C-kieltä, mutta onko tuo pilkku tarpeen "%d,"? Voisit jättää koko if:t pois for:en sisältä. Eikös ne tiedostossa ollut välilyönneillä eroteltu? Silloin scanf..:t osannee itse parsia halutut arvot ilman erikoismerkkejä.

Ja jos nyt tarkkoja ollaan, niin koko ohjelmaan riittäisi tämän tyylinen rakenne:

int a, b
avaa tiedosto1
avaa tiedosto2
for (n menee 0..99) {
  lue(tiedosto1, a)
  lue(tiedosto2, b)
  tulostanäytölle(a+b)
}
sulje tiedosto1
sulje tiedosto2

Muuttujan nimeämisestä, matemaattisesti summa ja neliö ei tarkoita samaa asiaa. Luvun neliö on esim:
neliö(5) = 5^2 = 5*5 = 25

Shooter99 [29.10.2012 16:31:55]

#

.usr pääte tulee tehtävästä...

joo tiedän kyllä neliö käsitteen... tuttu algebrasta...

Otin mallia ohjelmasta mikä teki saman asia yhdelle tiedostolle ja laski siinä esiintyvien lukujen neliö arvon.
Neliö jäi vahingossa tähänkin kun sain ohjelman toimiin niin olin niin tohkeissani että en muuttanut enään mitään...

%d, ei käsittääkseni tee muuta kuin lisää pilkun luvun jälkeen mikä selkeytää hitusen vain tallennettuja lukuja...

No joo en ole ihan vielä tietoinen mihin kaikkeen scanf pystyy mutta tällä hetkellä olen hyvin tohkeissani siitä mihin c-kieli pystyy...

Lisäys:

Ai niin reino, periaatteessa koodi on hyvä silloin kun se toimii mutta lähinnä se mitä hain tällä kysymyksellä oli se että näkisin kuinka paljon käytän periaatteessa turhaa koodia, ja samalla ehkä voisin oppia toisen tavan tehdä saman asian.
Rivin vaihdot tulee lähinnä siitä että itse pystyn heelpottamaan omaa koodin lukemistani kun en ole mikään pro vielä... enemmänikin noob...

jalski [29.10.2012 17:50:17]

#

Shooter99 kirjoitti:

No joo en ole ihan vielä tietoinen mihin kaikkeen scanf pystyy mutta tällä hetkellä olen hyvin tohkeissani siitä mihin c-kieli pystyy...

Kun opiskelet hieman pidemmälle niin huomaat kyllä, että tiedoston -ja merkkijonojen käsittely ei kuitenkaan ole ihan C:n ominta alaa...

Esimerkiksi Fortran 90:llä tehtäväsi hoituisi:

program testi
  integer, dimension(100) :: matA, matB, matC

  open(unit=97, file='mata.txt', status='old', action='read')
  open(unit=98, file='matb.txt', status='old', action='read')
  open(unit=99, file='result.txt', status='new', action='write')

  read(97,*) matA
  read(98,*) matB
  close(97)
  close(98)

  matC = matA + matB

  write(99,*) matC
  close(99)
end program testi

Shooter99 [29.10.2012 21:24:05]

#

Terve jalski...

Varmasti kaikessa on joku mikä on toista parempi...
Ajattelin sitten kun opin pidemmälle c:tä siirtyä c++:n kautta c skriptiin... jos siis onnistun tässä vielä ennen 50 vuotis synttäreitä... Sit varmaan on c:stä tullut joku muu taas...

Jaska [30.10.2012 15:46:56]

#

Shooter99 kirjoitti:

for(y = 0; y < 10; y++) {
  for(x = 0; x < 10; x++) {
    if(x == 9) {
      fscanf(luku_tied, "%d", &eka_matriisi[y][x]);
    }
    else {
      fscanf(luku_tied, "%d,", &eka_matriisi[y][x]);
    }
  }
}

Lyhyemmin

for(y = 0; y < 10; y++) {
  for(x = 0; x < 9; ++x) {
    fscanf(luku_tied, "%d", &eka_matriisi[y][x]);
  }
  fscanf(luku_tied, "%d,", &eka_matriisi[y][x]);
}

tai ehdollisella lausekkeella:

x<9?fscanf(luku_tied, "%d", &eka_matriisi[y][x]):fscanf(luku_tied, "%d,", &eka_matriisi[y][x]);

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta