Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

Benutzer Diskussion:Mario: Unterschied zwischen den Versionen

K (howto added)
K (Adaption des Feedbacks)
Zeile 39: Zeile 39:
  
 
* ''printf'' benutzt das '''%'''-Zeichen zur Markierung welcher Teil des Textes ersetzt werden muss.
 
* ''printf'' benutzt das '''%'''-Zeichen zur Markierung welcher Teil des Textes ersetzt werden muss.
* nach dem '''%'''-Zeichen steht der ''Typbezeichner'': '''%d''' steht für '''d'''igit (ganzzahlige Formatierung).
+
* nach dem '''%'''-Zeichen steht der ''Typbezeichner'': '''%d''' steht für '''d'''ecimal (ganzzahlige Ausgabe).
 
** ''%s'' für Zeichenketten
 
** ''%s'' für Zeichenketten
 
** ''%f'' für Fließkommazahlen
 
** ''%f'' für Fließkommazahlen
Zeile 52: Zeile 52:
 
  int main(int argc, char **argv)   
 
  int main(int argc, char **argv)   
 
  {  
 
  {  
   '''int iSumOfSquares = 1 + 9 + 8 + 5;'''
+
   '''int iSumOfDigits = 1 + 9 + 8 + 5;'''
   printf("Hello World! Some Number: %d\n", '''iSumOfSquares''');
+
   printf("Hello World! Some Number: %d\n", '''iSumOfDigits''');
 
   return 0;
 
   return 0;
 
  }
 
  }
  
 
* '''''Frage:'' Was ist das Ergebnis? Warum?'''
 
* '''''Frage:'' Was ist das Ergebnis? Warum?'''
* '''''Antwort:'' Hello World! Some Number: 42'''
+
* '''''Antwort:'' Hello World! Some Number: 23'''
 +
 
 +
 
 +
 
 +
 
 +
== Formatierung ==
 +
* ''%5d'' für 5 Zahlen mindestens
 +
* ''%05d'' für 5 Zahlen mindestens, aufgefüllt mit Nullen
 +
* ''%-5d'' für 5 Zahlen mindestens, linksbündig
 +
* ''%-5.2f'' für 5 Zahlen mindestens, linksbündig, auf zwei Nachkommastellen gerundet
  
* Formatierung
 
** ''%5d'' für 5 Zahlen mindestens
 
** ''%05d'' für 5 Zahlen mindestens, aufgefüllt mit Nullen
 
** ''%-5d'' für 5 Zahlen mindestens, linksbündig
 
** ''%-5.2f'' für 5 Zahlen mindestens, linksbündig, genau 2 Nachkommastellen
 
  
 
'''''Beispiel (An Tafel/Laptop)'''''
 
'''''Beispiel (An Tafel/Laptop)'''''
 
  char pcName[255];
 
  char pcName[255];
  strcpy(pcName,"Mario");// #include <string.h><br>
+
  strcpy(pcName,"Mario");// #include <string.h> + ''richtige'' Art der Zuweisung für konstanten Inhalt<br>
 
  unsigned uiAge = 26u;
 
  unsigned uiAge = 26u;
  float fHeight=1.83f;
+
  float fHeight=1.83f;<br>
float fPi = 3.1459f;<br>
 
 
  printf("%s ist %5.0fm hoch und %05d Jahre alt\n", pcName, fHeight, uiAge);
 
  printf("%s ist %5.0fm hoch und %05d Jahre alt\n", pcName, fHeight, uiAge);
 
  printf("%s ist %-5.1fm hoch und %-05d Jahre alt\n", pcName, fHeight, uiAge);<br>
 
  printf("%s ist %-5.1fm hoch und %-05d Jahre alt\n", pcName, fHeight, uiAge);<br>
  
'''''Frage: '' Was ist das Ergebnis? Warum?'''
+
'''''Frage: '' Wie sieht die Ausgabe aus? Warum?'''<br>
 +
'''''Antwort: '''''
 
  Mario ist    2m hoch und 00026 Jahre alt
 
  Mario ist    2m hoch und 00026 Jahre alt
 
  Mario ist 1.8  m hoch und 26    Jahre alt
 
  Mario ist 1.8  m hoch und 26    Jahre alt
 +
  
  
 
= Eingabe =
 
= Eingabe =
  
* scanf wie printf
+
* ''scanf'' ähnlich zu ''printf''
 
* liest stets von der Kommandozeile
 
* liest stets von der Kommandozeile
  
Zeile 88: Zeile 93:
 
  int main(int argc, char **argv)   
 
  int main(int argc, char **argv)   
 
  {  
 
  {  
  char pcName[255]; // Verschiebung der Eklärung auf späteres Tutorium.
 
 
   unsigned int uiAge;
 
   unsigned int uiAge;
   '''printf("Name: ");'''
+
   '''printf("Alter: ");''' // Ausgabe vor der Eingabe ...
   '''scanf("%s", &pcName);''' // '''&''': Adressoperator, kommt später, immer mitnehmen!
+
   '''scanf("%d", &uiAge);''' // '''&''': Adressoperator, kommt später, immer mitnehmen!
  '''printf("Alter: ");'''
+
   printf("Du bist %d Jahre alt.\n", uiAge);
  '''scanf("%d", &uiAge);'''
 
   printf("%s ist %d Jahre alt.\n", pcName, uiAge);
 
 
   return 0;
 
   return 0;
 
  }
 
  }
Zeile 100: Zeile 102:
  
  
= Fehlerfälle =
+
== Fehlerhafte Eingabe ==
 +
 
 +
'''''Frage:'' Welchen Wert hat ''uiAge'' wenn ''A'' eingegeben wurde?'''<br>
 +
'''Antwort:''' ''0'' und keine Fehlermeldung. Daher: Stets prüfen, ob Konvertierung möglich war.
  
'''''Frage:'' Was passiert, wenn ''"A"'' als Alter angegeben wird?'''<br>
+
* Rückgabewert von ''scanf'' gibt Anzahl der erfolgreich gelesenen '''%'''-Zeichenketten zurück
'''Antwort:''' Nix! Keine Fehlermeldung, etc. Stets selber überprüfen!
+
* '''0''' bedeutet, keine erfolgreiche Konvertierung möglich ...
* Rückgabewert von ''scanf'' gibt Anzahl der erfolgreich gelesenen '''%?'''-Zeichenketten zurück
 
* ''0'' bedeutet, keine erfolgreiche Konvertierung möglich ...
 
  
 
  #include <stdio.h><br>
 
  #include <stdio.h><br>
 
  int main(int argc, char **argv)   
 
  int main(int argc, char **argv)   
 
  {
 
  {
  char pcName[255];
 
 
   unsigned int uiAge;
 
   unsigned int uiAge;
  printf("Name: ");
 
  scanf("%s", &pcName);<br>
 
 
   printf("Alter: ");
 
   printf("Alter: ");
 
   if( 1 != scanf("%d", &uiAge) )
 
   if( 1 != scanf("%d", &uiAge) )
Zeile 129: Zeile 129:
  
 
Ein und Ausgabe in Dateien: Schrittfolge zum Dateibearbeiten:
 
Ein und Ausgabe in Dateien: Schrittfolge zum Dateibearbeiten:
# Datei öffnen '''FILE fOpenedFile = fopen( ''FILE_PATH'', ''MODE'');'''
+
# Datei öffnen '''FILE *pOpenedFile = fopen( ''FILE_PATH'', ''MODE'');'''
 
#* ''FILE_PATH'' = "/usr/share/.."
 
#* ''FILE_PATH'' = "/usr/share/.."
#* ''MODE'' = '''r'''ead, '''w'''rite oder
+
#* ''MODE''
#**'''w+''' (write+read) lesen und schreiben, Dateiinhalt wird dabei auf gelöscht
+
#** '''r'''ead (nur lesend, bricht ab bei nicht existenter Datei)
#**'''r+''' (read+write) lesen und schreiben, Dateiinhalt bleibt erhalten
+
#** '''w'''rite (nur schreibend, erzeugt Datei, schreibt von Anfang)
#* '''fOpenedFile''' muss ungleich NULL sein, wenn Datei geöffnet werden konnte
+
#** '''a'''ppend (nur schreibend, schreibt ans Ende)
 +
#** '''r+''' (read+write) lesen und schreiben, Dateiinhalt bleibt erhalten
 +
#** '''w+''' (write+read) lesen und schreiben, Dateiinhalt wird gelöscht
 +
#** '''a+''' (append+read) vom Dateianfang lesen und ans Ende schreiben
 +
#* '''pOpenedFile''' muss ungleich '''NULL''' sein, wenn Datei geöffnet werden konnte
 
# Datei bearbeiten
 
# Datei bearbeiten
 
#* Schreiben:
 
#* Schreiben:
#** '''f'''printf( fOpenedFile, ''FORMAT_STRING''[, ''TYPES'']*);
+
#** '''f'''printf( pOpenedFile, ''FORMAT_STRING''[, ''TYPES'']*);
 
#** ''FORMAT_STRING'' und ''TYPES'', wie bei printf!
 
#** ''FORMAT_STRING'' und ''TYPES'', wie bei printf!
 
#* Lesen:
 
#* Lesen:
#** '''f'''scanf( fOpenedFile,  ''FORMAT_STRING''[, &''TYPES'']*);
+
#** '''f'''scanf( pOpenedFile,  ''FORMAT_STRING''[, &''TYPES'']*);
 
#** ''FORMAT_STRING'' und ''TYPES'', wie bei scanf!
 
#** ''FORMAT_STRING'' und ''TYPES'', wie bei scanf!
# Datei schließen (Sonst kann Windows die Datei nicht in anderen Programmen lesen ...)
+
#** Testen ob Dateiende: '''feof(pOpenedFile)'''
#* '''fclose( fOpenedFile );'''
+
#*** Wenn Rückgabe != 0 wurde Dateiende erreicht
 +
# Datei schließen (Sonst kann die Datei nicht erneut geöffnet werden)
 +
#* '''fclose( pOpenedFile );'''
  
'''''Frage:'' Wie lese ich die existierende ''/tmp/sample.txt'' ein?'''<br>
+
 
 +
= Komplexe Aufgabe =
 +
'''''Aufgabe:'' Lese eine Datei mit folgendem Inhalt ein und füge am Ende der Datei die Summe aller Elemente hinzu.'''<br>
 +
<pre>
 +
1 2 3
 +
4 5 6
 +
7 8 9
 +
</pre>
 +
(Summe = 45)
  
 
'''''Antwort:'''''
 
'''''Antwort:'''''
#include <stdio.h><br>
+
<pre>
int main(int argc, char **argv)
+
#include <stdio.h>
{
+
int main(int argc, char **argv)
  // Schritt 1: Öffnen
+
{
  FILE* pOpenendFile = fopen("/tmp/sample.txt", "r+");
+
  // Schritt 1: Öffnen
  if( NULL == pOpenendFile )
+
  FILE *pOpenFile = fopen("/tmp/sample.txt", "a+");
  {
+
  if( NULL == pOpenFile )
        printf("Konnte Datei nicht öffnen!\n");
+
  {
        return -1;
+
    printf("Konnte Datei nicht öffnen!\n");
  }<br>
+
    return -1;
  // Schritt 2: Bearbeiten (lesen)
+
  }
  char pcFileEntry[255];
+
 
  if( 0 >= fscanf(pOpenendFile, "%s", &pcFileEntry) )
+
  // Schritt 2a: Bearbeiten (lesen)
  {
+
  int iSum = 0;
        printf("Konnte Datei nicht lesen!\n");
+
  while( feof( pOpenFile ) == 0 )
  }
+
  {
  else
+
    int iReadDecimal = 0;
  {
+
    if( 1 == fscanf(pOpenFile, "%d", &iReadDecimal) )
        printf("Inhalt gelesen: \"%s\"\n", pcFileEntry);
+
    {
  }<br>
+
      iSum+=iReadDecimal;
  // Schritt 2: Bearbeiten (schreiben)
+
      printf("Wert gelesen: \"%d\"\nAktuelle Summe: %d\n\n", iReadDecimal, iSum);
  if( 0 == fprintf(pOpenendFile, "FileRead!\n") )
+
    }
  {
+
    else
        printf("Inhalt der Datei konnte nicht verändert werden\n");
+
    {
  }
+
      printf("Wert konnte nicht gelesen werden ...\n");
  else
+
    }
  {
+
  }
        printf("Datei wurde erfolgreich beschrieben!\n");
 
  }<br>
 
  // Schritt 3: Datei Schließen
 
  fclose(pOpenendFile);
 
}
 
  
 +
  // Schritt 2b: Bearbeiten (schreiben)
 +
  printf("Hänge Ergebnis %d ans Ende der Datei an.\n", iSum);
 +
  if( 0 == fprintf(pOpenFile, "%d\n", iSum) )
 +
  {
 +
    printf("Inhalt der Datei konnte nicht verändert werden\n");
 +
  }
 +
  else
 +
  {
 +
    printf("Datei wurde erfolgreich beschrieben!\n");
 +
  }
  
 +
  // Schritt 3: Schließen
 +
  fclose(pOpenFile);
 +
  return 0;
 +
}
  
 +
</pre>
  
 
= ENDE =
 
= ENDE =
  
 
Empfohlene Aufgabe: '''Taschenrechner''' + '''Kassenbon?'''
 
Empfohlene Aufgabe: '''Taschenrechner''' + '''Kassenbon?'''

Version vom 5. September 2011, 20:45 Uhr

CKurs - Ein und Ausgabe

- DRAFT -
  • Kommentare im Code sind Infos zum Erzählen.
  • Fett: Fragen an Publikum/Im Code: Ergänzung zum letzten Listings ...



Wiederholung

Durch Studis zu ergänzen HelloWorld-Programm an die Tafel

#include <stdio.h> // Einbinden des Headers der IO-Lib
int main(int argc, char **argv) // Haupteinsprungspunkt { // Scope erwähnen? // Platz für Variablen lassen printf("Hello World!\n"); // Kurz: \n => newline, folgende Ausgabe in der nächsten Zeile return 0; }
  • \n für eine Zeilenende
  • \" für ein "-Symbol
  • \\ für ein \-Symbol (Windows-Pfadtrenner)


dynamische Ausgabe

(Ausgabe an Tafel/Laptop)

#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World! Some Number: %d\n", 42); // Wichtig: Komma erwähnen! return 0; }
  • printf benutzt das %-Zeichen zur Markierung welcher Teil des Textes ersetzt werden muss.
  • nach dem %-Zeichen steht der Typbezeichner: %d steht für decimal (ganzzahlige Ausgabe).
    • %s für Zeichenketten
    • %f für Fließkommazahlen
    • %% für %


Variablen

  • bisher: keine Verbesserung, da %d auch einfach direkt 42 sein könnte ...
  • Nutzbar auch für Variablen: (Frage: Was ist eine Variable?)
#include <stdio.h>
int main(int argc, char **argv) { int iSumOfDigits = 1 + 9 + 8 + 5; printf("Hello World! Some Number: %d\n", iSumOfDigits); return 0; }
  • Frage: Was ist das Ergebnis? Warum?
  • Antwort: Hello World! Some Number: 23



Formatierung

  • %5d für 5 Zahlen mindestens
  • %05d für 5 Zahlen mindestens, aufgefüllt mit Nullen
  • %-5d für 5 Zahlen mindestens, linksbündig
  • %-5.2f für 5 Zahlen mindestens, linksbündig, auf zwei Nachkommastellen gerundet


Beispiel (An Tafel/Laptop)

char pcName[255];
strcpy(pcName,"Mario");// #include <string.h> + richtige Art der Zuweisung für konstanten Inhalt
unsigned uiAge = 26u; float fHeight=1.83f;
printf("%s ist %5.0fm hoch und %05d Jahre alt\n", pcName, fHeight, uiAge); printf("%s ist %-5.1fm hoch und %-05d Jahre alt\n", pcName, fHeight, uiAge);

Frage: Wie sieht die Ausgabe aus? Warum?
Antwort:

Mario ist     2m hoch und 00026 Jahre alt
Mario ist 1.8  m hoch und 26    Jahre alt


Eingabe

  • scanf ähnlich zu printf
  • liest stets von der Kommandozeile
#include <stdio.h>
int main(int argc, char **argv) { unsigned int uiAge; printf("Alter: "); // Ausgabe vor der Eingabe ... scanf("%d", &uiAge); // &: Adressoperator, kommt später, immer mitnehmen! printf("Du bist %d Jahre alt.\n", uiAge); return 0; }


Fehlerhafte Eingabe

Frage: Welchen Wert hat uiAge wenn A eingegeben wurde?
Antwort: 0 und keine Fehlermeldung. Daher: Stets prüfen, ob Konvertierung möglich war.

  • Rückgabewert von scanf gibt Anzahl der erfolgreich gelesenen %-Zeichenketten zurück
  • 0 bedeutet, keine erfolgreiche Konvertierung möglich ...
#include <stdio.h>
int main(int argc, char **argv) { unsigned int uiAge; printf("Alter: "); if( 1 != scanf("%d", &uiAge) ) { printf("Konnte das Alter nicht lesen!\n"); return -1; }
printf("%s ist %d Jahre alt\n", pcName, uiAge); return 0; }


Dateien

Ein und Ausgabe in Dateien: Schrittfolge zum Dateibearbeiten:

  1. Datei öffnen FILE *pOpenedFile = fopen( FILE_PATH, MODE);
    • FILE_PATH = "/usr/share/.."
    • MODE
      • read (nur lesend, bricht ab bei nicht existenter Datei)
      • write (nur schreibend, erzeugt Datei, schreibt von Anfang)
      • append (nur schreibend, schreibt ans Ende)
      • r+ (read+write) lesen und schreiben, Dateiinhalt bleibt erhalten
      • w+ (write+read) lesen und schreiben, Dateiinhalt wird gelöscht
      • a+ (append+read) vom Dateianfang lesen und ans Ende schreiben
    • pOpenedFile muss ungleich NULL sein, wenn Datei geöffnet werden konnte
  2. Datei bearbeiten
    • Schreiben:
      • fprintf( pOpenedFile, FORMAT_STRING[, TYPES]*);
      • FORMAT_STRING und TYPES, wie bei printf!
    • Lesen:
      • fscanf( pOpenedFile, FORMAT_STRING[, &TYPES]*);
      • FORMAT_STRING und TYPES, wie bei scanf!
      • Testen ob Dateiende: feof(pOpenedFile)
        • Wenn Rückgabe != 0 wurde Dateiende erreicht
  3. Datei schließen (Sonst kann die Datei nicht erneut geöffnet werden)
    • fclose( pOpenedFile );


Komplexe Aufgabe

Aufgabe: Lese eine Datei mit folgendem Inhalt ein und füge am Ende der Datei die Summe aller Elemente hinzu.

1 2 3 
4 5 6
7 8 9

(Summe = 45)

Antwort:

#include <stdio.h>
int main(int argc, char **argv)
{
  // Schritt 1: Öffnen
  FILE *pOpenFile = fopen("/tmp/sample.txt", "a+");
  if( NULL == pOpenFile )
  {
    printf("Konnte Datei nicht öffnen!\n");
    return -1;
  }

  // Schritt 2a: Bearbeiten (lesen)
  int iSum = 0;
  while( feof( pOpenFile ) == 0 )
  {
    int iReadDecimal = 0;
    if( 1 == fscanf(pOpenFile, "%d", &iReadDecimal) )
    {
      iSum+=iReadDecimal;
      printf("Wert gelesen: \"%d\"\nAktuelle Summe: %d\n\n", iReadDecimal, iSum);
    }
    else
    {
      printf("Wert konnte nicht gelesen werden ...\n");
    }
  }

  // Schritt 2b: Bearbeiten (schreiben)
  printf("Hänge Ergebnis %d ans Ende der Datei an.\n", iSum);
  if( 0 == fprintf(pOpenFile, "%d\n", iSum) )
  {
    printf("Inhalt der Datei konnte nicht verändert werden\n");
  }
  else
  {
    printf("Datei wurde erfolgreich beschrieben!\n");
  }

  // Schritt 3: Schließen
  fclose(pOpenFile);
  return 0;
}

ENDE

Empfohlene Aufgabe: Taschenrechner + Kassenbon?