Programmieren
 
 
 
 
 
C-Grundkurs
 
 
 
 
 
.. Headerdatei: fstrgin.h
 
 

 
 
 
 
 
Zeileneditor fstrgin()
 
 
Einbindung
Die Headerdatei sollte im Verzeichnis des Benutzerprogramms abgelegt sein und kann dann mit dem Präprozessorbefehl .. #include "fstrgin.h" .. eingebunden werden.
 
 
 
 
 

 
// fstrgin.h
// ------------  Version 19.06.2009
//               Model: beliebig
//               keine Fliesskommaemulation
//               www.GoBlack.de, D.Schwarzer
// ---------------------------------------------------------------

#ifndef __fstrgin_h__
#define __fstrgin_h__

// Deklarationen von Bibliotheksfunktionen für fstrgin()
#include <conio.h>                              // für getch()
#include <stdio.h>                              // für putc()

// Übergaben:
// int fstrgin (char* string, int strglang, int typ, char* fstrg);

// string   - ein zu übergebener Buffer, in welchem die ASCII-
//            Codes der Eingabe gesammelt werden. Ist string bei
//            der Übergabe nicht leer, versucht das Programm 
//            bei negativen Werten von 'strglang', die Zeichen in
//            string vor einer Eingabe nach stdout auszugeben.
//            Dies gelingt nur mit Zeichen, welche dem in 'typ'
//            angegebenen Filtertyp entsprechen.

// strglang – max.Anzahl der Zeichen die bei Eingaben angenommen
//            und in string gesammelt werden sollen. Ist die Angabe
//            positiv, wird der Buffer 'string' zuvor gelöscht. Ist
//            die Angabe negativ, versucht fstrgin() den
//            Bufferinhalt 'string', vor einer Eingabe zum
//            Bildschirm auszugeben.

// typ      - kennzeichnet den Typ der zur Eingabe zugelassenen
//            Zeichen. Welche Typen verfügbar sind, siehe weiter 
//            unten ..
// fstrg    - eine Alternative zum Parameter 'strglang'. Das
//            Eingabefeld kann durch einen String mit dem Zeichen #
//            gekennzeichnet werden. Die Eingabemaske darf zudem
//            Zeichen enthalten, die der optischen Unterteilung des
//            Ausgabefeldes dienen. Diese Zeichen werden nach der
//            Eingabe nicht in den Buffer 'string' übernommen.
//         a) Soll keine Eingabemaske verwendet werden, so muss in
//            'strglang' ein Wert für die Feldlänge angegeben
//            werden. 'fstrg' wird als leerer String ("")übergeben.
//         b) Mit der Angabe einer Eingabemaske werden Angaben im
//            Parameter 'strglang' bis auf das negative Vorzeichen
//            ignoriert.
//            Achtung! Die gesammelten Eingaben im Buffer 'string'
//            bilden eine zusammenhängenden Einheit, die nicht
//            durch die optischen Trennzeichen der Eingabemaske
//            unterteilt ist.


// Steuerzeichen: fstrgin() kennt folgende Steuerzeichen ..
//            [<--]     -rückwärts löschen
//            [Strg][Y] -alle Eingabefelder löschen
//            [ESC]     -Eingaben verwerfen, Rückgabe -1
//            [ENTER]   -Eingabe übernehmen (Rückgabe Anzahl der
//                       Zeichen im Buffer string 

// Rückgaben: Bei [Enter] wird die Anzahl der Zeichen in 'string',
//            ohne die 0 der Nullterminierung zurückgegeben.
//            Bei [ESC] ist 'string' leer, die Rückgabe ist -1

// Zuweisung von ASCII-Codes zu Literalen
#define ESC   0x1B
#define CR    0x0D
#define BS    0x08
#define SPC   0x20
#define CTRLY 0x19

// Zuweisung von Filterzuständen zu Literalen, die im Übergabe-
// Parameter 'typ' verwendet werden können 
#define ASC 0             // reiner ASCII-Text zwischen SPC und ~
#define FLT 1             // Fliesskommazahlen  wie -3.123
#define BIN 2             // Binärziffern       0-1
#define OCT 8             // Oktalziffern       0-7
#define DEZ 10            // Dezimalziffern     0-9
#define INT 11            // Dezimalziffern     0-9 und Vorzeichen
#define HEX 16            // Hexadezimalziffern 0-9 und A-F (a-f)

#define inPos  '#'    // Zeichen, das in 'fstrg' eine Einfügestelle
                      // markiert.


int fstrgin (char* string, int stringlang, int typ, char* fstrg)
{
unsigned char c=0;                          // ASCII-Zeichencode
unsigned char p=0;                          // Punktflg bei FLT 
unsigned char n=0, m=0, o=0, s=0, f=0;      // Hilfsvariable

 // stringlang auf negative Angaben testen, diese ggf. invertieren
 // und die Ausgabeflagge s des buffers string setzen. 
 if(stringlang <0) {stringlang *=-1; s=1;}

 // fstrg mit Einfügungen aus string ausgeben und wenn
 // fstrg vorhanden,stringlang auf die Anzahl von inPos-Zeichen
 // setzen

  STRG:
  // fstrg[] ohne inPos-Zeichen ausgeben, inPos Zeichen in
  // stringlang zählen
  if(fstrg[0]!=0){
    stringlang=0;
    for(m=0; fstrg[m]!=0; m++){
      if(fstrg[m]!=inPos)putc(fstrg[m],stdout);
      else{putc(SPC,stdout); stringlang++;}
    }
    // Cursor zurück, auf fstrg-Stringanfang
    for(;m>0;m--) putc(BS,stdout);

    // Cursor nach Angaben von fstrg auf erste Einfügestelle
    for(m=0; fstrg[m]!=inPos && fstrg[m]!=0; m++)
                                        putc(fstrg[m],stdout);

    // Eingabe nach fstrg flaggen
    // m zeigt auf 1. Einfügestelle
    f=1;
  }

  // Eingabebuffer auf 0 löschen, wenn sein Inhalt nicht zur
  // Ausgabe verwendet wird. Vorteil bei der Analyse mehrerer
  // Eingabebereiche, wenn diese nicht vollständig ausgefüllt
  // wurden.
  if(!s) for(n=0; n<stringlang; n++) string[n]=0;

  // n beschreibt die momentane Eingabeposition
  n=0;

  while(1){
    if(!s)c= getch();                   // Tastatureingabe
    else if(s && string[o]!=0){         // eventuelle Zeichen in
          c=string[o++];                // string ausgeben
    }
    else c=s=0;                         // s umschalten

    // Steuerung
    switch (c & 0xFF){
      case CR:                          // [Enter] Eingabeende
           string[n]=0; return(n);                     
      case ESC:
           string[0]=0; return(-1);     // [ESC]   Eingabeende

      case CTRLY:                       // Eingabefelder löschen    
           if(f) for(;m>0;m--)  putc( BS, stdout);
           else  for(;m>0;m--){ putc( BS, stdout);
                                putc(SPC, stdout);
                                putc( BS, stdout); }
           string[0]=0;
           n=o=p=0; s=1;
           goto STRG;

      case BS:                          // [<--] rückwärts löschen
           if(n>0){
             if(f){
               for(;fstrg[m-1]!=inPos && m>0; m--)
                 putc(BS, stdout);
             }
             putc( BS, stdout);
             putc(SPC, stdout);
             putc( BS, stdout);
             n--;m--;
             if(typ==FLT && string[n]=='.')p=0; 
           }
           break;

      // Filter
      default:

        if((typ==ASC && c>=' '&& c<='~')||
           (typ==BIN && c>='0'&& c<='1')||
           (typ==OCT && c>='0'&& c<='7')|| 
           (typ==DEZ && c>='0'&& c<='9')||
           (typ==INT &&(n== 0 && c=='+'||   // nur erstes Zeichen
                        n== 0 && c=='-'||   // nur erstes Zeichen
                        c>='0'&& c<='9'))||
           (typ==HEX &&(c>='0'&& c<='9'||
                        c>='a'&& c<='f'||
                        c>='A'&& c<='F'))||
           (typ==FLT &&(n== 0 && c=='+'||   // nur erstes Zeichen
                        n== 0 && c=='-'||   // nur erstes Zeichen
                        p== 0 && c=='.'||   // nur ein Punkt
                        c>='0'&& c<='9'))||
                        c==0){
            // Ausgabe eines gefilterten Zeichens in c
            // zum Ausgabestring string und Bildschirm
           if(n<stringlang && c!=0){
             putc(c,stdout);
             string[n] = (unsigned char)c;
             n++; m++;
             if(typ==FLT && c=='.') p=1;     // '.' sperren bei FLT
           }
           // Ausgabe von Zeichen in fstrg, die keine inPos
           // Zeichen sind, zum Bildschirm.
           if(f){
             for(; fstrg[m]!=inPos && fstrg[m]!=0; m++){
               putc(fstrg[m],stdout);
             }  // for
           }  // if
        }  // if

    }  // switch
  }  //while
}  // fstrgin()

#endif  // __fstrgin_h__
 

 




Hinweis
Die Funktion fstrgin() ist ein Beispiel für eine einfache Eingabefunktion von ASCII-Code von der Tastatur. Sie erwirkt eine Benutzerführung durch die Angabe einer Eingabefeldlänge und der Vorgabe von Zeichen, die angenommen werden dürfen. Sie ist für Kleincomputer geeignet, die ein DOS- oder DOSähnliches Betriebssystem besitzen und über Terminalprogramme mit einem PC verbunden sind.
Die von der Tastatur übernommenen ASCII-Codes werden in einem Buffer (char Array) abgelegt, der von der aufrufenden Funktion bereitgestellt werden muss. Dies ist notwendig, da die Daten eines Buffers in fstrgin() selber, nach dem Verlassen der Funktion nicht mehr verfügbar wären. Daten einer Funktion sind 'lokal' und werden nach dem Verlassen der Funktion wieder freigegeben.
Wollte man in fstrgin() einen statischen Buffer anlegen, der seine Daten auch nach dem Verlassen der Funktion behalten würde, so müsste dieser Buffer einen Speicherumfang besitzen, der für alle Anwendungsfälle der Funktion ausreichend wäre. Es bestände die Gefahr einer Überdimensionierung.

Die Kommunikation zwischen fstrgin() und der aufrufenden Funktion geschieht also über einen 'Übergabe'-Parameter, .. über den Daten zur aufrufenden Funktion zurückfließen. Dies wird erst erklärbar, wenn die Zeiger (Vektoren) behandelt wurden. Für den Moment muss akzeptiert werden, dass in C auch Dinge möglich sind, die dem Grundaufbau zu wiedersprechen scheinen.


Beispiel für einen Aufruf

// Dieses Programm bindet fstrgin.h ein, stellt einen Buffer aus 32
// Bytes bereit, sowie einen Integer, der die Rückgabe übernimmt.
// Es ruft die Funktion fstrgin() auf und wartet auf die Tastatur-
// eingabe von Zeichen für Fließkommazahlen +-.0-9 (FLT). Von
// diesen werden maximal 10 Stück entgegengenommen.
// Nach der Beendigung von fstrgin() durch [ENTER] oder [ESC] wird
// der eingegebene String zum Bildschirm ausgegeben, ebenso die
// Anzahl der in ihm enthaltenen Zeichen.  

#include "fstrgin.h"
void main (void)
{
 char buffer[32]="";    // Buffer für max.31 Zeichen+NUL
 int anzahl=0;          // Rückgabe, Anzahl eingegebener Zeichen

 anzahl= fstrgin (buffer, 10, FLT,"");
 printf("Der eingegebene String lautet: %s", buffer);
 printf("Er besteht aus %d Zeichen",anzahl);
}

// Der Buffer ist mit 32 Bytes für dieses Program etwas zu groß
// geraten. Dies könnte sich aber relativieren, wenn ein Binärsting
// (BIN) entgegengenommen werden soll, oder Fließkommazahlen mit
// größerer Stellenzahl.
 
 
 
www..de