C-Kurs/Zahlen sagen/Musterlösung
< C-Kurs | Zahlen sagen
Version vom 23. September 2009, 08:08 Uhr von 130.149.242.150 (Diskussion) (Die Seite wurde neu angelegt: „<pre> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <limits.h> →* Größe des Puffers für den Ergebnisstring: #define...“)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <limits.h>
/** Größe des Puffers für den Ergebnisstring */
#define BUFFER_SIZE 1000
/** Einerstellen zur allgemeinen Zusammensetzung. */
const char* EINER[] = {NULL, "eins", "zwei", "drei", "vier",
"fünf", "sechs", "sieben", "acht", "neun"};
/** Zehnerstellen zur allgemeinen Zusammensetzung */
char* ZEHNER[] = {NULL, "zehn", "zwanzig", "dreißig", "vierzig",
"fünfzig", "sechzig", "siebzig", "achtzig", "neunzig"};
/** Anzahl der vorhandenen Ausnahmen */
#define ANZAHL_AUSNAHMEN 18
/** Ausnahmen, die sich nicht zusammensetzen lassen. */
char* AUSNAHMEN[] =
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"elf", "zwölf", NULL, NULL, NULL, "sechzehn", "siebzehn"};
/** Anzahl der vorhandenen 1000er-Potenzen */
#define ANZAHL_POTENZEN 4
/** 1000er-Potenzen in ihrer Einzahl */
char* POTENZEN_SINGULAR[] = {"", "tausend", " Million ", " Milliarde ", " Billion "};
/** 1000er-Potenzen in ihrer Mehrzahl */
char* POTENZEN_PLURAL[] = {"", "tausend", " Millionen ", " Milliarden ", " Billionen "};
/**
* Kopiert die übergebene Zahl 0 < x < 1000 als Zahlwort
* in den übergebenen Puffer.
*/
void say_short_number(long int x, char *buffer, int bufsize) {
/* Hunderterstelle ausrechnen */
int hunderter = x/100;
if (hunderter > 0) {
/* an den Pufferstring anhängen */
if (hunderter == 1) {
/* Ausnahme: "einhundert" statt "einshundert" */
strncat(buffer, "ein", bufsize-strlen(buffer)-1);
} else {
strncat(buffer, EINER[hunderter], bufsize-strlen(buffer)-1);
}
strncat(buffer, "hundert", bufsize-strlen(buffer)-1);
/* Hunderterstelle entfernen */
x %= 100;
}
if ((x < ANZAHL_AUSNAHMEN) && (AUSNAHMEN[x] != NULL)) {
/* eine Ausnahme wie "zwölf", oder */
strncat(buffer, AUSNAHMEN[x], bufsize - strlen(buffer) - 1);
} else {
/* Rest aus Einer- und Zehnerstelle zusammensetzen */
int zehner = x/10, einer = x%10;
if (einer > 0)
strncat(buffer, EINER[einer], bufsize - strlen(buffer) - 1);
if (zehner > 0) {
if ((zehner > 1) && (einer > 0))
strncat(buffer, "und", bufsize - strlen(buffer) - 1); /* ab 20 ein "und" einfügen */
strncat(buffer, ZEHNER[zehner], bufsize - strlen(buffer) - 1);
}
}
}
/**
* Generiert die natürlichsprachliche Repräsentation (Zahlwort) der
* übergebenen Zahl und kopiert diese in den angegebenen Puffer.
*/
void say_number(long int x, char* buffer, int bufsize) {
int i;
/* Der Null kommt wie immer eine Sonderbehandlung zugute */
if (x == 0) {
strncat(buffer, "null", bufsize - strlen(buffer) - 1);
return;
}
/* Alle relevanten 1000er-Potenzen durchgehen */
for (i=ANZAHL_POTENZEN-1; i>=0; i--) {
/* Potenz für relevante Stellen ausrechnen */
long int power = floor(pow(10, i*3) + 0.5);
/* Stellen für diese Potenz extrahieren */
int value = x/power;
if (value > 0) {
if ((value == 1) && (i >= 1)) {
if (i == 1) {
/* Ausnahme: "eintausend" statt "einstausend" */
strncat(buffer, "ein", bufsize - strlen(buffer) - 1);
} else {
/* Ausnahme: "eine Million" etc. statt "eins Million" */
strncat(buffer, "eine", bufsize - strlen(buffer) - 1);
}
/* Einzahl von Million etc. berücksichtigen */
strncat(buffer, POTENZEN_SINGULAR[i], bufsize - strlen(buffer) - 1);
} else {
say_short_number(value, buffer, bufsize);
strncat(buffer, POTENZEN_PLURAL[i], bufsize - strlen(buffer) - 1);
}
/* bereits ausgegebene Stellen abschneiden */
x %= power;
}
}
}
int main(int argc, char **argv) {
long int number;
char *buffer;
/* überprüfen, ob notwendige Kommandozeilenparameter angegeben wurden */
if (argc != 2) {
printf("Usage: %s NUMBER", argv[0]);
exit(1);
}
/* numerischen String zu Ganzzahl konvertieren */
number = atol(argv[1]);
if (number <= 0 || number == LONG_MAX) {
printf("Invalid number.\n");
exit(1);
}
/* Puffer für Ergebnisstring allozieren */
buffer = malloc(BUFFER_SIZE);
if (!buffer) {
printf("Unable to allocate memory.\n");
exit(1);
}
/* Speicher mit Nullbyte initialisieren (= leerer String) */
buffer[0] = '\0';
/* Zahlwort in den Puffer schreiben */
say_number(number, buffer, BUFFER_SIZE);
/* und ausgeben */
printf("%s\n", buffer);
/* Speicher freigeben */
free(buffer);
/* Alles ok, Fehlercode 0 */
return 0;
}