Forum: PC-Programmierung scanf und buffer array


von Stefan (Gast)


Lesenswert?

Zuerst Mal ein schönes neues Jahr...

Ich habe folgendes Problem.
1
char buffer[10];
 wo ich mit fgets von der Standarteingabe etwas hineinspeichere. Jetzt 
will ich wissen, wie ich mit scanf nachschauen kann, ob auch wirklich 
das drin ist was ich drin haben will. Soll in meinem Fall so ausschauen:
-LEERZEICHEN1xy
oder
-LEERZEICHENxyLEERZEICHENxy
wobei xy Werte zwischen 1-3 haben darf bzw. soll

Ich hoffe, dass ihr versteht was ich meine :D

lg
Stefan

von Klaus W. (mfgkw)


Lesenswert?

> -LEERZEICHEN1xy

die 1 ist ernst gemeint und kein Schreibfehler?

von Stefan (Gast)


Lesenswert?

Doch das ist ein Schreibfehler! Habs leider nicht ändern können...

von Klaus W. (mfgkw)


Lesenswert?

Es geht also darum festzustellen, ob im String eine oder zwei Zahlen 
stehen?

von Klaus W. (mfgkw)


Lesenswert?

Falls ja:
1
    int   erste, zweite;
2
    switch( sscanf( puffer, "%d%d", &erste, &zweite ) )
3
    {
4
     case 1:  // eine Zahl erfolgreich gelesen
5
              ... nur erste verwenden ...
6
              break;
7
     case 2:  // zwei Zahlen erfolgreich gelesen
8
              ... erste und zweite verwenden ...
9
              break;
10
     default: // Lesen gescheitert!
11
              ...
12
              break;
13
    }

sscanf() liefert als Rückgabewert, wieviele %... erfolgreich gelesen 
werden konnten.

von Stefan (Gast)


Lesenswert?

Fast, aber nicht ganz. Im Prinzip will ich so 4 Zahlen herauslesen.

xy räpresentiert dabei eine Koordinate auf einem 3x3 Spielfeld.

Der Befehlsaufbau sieht ursprünglich so aus:

p xy
oder
c xy xy

das p oder c fang ich dabei schon in einem Schleifendurchlauf ab und es 
bleibt somit nur LEERZEICHEN und Zahlen übrig.

von Klaus W. (mfgkw)


Lesenswert?

Dann halt so:
1
    int   erste, zweite, dritte, vierte;
2
    char puffer[100];
3
    fgets( puffer, 100, stdin );
4
    switch( sscanf( puffer, "%1d%1d%1d%1d", &erste, &zweite, &dritte, &vierte ) )
5
    {
6
    case 1:  // eine Zahl erfolgreich gelesen
7
        printf( "%d\n", erste );
8
        break;
9
    case 2:  // zwei Zahlen erfolgreich gelesen
10
        printf( "%d %d\n", erste, zweite );
11
        break;
12
    case 3:  // drei Zahlen erfolgreich gelesen
13
        printf( "%d %d %d\n", erste, zweite, dritte );
14
        break;
15
    case 4:  // vier Zahlen erfolgreich gelesen
16
        printf( "%d %d %d %d\n", erste, zweite, dritte, vierte );
17
        break;
18
    default: // Lesen gescheitert!
19
        printf( "ganz dumm gelaufen\n" );
20
        break;
21
    }

von Klaus W. (mfgkw)


Lesenswert?

ach ja; Standard, nicht Standart

von Stefan (Gast)


Lesenswert?

sehr super...danke!

Genau das was ich gesucht habe.

von Stefan (Gast)


Lesenswert?

eine Sache ist mir jetzt doch noch eingefallen :D

Gibts da noch eine Möglichkeit, dass er eine Chareingabe verbietet?

z.B.: p 1a oder wechselt er dann automatisch in den default Zweig?

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> eine Sache ist mir jetzt doch noch eingefallen :D
>
> Gibts da noch eine Möglichkeit, dass er eine Chareingabe verbietet?

Nein.
fgets frisst was es kriegen kann. Bis zum abschliessenden \n
Es ist dein Bier die Eingabe daraufhin zu untersuchen, ob sie gültig ist 
(und genau deshalb eignet sich sscanf nicht besonders gut dazu, wenn am 
anderen Ende des Streams ein Mensch sitzt. Wenn die Eingabe von einem 
anderen Programm generiert wird, sieht die Sache anders aus. Aber bei 
einer menschlichen Eingabe muss man immer mit Fehleingaben rechnen. Und 
da man das sowieso analysieren muss, kann man dann auch gleich die 
Wandlung in Zahlen auch noch mitmachen. Das ist dann schon fast kein 
Mehraufwand mehr)

> z.B.: p 1a oder wechselt er dann automatisch in den default Zweig?

Nix default. sscanf konnte 1 Zahl korrekt lesen und genau das meldet es 
dir auch mit seinem Returnwert. Ob diese 1 Zahl dadurch zustande kam, 
dass der Benutzer tatsächlich nur "p 1" oder aber "p 1a" eingegeben hat, 
kannst du mit sscanf nicht feststellen.

von Klaus W. (mfgkw)


Lesenswert?

Wenn man es detaillierter haben möchte, bietet es sich an, entweder zu 
Fuß zu parsen oder stückweise mit strtol().
Mit letzterem erfährt man jeweils, wie weit das Lesen im String geklappt 
hat und kann ab dieser Stelle nachschauen, was da so steht.

von Stefan (Gast)


Lesenswert?

Zu was würdest du raten, wie man das am besten macht? Will jetzt 
natürlich keinen fertigen Code von dir, aber ein kleiner Denkanstoß in 
die richtige Richtung würde mir sicher helfen...

von Klaus W. (mfgkw)


Lesenswert?

Mein Rat: erst überlegen, was du genau willst.
Dann ergibt sich der Rest meist schnell.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Zu was würdest du raten, wie man das am besten macht? Will jetzt
> natürlich keinen fertigen Code von dir, aber ein kleiner Denkanstoß in
> die richtige Richtung würde mir sicher helfen...

Anfangen würd eich damit mir zu überlegen, dass es sich ja immer nur um 
Einzelzeichen handelt, die durch eine oder mehrere Whitespace Zeichen 
voneinander getrennt sind.

Dein Aufbau sieht doch so aus

Commandozeichen: kann nur p oder c sein

nach dem Commandozeichen kommt auf jeden Fall mal Whitespace

Wenn Commando 'p' dann kommen
   x-Koordinate y-Koordinate

Wenn Commando 'c' dann kommen
   x-Koordinate y-Koordinate Whitespace x-Koordinate y-Koordinate


Das Pärchen 'xKoordinate y-Koordinate' kommt in beiden Fällen mehrfach 
vor. Da bietet es sich also ein eine Funktion dafür zu machen, die ein 
Koordinatenpärchen aus dem String holt und mir auch meldet, ob das 
gültig war (damit der Aufrufer nicht weiter macht).
AUch für Whitespace überlesen kann man sich eine schöne Funktion machen.

Allen Funktionen gemeinsam ist: Sie kriegen den String und einen Index 
ab wo sie loslegen sollen. Und sie modifizieren den Index, so dass man 
ihn gelich in die nächste Funktion reinstecken kann und die dann dort 
weiter macht, wo die vorhergehende Funktion aufgehört hat.

Die Verwendung in der Hauptfunktion könnte zb so sein
1
   fgets( ..... )
2
3
   nextChar = 0;
4
   Error = FALSE;
5
   SkipWhiteSpace( Input, &nextChar );
6
7
   switch( Input[nextChar] ) {
8
     case 'p':
9
       Error |= SkipWhitespace( Input, &nextChar );
10
       Error |= FetchPair( Input, &nextChar, &x1, &y1 );
11
       if( !Error ) {
12
         mach was mit x1, y1
13
       }
14
       break;
15
16
     case 'c':
17
       Error |= SkipWhitespace( Input, &nextChar );
18
       Error |= FetchPair( Input, &nextChar, &x1, &y1 );
19
       Error |= SkipWhitespace( Input, &nextChar );
20
       Error |= FetchPair( Input, &nextChar, &x2, &y2 );
21
       if( !Error ) {
22
         mach was mit x1, y1, x2, y2
23
       }
24
       break;
25
26
     default:
27
       Error = TRUE;
28
   }
29
30
   if( Error ) {
31
     printf( "Illegal Input: '%s'\n", Input );
32
   }
33
34
   ....

Nachdem geklärt ist, wie ich das ganze verwenden möchte ... wie müssen 
daher die Funktionen SkipWhitespace und FetchPair aussehen?

von Stefan (Gast)


Lesenswert?

Vielen Dank nochmal für den super Post...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.