Forum: Compiler & IDEs Eingabe auf Gültigkeit prüfen


von obelix (Gast)


Lesenswert?

Hallo,
ich habe C-Programm für einen AVR-Mikrokontroller.
Ich will nun Prüfen, ob ein bestimmtes Zeichen in einem Array gültig 
ist, also z.B. so:
1
if (command[3] != ';' || command[3] != '@' || command[3] != 'A' || command[3] != 'B' .......)

Ich könnte die Liste jetzt weiter fortführen, aber das ist aber ein 
wenig umständlich!
Gibt es da eine einfacherer Lösung für??

In Voraus schonmal Danke für Eure Hilfe.

von Karl H. (kbuchegg)


Lesenswert?

obelix wrote:
> Hallo,
> ich habe C-Programm für einen AVR-Mikrokontroller.
> Ich will nun Prüfen, ob ein bestimmtes Zeichen in einem Array gültig
> ist, also z.B. so:
>
1
> if (command[3] != ';' || command[3] != '@' || command[3] != 'A' ||
2
> command[3] != 'B' .......)
>
> Ich könnte die Liste jetzt weiter fortführen, aber das ist aber ein
> wenig umständlich!

Erst mal: mach es korrekt und dann frag dich ob du das Vereinfachen
kannst. Deine Abfrage da oben ist nämlich nicht korrekt :-)

> Gibt es da eine einfacherer Lösung für??

Sicher: Die gültigen (oder ungültigen) Zeichen in ein Array
packen und dann in einer Schleife das in Frage stehende
Zeichen mit jedem Zeichen im Array vergleichen.

Nur so als alternatives Beispiel.

von Karl H. (kbuchegg)


Lesenswert?

Stefan "stefb" B. wrote:
> Geht so nicht.
>
> Mehrfache UNGLEICH-Bedingungen der gleichen Variableb verODERt sind in
> 99,9% der Fälle immer wahr ;-)

In obigem Fall, kannst du ruhig auf 100% gehen :-)

Für jedes Zeichen, egal welches, gilt:
  es ist entweder nicht gleich '@' oder
  es ist nicht gleich 'A'.

Selbst ein einzelnes '@' ist ja nicht gleich einem 'A'
und umgekehrt ist ein einzelnes 'A' ja nicht gleich einem '@'.

Die einzige Möglichkeit, wie ein Zeichen diese Hürde
schaffen könnte bestünde darin, dass es gleichzeitig
'@' ist und gleichzeitig 'A' und gleichzeitig ';' und gleichzeitig ...
Da das offensichtlich nicht möglich ist, ....

Edit: Stefan hat sein Post mitlerweile zurückgezogen.
Finde ich schade. Da war ein Hinweis auf isupper, islower, isalpha,
is digit drinnen, der nicht zu verachten ist.

von hudi (Gast)


Lesenswert?

auf welche Zeichen möchtest du denn prüfen?
du kannst natürlich einen Bereich angeben, in dem geprüft werden soll, 
z.B.
1
 if(command[3]>='A'){
2
       if(command[3]<='X'){
3
       }   // command[3] ist ein Buchstabe zwischen A und B
4
}

von hudi (Gast)


Lesenswert?

sorry, so gehts noch einfacher:
1
 if(command[3]>='A'&& command[3]<='X'){
2
       }   // command[3] ist ein Buchstabe zwischen A und B

von obelix (Gast)


Lesenswert?

Danke für deiene schnelle Antwort.

Was ist denn an der Abfrage nicht korrekt??
Es funktioniert auf jeden Fall einwandfrei.

Die Idee mit dem Array hatte ich auch schon, allerdings weiß ich nicht, 
wie ich das in C umsetzen kann.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Oh da war ich sowohl zu lahm beim Schreiben meiner Antwort (1. Antwort 
von Karl heinz) als auch zu lahm beim Löschen meines dadurch überflüssig 
gewordenen E-Laborats (2. Antwort von Karl heinz).

von obelix (Gast)


Lesenswert?

da war ich wohl ein wenig langsam mit tippen, da waren hier schon gleich 
mehrer neue antworten :-)

Da ich nicht unbedingt nur ganze Bereiche prüfen will, sondern auch 
mehrere einzelne Zeichen, finde ich die Idee mit dem Array einfacher.
Kann mir einer sagen wie ich das umsetzen kann?

von Karl H. (kbuchegg)


Lesenswert?

1
unsigned char IsValid( char c )
2
{
3
  static char Valid[] = "@;ABGZ8/%";
4
5
  for( unsigned char i = 0; i < sizeof( Valid ); ++i )
6
  {
7
    if( Valid[i] == c )
8
      return TRUE;
9
  }
10
11
  return FALSE;
12
}
13
14
  ....
15
16
   if( IsValid( 'A' ) )
17
     ....

Da wird wohl mal etwas Literatur fällig. Ohne ist eine Sprache
wie C nicht vernünftig zu erlernen.

von obelix (Gast)


Lesenswert?

Danke für deine Antwort. Genau das hab ich gesucht!!!!!!

von Karl H. (kbuchegg)


Lesenswert?

> Was ist denn an der Abfrage nicht korrekt??

Überleg mal.
Dein zu prüfendes Zeichen sei zb. '!'

Die Abfrage (ich kürze jetzt mal wegen Tippaufwand) sei

  if (command[3] != ';' || command[3] != '@'

Wie ist das mit dem '!'?
'!' ist nicht gleich ';'. Das ergibt also TRUE und damit (wegen
dem ODER) ist auch der ganze Testausdruck TRUE. Das if wird
also genommen.

WIe ist das mit '@'?
Nun. '@' ist nicht gleich ';'. Damit ist dieser Teilausdruck
ebenfalls TRUE und damit der ganze Ausdruck wieder TRUE. Das if
wird also genommen.

Wie ist das mit ';'?
Nun. ';' != ';' ergibt falsch, denn natürlich ist ';' gleich ';'.
Aber das wars noch nicht, denn da werden ja meherer Teilausdrücke
verodert. Ein ODER kann erst dann abgebrochen werden, wenn ein
Teilausdruck TRUE ergibt, erst dann steht fest, dass der komplette
Ausdruck auf jeden Fall TRUE ergeben wird. Also wird weiter geprüft:
';' != '@'. Ja, klar ';' ist nicht gleich '@' und da das TRUE ergibt
ist auch der komplette Ausdruck TRUE. Das if wird also schon wieder
genommen.

Egal welches Zeichen du durch diese Bedingung schickst, es wird
immer TRUE herauskommen. Denn entweder das Zeichen ist nicht gleich
einem ';' oder es ist nicht gleich einem '@'. Eine der beiden
Bedingungen, oder aber sogar beide, trifft immer zu. Egal welches
Zeichen du testest.

von obelix (Gast)


Lesenswert?

Stimmt, da hast du recht!
Ist mir eben garnicht aufgefallen!!

von obelix (Gast)


Lesenswert?

@Karl-Heinz:
Ich hab noch eine Frage zu deinem Programm. Wenn ich das so übernehme, 
wie du es gepostet hast, funktioniert es einwandfrei.

Nun will ich diese Funktion ein wenig flexibler gestalten, indem ich die 
erlaubten Zeichen mit übergebe:
1
valid(command[3], "0123456789ABCDEF")

Habe Sie dazu entwas abgeändert:
1
unsigned int valid(char signe ,char signes[])
2
{
3
  for (unsigned char i = 0; i < sizeof(signes); ++i)
4
  {
5
    if(signes[i] == signe) return 1;
6
  }
7
8
  return 0;
9
}

Allerdings funktioniert dies nicht.
Die Zeichen werden doch in beiden Fällen als Array übergeben, sodass es 
doch eigendlich funktionieren sollte!?
Woran kann das liegen?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

obelix wrote:

> Woran kann das liegen?

Daran, dass signes jetzt kein Feld/Array, sondern wegen der Übergabe als 
Funktionsargument, ein Zeiger/Pointer ist. Dessen Länge ist beim AVR 2. 
Die Länge des Textes auf den der Pointer zeigt, bekommst du mit der 
Funktion strlen heraus.

http://www.dclc-faq.de/kap2.htm

von obelix (Gast)


Lesenswert?

Danke, fuktioniert!!!!

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Geht auch ohne zusätzliche Funktion:
1
strchr("0123456789ABCDEF", command[3]);

von jl (Gast)


Lesenswert?

Wenn Speicherplatz kein Problem darstellt, aber die Rechenzeit kurz sein 
muss und es sich um 8bit Werte handelt geht auch folgendes:

Array mit 256 Elementen, wobei jedes Element den Status TRUE oder FALSE 
hat.
  valid_array[256] = (FALSE, FALSE, TRUE, FALSE, TRUE, TRUE ..)

Anschliessend die Abfrage:

  if (valid_array[xyz] == TRUE)



JL

von obelix (Gast)


Lesenswert?

Danke!! Das vereinfacht die ganze Sache!!

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.