Beispielprogramme in C/Strukturiertes Programmieren mit C
Aus C64-Wiki
Zur Navigation springenZur Suche springenLeicht erweiterte C-Version des Beispiels im Artikel Strukturiertes Programmieren mit BASIC
/* Program: struct.c (cough cough) URL: http://www.c64-wiki.de/index.php/Strukturiertes_Programmieren_mit_BASIC Compiler: cc65, gcc 100 INPUT "NAME DES 1. KANDIDATEN "; A$ 110 INPUT "STIMMENANZAHL "; A 120 INPUT "NAME DES 2. KANDIDATEN "; B$ 130 INPUT "STIMMENANZAHL "; B 140 INPUT "NAME DES 3. KANDIDATEN "; C$ 150 INPUT "STIMMENANZAHL "; C 160 LET S = A+B+C 170 LET A1 = A*100/S 180 LET B1 = B*100/S 190 LET C1 = C*100/S 200 PRINT "KANDIDAT ";A$; " ERHIELT";A1;"%" 210 PRINT "KANDIDAT ";B$; " ERHIELT";B1;"%" 220 PRINT "KANDIDAT ";C$; " ERHIELT";C1;"%." */ #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> struct Kandidat_s { uint8_t Name[200]; uint32_t Stimmen; }; struct Kandidat_s Kandidat; struct Kandidat_s *Kandidat_p; uint8_t String[200]; uint16_t anzahlKandidaten, Zaehler; uint32_t abgegebeneStimmen = 0; void p_reset() { for (Zaehler = 0; Zaehler < anzahlKandidaten; ++Zaehler) --Kandidat_p; } void aufraeumen() { p_reset(); free(Kandidat_p); } void KandidatenEingabe(uint16_t Zaehler, struct Kandidat_s *Kandidat_p) { printf("\r\nName des %d. Kandidaten? ", Zaehler+1); fgets(String, 200, stdin); String[strcspn ( String, "\n\r" )] = '\0'; strcpy(Kandidat_p->Name, String); printf("\r\nStimmenanzahl? "); fgets(String, 16, stdin); Kandidat_p->Stimmen = atol(String); abgegebeneStimmen += Kandidat_p->Stimmen; } void Stimmerfassung() { printf("\r\nAnzahl der Kandidaten: "); fgets( String, 3, stdin ); anzahlKandidaten = (uint8_t) atoi(String); Kandidat_p = malloc(anzahlKandidaten * sizeof(Kandidat)); for (Zaehler = 0; Zaehler < anzahlKandidaten; ++Zaehler) { KandidatenEingabe(Zaehler, Kandidat_p); ++Kandidat_p; } } void Stimmauszaehlung() { p_reset(); printf("\r\nAbgegebene Stimmen %ld: \r\n",abgegebeneStimmen); for (Zaehler = 0; Zaehler < anzahlKandidaten; ++Zaehler) { printf("Kandidat %s erhielt %ld%%\r\n", Kandidat_p->Name, Kandidat_p->Stimmen*100/abgegebeneStimmen); ++Kandidat_p; } } void main(void) { Stimmerfassung(); Stimmauszaehlung(); aufraeumen(); }
Nochmal etwas erweitertes Beispiel mit Fehlerbehandlung, sortierter Kandidatenausgabe und Prozentausgabe mit einer Nachkommastelle:
/** * Beispiel eines Stimmenauszähl-Programms. * * Die Anzahl der Kandidaten ist flexibel — der Speicher wird zur * Laufzeit verwaltet. * * Es wird gezeigt, wie man auch ohne Gleitkommatypen Prozentzahlen mit * einer Nachkommastalle realisieren kann. * * Ferner werden die Kandidaten vor der Ausgabe absteigend nach Stimmen * sortiert. * * Ausserdem wurde versucht, auf Fehleingaben vom Benutzer zu reagieren, * damit das Programm nicht abstürzt oder unsinnige Werte anzeigt. * * \TODO Es wird nicht überprüft, ob ein eingegebener Name leer ist oder * bereits in den Kandidaten enthalten ist. */ #include <assert.h> #include <inttypes.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LENGTH 100 /* * Die Stimmen werden mit 1000 multipliziert, um eine Nachkommastelle * zu bekommen, deshalb darf die Anzahl pro Kandidat nicht so gross werden, * dass dadurch ein Überlauf entsteht. */ #define MAX_STIMMEN_PRO_KANDIDAT (INT32_MAX / 1000) #if ((INT32_MAX / MAX_STIMMEN_PRO_KANDIDAT) < 256) #error "Aufsummieren koennte zu Ueberlauf von Gesamtstimmen fuehren" #endif typedef int (*compare_func_t)(const void*, const void*); /** * \invariant stimmen <= MAX_STIMMEN_PRO_KANDIDAT */ typedef struct { char name[MAX_NAME_LENGTH]; int32_t stimmen; } Kandidat; typedef struct { uint8_t anzahl; Kandidat *data; } Kandidaten; void remove_trailing_newline(char *s) { char *ptr = s + strlen(s); if (ptr != s && ptr[-1] == '\n') ptr[-1] = '\0'; } int Kandidat_compare(const Kandidat *a, const Kandidat *b) { int32_t result = b->stimmen - a->stimmen; if (!result) return strcmp(a->name, b->name); return result < 0 ? -1 : 1; } Kandidaten* Kandidaten_init(Kandidaten *kandidaten, uint8_t anzahl) { if ((kandidaten->data = calloc(anzahl, sizeof(*kandidaten->data)))) { kandidaten->anzahl = anzahl; return kandidaten; } else { kandidaten->anzahl = 0; return NULL; } } void Kandidaten_free(Kandidaten *kandidaten) { assert(kandidaten); kandidaten->anzahl = 0; free(kandidaten->data); } _Bool Kandidaten_eingabe(Kandidaten *kandidaten) { uint8_t i; int16_t anzahl; int32_t stimmen; Kandidat *kandidat; char buffer[20]; assert(kandidaten); printf("Anzahl der Kandidaten: "); fgets(buffer, sizeof(buffer), stdin); anzahl = atoi(buffer); putchar('\n'); if (anzahl < 1) { puts("Weniger als 1 Kandidat ist sinnlos."); return false; } if (!Kandidaten_init(kandidaten, anzahl)) { puts("Konnte Kandidaten nicht initialisieren."); return false; } for (i = 0; i < kandidaten->anzahl; ++i) { kandidat = &kandidaten->data[i]; printf("\nName des %d. Kandidaten: ", i + 1); fgets(kandidat->name, sizeof(kandidat->name), stdin); remove_trailing_newline(kandidat->name); while (true) { printf("\nStimmenanzahl: "); fgets(buffer, sizeof(buffer), stdin); stimmen = atol(buffer); if (stimmen < 0) { puts("\nStimmanzahl muss >=0 sein!"); continue; } if (stimmen > MAX_STIMMEN_PRO_KANDIDAT) { printf( "\nPro Kandidat max %"PRIu32" Stimmen!", MAX_STIMMEN_PRO_KANDIDAT ); continue; } kandidat->stimmen = stimmen; break; } putchar('\n'); } return true; } void Kandidaten_sort(Kandidaten *kandidaten) { assert(kandidaten); qsort( kandidaten->data, kandidaten->anzahl, sizeof(*kandidaten->data), (compare_func_t) Kandidat_compare ); } void Kandidaten_auswerten(Kandidaten *kandidaten) { uint8_t i; int32_t stimmen, gesamt_stimmen; div_t percent; Kandidat *kandidat; assert(kandidaten); for (i = 0; i < kandidaten->anzahl; ++i) { stimmen = kandidaten->data[i].stimmen; assert(stimmen <= MAX_STIMMEN_PRO_KANDIDAT); gesamt_stimmen += stimmen; } assert(gesamt_stimmen >= 0); printf("\nAbgegebene Stimmen: %"PRIu32"\n", gesamt_stimmen); if (gesamt_stimmen) { Kandidaten_sort(kandidaten); for (i = 0; i < kandidaten->anzahl; ++i) { kandidat = &kandidaten->data[i]; percent = div(kandidat->stimmen * 1000 / gesamt_stimmen, 10); assert( percent.quot >= 0 && percent.quot <= 100 && percent.rem >= 0 && percent.rem <= 9 ); printf( " %2d.%01d%% fuer %s\n", percent.quot, percent.rem, kandidat->name ); } } } int main(void) { Kandidaten kandidaten; if (Kandidaten_eingabe(&kandidaten)) { Kandidaten_auswerten(&kandidaten); Kandidaten_free(&kandidaten); } return 0; }