www.mikrocontroller.net

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


Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
>
> 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!

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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: hudi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
 if(command[3]>='A'){
       if(command[3]<='X'){
       }   // command[3] ist ein Buchstabe zwischen A und B
} 

Autor: hudi (Gast)
Datum:

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

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unsigned char IsValid( char c )
{
  static char Valid[] = "@;ABGZ8/%";

  for( unsigned char i = 0; i < sizeof( Valid ); ++i )
  {
    if( Valid[i] == c )
      return TRUE;
  }

  return FALSE;
}

  ....

   if( IsValid( 'A' ) )
     ....


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

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für deine Antwort. Genau das hab ich gesucht!!!!!!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, da hast du recht!
Ist mir eben garnicht aufgefallen!!

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
valid(command[3], "0123456789ABCDEF")

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

  return 0;
}

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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, fuktioniert!!!!

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

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

Autor: jl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke!! Das vereinfacht die ganze Sache!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.