?
Ich möchte folgende "Lösung" zur Diskussion stellen. Sie ist nicht direkt zum Abtippen für die aktuelle Frage gedacht, weil sie
- Keine Datei mit mehreren Datensätzen einliest (ich war zu faul dazu), sondern eine Präprozessor-Konstante benutzt, mit der ich einfach besser testen kann.
- Ich mich immer ein wenig wundere, warum die neuen, sicheren Funktionen nicht eingesetzt werden.
- Ich einfach noch mehr verschiedene Datentypen testen wollte. Für Verbund im Verbund (Datum) ist mir nichts besseres eingefallen.
/*U0358_Einlesen : Definiert den Einstiegspunkt der Konsolenanwendung*/
/* direktes Einlesen eines Verbundes*/
#include <stdio.h>
#include <stdlib.h> /*fuer: system*/
//#include <string.h> /*fuer spaeter*/
#ifdef __cplusplus
#define KOMPILERMODUS "mit C++"
#else
#define KOMPILERMODUS "mit C"
#endif
#pragma message(KOMPILERMODUS)
/*Hier einfach experimentieren*/
#define EINGABETEXT "Hans567890123456789012345;Mustermann;10001;Berlin;m;01.12.2013" /*Pufferueberlauf in den Nachnamen*/
//#define EINGABETEXT "Hans5678901234567890;Mustermann;10001;Berlin;m;01.12.2013"
//#define SICHER
struct sDatum {
char strTag[2+1];
char strMonat[2+1];
char strJahr[4+1];
};
struct sPerson1 {
char strVName[20+1];
char strNName[30+1];
long nPLZ;
char strOrt[20+1];
char cGeschlecht; /*bei char kein 'regulaerer' Ausdruck mit [] moeglich*/
//char strGeschlecht[1+1]; /*stattdessen String denkbar*/
struct sDatum oDatum; /*nur mit Hilfsvariable, da Eingabe 10 Zeichen, sDatum aber nur 8 Zeichen hat*/
};
int main(void) {
struct sPerson1 P1={0};
unsigned int nFeld;
char strDatum[10+1];
/*Beim Lesen aus Datei kommt noch \n im Format hinzu*/
#ifdef SICHER
if (6!=(nFeld=sscanf_s(EINGABETEXT,"%[^;];%[^;];%d;%[^;];%c;%s",P1.strVName,_countof(P1.strVName),P1.strNName,_countof(P1.strNName),&P1.nPLZ,P1.strOrt,_countof(P1.strOrt),&P1.cGeschlecht,sizeof(char),strDatum,_countof(strDatum)))) {
#else
if (6!=(nFeld=sscanf(EINGABETEXT,"%30[^;];%20[^;];%d;%20[^;];%c;%s",P1.strVName,P1.strNName,&P1.nPLZ,P1.strOrt,&P1.cGeschlecht,strDatum))) {
#endif
fprintf_s(stderr,"Fehler beim Einlesen im Feld %d\n",nFeld+1);
} else {
if (3!=sscanf_s(strDatum,"%[^.].%[^.].%s",P1.oDatum.strTag,_countof(P1.oDatum.strTag),P1.oDatum.strMonat,_countof(P1.oDatum.strMonat),P1.oDatum.strJahr,_countof(P1.oDatum.strJahr))) {
fprintf_s(stderr,"Fehler im Datum");
} else {
fprintf_s(stdout,"'%s' '%s' '%d' '%s' '%c' '%s' '%s' '%s' '%s'\n\n",P1.strVName, P1.strNName, P1.nPLZ, P1.strOrt,P1.cGeschlecht,strDatum,P1.oDatum.strTag,P1.oDatum.strMonat,P1.oDatum.strJahr);
}
} /*if*/
system("Pause");
return 0;
} /*main*/
Ohne die sicheren Funktionen ergibt sich
'Hans56789012345678901Mustermann' 'Mustermann' '10001' 'Berlin' 'm' '01.12.2013'
'01' '12' '2013'
Drücken Sie eine beliebige Taste . . .
Man sieht sehr schön, wie das Abschlusszeichen überfahren wird und der Vorname länger als erlaubt ist.