PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Funktionen in C89



sesam
14-01-2007, 20:29
Hallo.
Ich habe folgendes Problem: Wenn ich folgenden Code ausführe, fragt mich das Programm nur nach der ersten Eingabe und nimmt für die zweite Eingabe automatisch einen Eingabewert an bzw. lässt keine zweite Eingabe zu.

Was ist an dem Code falsch bzw. wie löse ich dasProblem eleganter?
Es darf nur der C89-Standard verwendet werden.


#include <stdio.h>
#include <string.h>
#define N 2

void eingabe(char *zz1){
scanf("%[0123456789abcdefABCDEF]", zz1);
}


// ***************************** main ******************************
int main()
{
char z1[20], z2[20];

printf("\n\n");

printf("\n\n \t Programm 1 \n\n");

printf("Bitte eine %d-stellige Hex-zahl eingeben: ",N);
eingabe(z1);
printf("\nlänge: %i\n",strlen(z1));
if(strlen(z1) != N)
{
printf("Falsche Eingabe. Ende.\n\n");
exit(1);
}
printf("Bitte eine %d-stellige Hex-zahl eingeben: ",N);
eingabe(z2);
printf("\nlänge: %i\n",strlen(z2));

if(strlen(z1) != N)
{
printf("Falsche Eingabe2. Ende.\n\n");
exit(1);
}

printf("Ende.\n\n");
return 0;
}

jeebee
15-01-2007, 22:14
das drücken der Entertaste ('\n' Linux; '\r\n' Windows) mit fgetc(stdin); (Linux); resp fgetc(stdin);fgetc(stdin); (Windows) abfangen und vergessen. Sonst liest dein Programm das Drücken der Enter-Taste als 2. Zahl ein.

peschmae
15-01-2007, 23:10
1) Wenn du die Funktion exit() verwenden willst darfst du nicht vergessen stdlib.h zu includen. Oder einfach return verwenden - du bist ja in main().
Eine nicht deklarierte Funktion zu verwenden ist in C eine sehr schlechte Idee - das kann nämlich kompiliert werden. Der Compiler "nimmt" einfach eine Funktion mit int als Rückgabewert und keinem Argument an - wenn die entsprechende Funktion was anderes ist läuft das nur zufälligerweise. GCC sagt dir das sogar, wenn du das Programm mit -Wall kompilierst:


peschmae@sid:/tmp$ gcc -Wall test.c -o test
test.c: In Funktion »main«:
test.c:25: Warnung: Implizite Deklaration der Funktion »exit«
test.c:25: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »exit«
test.c:34: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »exit«
peschmae@sid:/tmp$


2) scanf() auf diese Art und weise zu verwenden ist überhaupt gar nicht sicher und eine sehr schlechte Idee. Du kannst nicht verhindern dass ein Benutzer mehr als 30 Zeichen (oder wie gross dein Buffer auch immer ist) eingibt - es kommt zu einem Bufferüberlauf, der im besten Fall dein Programm zum abstürzen bringt.
Besser: Die Funktion fgets() verwenden um maximal so viele Zeichen zu lesen wie der Buffer Platz für hat und anschliessend die Daten mit sscanf() analysieren.
Damit bist du dann gleich auch noch dein ursprüngliches Problem los - fgets liest nämlich bis und mit dem nächsten Zeilenumbruch.

MfG Peschmä

sesam
16-01-2007, 10:46
Vielen Dank für die Hilfe. :-)

Ich habe jetzt die Tipps umgesetzt und es funktioniert soweit. Damit kann ich dann schonmal weiterprogrammieren.
Ich habe jetzt folgenden Code:



int main()
{
void exit(int exit_code);
char zz1[20], zz2[20];
// int add1, add2, sum;

printf("\n\n");

printf("\n\n \t Prog1 \n\n");
printf("Bitte eine %d-stellige Hex-zahl eingeben: ",N);
gets(zz1);
sscanf("%[0123456789abcdefABCDEF]", zz1);
printf("\nlänge: %i\n",strlen(zz1));
if(strlen(zz1) != N)
{
printf("Falsche Eingabe. Ende.\n\n");
exit(1);
}
printf("Bitte eine %d-stellige Hex-zahl eingeben: ",N);
gets(zz2);
scanf("%[0123456789abcdefABCDEF]", zz2);
printf("\nlänge: %i\n",strlen(zz2));

if(strlen(zz2) != N)
{
printf("Falsche Eingabe2. Ende.\n\n");
exit(1);
}
printf("Zahl1: %c \n", *zz1);
printf("Zahl2: %c \n", *zz2);
printf("ende.");
return 0;
}


Ich brauche am Ende des Codefragments die 2 Eingaben zz1 und zz2, die ich dann manuell in Dezimalzahlen umwandeln muss (um sie dann manuell mittels Übertrag zu addieren und wieder in hex umzuwandeln und ergebnis auszugeben).

Wenn obiges noch eleganter/sicherer gelöst werden kann und hier postet, bin ich sehr dankbar dafür.