Jazyk C 2013 – 4. cvičenie

Práca so súbormi

Maximum z nameraných teplôt

V textovom súbore sa nachádza 10 teplôt (reálne čísla). Nájdite najväčšiu nameranú teplotu.

Na I/O operácie použijeme:

  • fopen() na otvorenie súboru v režime čítania (r).

    • funkcia vracia FILE * (čítaj smerník na FILE, resp. pointer na FILE, resp. ukazovateľ na FILE)
      • FILE je veľkými písmenami!
    • výnimky v C neexistujú. Chyba sa indikuje návratovou hodnotou. Po dobehnutí funkcie je nutné overiť, že návratová hodnota nie je NULL
      • na rozdiel od Javy je NULL konštanta uvádzaná veľkými písmenami.
      • ak sa súbor nenájde, program môžeme rovno ukončiť. Vráťme nenulovú hodnotu, napr. -1.
  • prípadnú chybu môžeme vypísať cez perror(). Tá vypíše nielen vlastnú hlášku, ale aj popisnejšiu hlášku pochádzajúcu zo systému.

  • fclose() slúži na zavretie súboru.

Vyskúšajme si minimalistickú verziu, so zámerne zlou cestou k súboru:

#include<stdio.h>

int main() {
  FILE * subor;

  subor = fopen("neexistujuci.txt", "r");
  if(subor == NULL) {
    perror("Subor sa nepodarilo otvorit");
    return -1;
  }

  fclose(subor);
  return 0;
}

Na načítavanie:

  • fscanf() je použité na načítanie hodnoty.
    • syntax je podobná printf(): formátovací reťazec nasledovaný premennými
    • hodnoty typu double načítavame cez špecifikátor %lf (long float)
    • pri načítavaní cez scan označíme premenné prefixom &. Súvisí to so smerníkmi, o ktorých nevieme nič.

Maximum môžeme inicializovať konštantou INT_MIN z hlavičkového súboru limits.h.

  • Nezabudnime include-núť príslušný súbor!

Celý zdroják:

#include<stdio.h>
#include<limits.h>

#define POCET_HODNOT 10

int main() {
  double maximum = INT_MIN;
  double hodnota = 0;
  int i = 0;
  FILE * subor;

  subor = fopen("teploty.txt", "r");
  if(subor == NULL) {
    perror("Subor sa nepodarilo otvorit");
    return -1;
  }

  for(i = 0; i < POCET_HODNOT; i++) {
    fscanf(subor, "%lf", &hodnota);
    if(hodnota > maximum) {
      maximum = hodnota;
    }
  }
  printf("Maximum je: %f", maximum);

  fclose(subor);
  return 0;
}

Maximum z nameraných teplôt [cez pole]

Načítajte 10 teplotných hodnôt do poľa. Nájdite v ňom maximum.

Úloha je rozšírením predošlého zadania.

  • pole 10 prvkov deklarujeme cez:

    double prvky[POCET_PRVKOV]
    

    Porov. s Javou:

    /*Java:*/ 
    double[] prvky = new double[POCET_PRVKOV];
    
  • pole v C možno nadeklarovať (bez inicializácie prvkami) len na základe konštanty. Pri uvádzaní dĺžky poľa nemožno použiť premennú! (Vysvetlenie napríklad v 5. dieli seriálu o Jave.)

  • môžeme radostne načítavať fscanf()om do prvku poľa. Nezabudnime na ampersand!

    fscanf(subor, "%lf", &prvky[i]);
    
  • ak vytvárame funkciu, ktorá berie pole, vždy dodajme argument s dĺžkou poľa!

    • v C nemožno za behu zistiť dĺžku poľa, na rozdiel od Javy, kde existuje prvky.length.

Celý zdroják

#include<stdio.h>
#include<limits.h>

#define POCET_PRVKOV 10

double najdi_maximum(double prvky[], int dlzka) {
  int i = 0;
  double maximum = INT_MIN;
  while(i < dlzka) {
    if(prvky[i] > maximum) {
      maximum = prvky[i];
    }
    i++;
  }
  return maximum;
}

int main() {
  FILE * subor;
  int i = 0;

  double prvky[POCET_PRVKOV];

  subor = fopen("teploty.txt", "r");
  if(subor == NULL) {
    perror("Subor sa nepodarilo otvorit");
    return -1;
  }

  for(i = 0; i < POCET_PRVKOV; i++) {
    fscanf(subor, "%lf", &prvky[i]);
  }

  printf("Maximum je: %f", najdi_maximum(prvky, POCET_PRVKOV));

  fclose(subor);
  return 0;
}

Poznámky

Nastavte si nano

  • Skratkou Ctrl + _ (podtržidlo) môžete prechádzať na zadané číslo riadku.
  • Ak spustíte nano s parametrom -c, dostanete stavový riadok s číslom aktuálneho riadka v súbore

    nano -c teploty2.c
    
  • Toto nastavenie môžete zaviesť do konfiguráku nano:

    nano ~/.nanorc
    

    Uveďte doň jediný riadok:

    set const
    

    Odteraz nemusíte používať parameter -c.

Generovanie náhodných čísiel

Teploty možno nagenerovať v shelli cez seq a awk:

seq 10 | awk 'BEGIN { srand() } { printf "%.2f\n",  -(rand() * 60) - 30}'
  1. Vygenerujeme 10 náhodných čísiel.
  2. Pred spracovávaním prvého nainicializujeme generátor čísiel.
  3. V awk vracia funkcia rand() reálne číslo medzi 0 a 1. Využijeme vzorec:

    spodok + číslo * (vrch - spodok)
    -30    + číslo * (30 - -30)
    -30    + číslo * 60 
    
  4. Vytlačíme ho s presnosťou na dve desatinné miesta — printf() funguje presne ako v C.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *