C Academy · Oppitunti

Yleiset I/O-sudenkuopat

Puskuri- ja rivinvaihto-ongelmat.

Oppitunti 4/413 vaihetta

Yleiset I/O-sudenkuopat on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.

Yleiset I/O-ongelmat

C-kielen syötteessä ja tulosteessa on muutamia klassisia kompastuskiviä. Niiden tunteminen säästää tuntikausia virheenkorjauksessa.

#include <stdio.h>
int main(void) {
    printf("Let us study I/O pitfalls\n");
    return 0;
}

Puskuriin jäänyt rivinvaihto

scanf("%d", ...)-kutsun jälkeen Enter-näppäin jättää puskuriin merkin \n. Myöhempi %c lukee tämän rivinvaihdon oikean syötteen sijaan.

#include <stdio.h>
int main(void) {
    char c = 'A';
    printf("Use a space before %%c to skip the leftover newline\n");
    printf("c = %c\n", c);
    return 0;
}

Korjaaminen välilyönnillä

Kun kirjoitatte scanf(" %c", &c), alussa oleva välilyönti käskee scanf-funktiota ohittamaan ensin tyhjemerkit.

#include <stdio.h>
int main(void) {
    char c = 'Z';
    printf("scanf(\" %%c\", &c) skips whitespace\n");
    printf("c = %c\n", c);
    return 0;
}

Et-merkinnän unohtaminen

Muuttujan välittäminen scanf-funktiolle ilman &-merkkiä tallentaa tiedon väärään osoitteeseen ja aiheuttaa todennäköisesti ohjelman kaatumisen.

#include <stdio.h>
int main(void) {
    int n = 9;
    printf("Always pass &n, not n, to scanf for an int\n");
    printf("n = %d\n", n);
    return 0;
}

Määritteiden yhteensopimattomuus

Doublen lukeminen määritteellä %f määritteen %lf sijaan scanf-funktiossa turmelee arvon. Tulostuksessa molemmille käytetään %f-määritettä, mutta syötteessä ne eroavat toisistaan.

#include <stdio.h>
int main(void) {
    double d = 2.5;
    printf("scanf needs %%lf for double; printf uses %%f\n");
    printf("d = %.1f\n", d);
    return 0;
}

Tulosteen puskurointi

Tuloste voidaan puskuroida, jolloin se ei näy heti. Lopettaminen merkkiin \n tai kutsu fflush(stdout) tyhjentää puskurin.

#include <stdio.h>
int main(void) {
    printf("Flushed by newline\n");
    fflush(stdout);
    return 0;
}

gets on vaarallinen

Vanha gets-funktio ei tarkistanut rajoja, ja se on poistettu nykyaikaisesta C-kielestä. Käyttäkää sen sijaan fgets-funktiota.

#include <stdio.h>
int main(void) {
    char buf[10];
    /* fgets(buf, sizeof buf, stdin); */
    buf[0] = 'H'; buf[1] = 'i'; buf[2] = 0;
    printf("buf = %s\n", buf);
    return 0;
}

Puskuriylivuoto %s-määritteellä

Pelkkä %s scanf-funktiossa voi kirjoittaa pienen taulukon rajojen yli. Rajoittakaa pituutta leveydellä, kuten %19s.

#include <stdio.h>
int main(void) {
    char name[20];
    printf("Use %%19s to leave room for the null terminator\n");
    name[0] = 0;
    printf("name length cap protects buffer\n");
    return 0;
}

fgets säilyttää rivinvaihdon

fgets tallentaa lopussa olevan rivinvaihdon. Se on usein poistettava erikseen.

#include <stdio.h>
#include <string.h>
int main(void) {
    char line[] = "hello\n";
    line[strcspn(line, "\n")] = 0;
    printf("[%s]\n", line);
    return 0;
}

Palautusarvojen huomiotta jättäminen

scanf-funktion palautusarvon tarkistamatta jättäminen päästää virheellisen syötteen läpi huomaamatta. Tarkistakaa se aina.

#include <stdio.h>
int main(void) {
    int n = 3;
    int items = 1;
    if (items != 1)
        printf("bad input\n");
    else
        printf("ok: %d\n", n);
    return 0;
}

Kokonaisuuden turvallinen yhdistäminen

Luotettava toimintamalli on seuraava: lukekaa fgets-funktiolla, jäsentäkää sscanf-funktiolla ja tarkistakaa tulos.

#include <stdio.h>
int main(void) {
    char line[] = "123";
    int n;
    if (sscanf(line, "%d", &n) == 1)
        printf("parsed %d\n", n);
    return 0;
}

Pikatarkistus

Testatkaa, miten hyvin ymmärrätte I/O:n kompastuskivet.

Kertaus: yleiset I/O-kompastuskivet

Opitte välttämään yleisiä virheitä.

  • Puskuriin jääneet rivinvaihdot sekoittavat %c-määritteen; käyttäkää alussa välilyöntiä
  • Välittäkää osoitteet aina &-merkin kanssa
  • Käyttäkää %lf-määritettä double-arvojen lukemiseen
  • Suosikaa fgets-funktiota gets-funktion sijaan ja rajoittakaa %s-määritteen pituutta
  • Tarkistakaa palautusarvot ja tyhjentäkää tulostuspuskuri
Aloita maksutta

Opi C tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
39
Oppitunnit
144

Usein kysytyt kysymykset

Onko oppitunti ”Yleiset I/O-sudenkuopat” ilmainen?

Kyllä – oppitunnin ”Yleiset I/O-sudenkuopat” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Yleiset I/O-sudenkuopat”?

Puskuri- ja rivinvaihto-ongelmat. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Yleiset I/O-sudenkuopat”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?

Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. printf-muotoilumääritteet
  2. scanf ja syöte
  3. Leveys, tarkkuus ja liput
  4. Yleiset I/O-sudenkuopat
← Takaisin: C Academy