Forum: PC-Programmierung C/Zeichen aus Array vergleichen?


von Stefan O. (Gast)


Lesenswert?

Hallo zusammen,

seit ein paar Tagen hat mich auch der µC Virus befallen, bei der 
Gelegenheit unternehme ich auch meine ersten Gehversuche mit "C". Und 
schon habe ich mein erstes Problem und Fragen:

Meine selbstgestellte Übungsaufgabe: eine Art "Ablaufsteuerung" in einem 
Array (code) abzulegen. Kommandos sind dabei in Form von einzelne 
Buchstaben hinterlegt.Was ich jetzt hin bekommen habe ist es das Array 
zu splitten und die einzelnen Buchstaben wieder separat auszugeben. 
Woran ich aber schier verzweifle ist Vergleichsoperationen 
durchzuführen.
Wenn ich mit "if(strcmp(element, "A") == 0)" vergleiche funktioniert 
dies nicht richtig.

Leider bringt mich der Compiler Hinweis "passing argument 1 of ‘strcmp’ 
makes pointer from integer without a cast" nur bedingt weiter. Wenn ich 
das richtig verstehe muss ich eine Typenumwandlung durchführen weil 
sonst mit dem Pointer auf die Variable verglichen werden würde. Nur wie? 
Kann mir jemand auf die Sprünge helfen?

Nach einiger Frickelei habe ich jetzt Version2 gebastelt und die Strings 
für den Vergleich "kompatibel" gemacht, die Version funktioniert 
zumindest. Kann ich das auch intelligenter lösen?

[[http://www.mikrocontroller.net/articles/FAQ#wie_schreibt_man_eine_Funktion.2C_die_einen_String_liefert.3F]] 
habe ich gefunden, leider habe ich da aber noch Transferschwierigkeiten.

Schönes Wochenende und besten Dank im vorraus,

Stefan

Code Sniplet Version1:
1
#include <stdio.h>
2
#include <string.h>
3
4
5
int main()
6
{
7
  char code []="AABCAEE";
8
  char element;
9
  int i=0;
10
  while (i<sizeof(code)-1)
11
  {
12
    element = code[i];
13
    printf("Element %d: %c\n",i,element);
14
    
15
    if(strcmp(element, "A") == 0)
16
17
    {
18
      printf("Ausgang A Schalten\n");
19
    }
20
    if(strcmp(element, "B") == 0)
21
22
        {
23
          printf("Ausgang B Schalten\n");
24
        }
25
  i++;
26
  }
27
28
  return 0;
29
}
Code Sniplet Version2:
1
#include <stdio.h>
2
#include <string.h>
3
4
5
int main()
6
{
7
  char code []="AABCAEE";
8
  char element[2];
9
  int i=0;
10
  while (i<sizeof(code)-1)
11
  {
12
    element[0] = code[i];
13
14
    i++;
15
    element[1] = '\0';
16
17
    if(strcmp(element, "A") == 0)
18
19
    {
20
      printf("Ausgang A Schalten\n");
21
    }
22
    if(strcmp(element, "B") == 0)
23
24
        {
25
          printf("Ausgang B Schalten\n");
26
        }
27
  }
28
29
  return 0;
30
}

von Stefan E. (sternst)


Lesenswert?

Wenn du einzelne Buchstaben vergleichen willst, dann vergleiche auch nur 
Buchstaben und keine Strings:
1
if (element == 'A')

von Stefan O. (Gast)


Lesenswert?

Hi Stefan,

danke für die prompte Antwort. Leider komme ich so nicht zum gewünschten 
Ergebnis (keine Verzweigung in die Bedingung bei "A") und den Hinweis 
"comparison between pointer and integer".

Werde in der Zwischenzeit mal versuchen Variante 2 auf einen µC zu 
portieren.

LG Stefan

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefan Ott schrieb:
> Leider komme ich so nicht zum gewünschten
> Ergebnis (keine Verzweigung in die Bedingung bei "A") und den Hinweis
> "comparison between pointer and integer".

Dann sieh mal ganz genau hin und vergleiche die von Dir verwendeten 
Zeichen unmittelbar vor und hinter dem A mit dem, was Stefan Ernst 
verwendet hat.

Da ist ein Unterschied.

Tipp:
Stringkonstanten werden in Anführungszeichen geschrieben: "bla",
Zeichenkonstanten aber werden in Hochkommata geschrieben: 'a'.

von Stefan O. (Gast)


Angehängte Dateien:

Lesenswert?

Na klar, so funktioniert es. Ich danke Euch beiden. Da habe ich mir ein 
""" für ein "'" vormachen lassen ;-)

In der Zwischenzeit habe ich das ganze mal mit Euren Korrekturen für den 
ATTINY13 mit 3 LED aufgebaut. Funktioniert einwandfrei und kann schnell 
und flexibel erweitert werden.

Ich hänge das ganze mal im kommentierten Quelltext an.Vielleicht kann 
jemand so etwas noch gebrauchen.

LG Stefan

von nocheinGast (Gast)


Lesenswert?

Ich weiß nicht, ob du schon so weit bist, aber für solche 
Mehrfachverzweigungen bietet sich auch "switch" an. Das wird m. E. 
leichter lesbar und ist vor allem nicht so viel zu tippen:
1
switch (do_action) {
2
  case 'A':
3
    led_A_on;
4
    break;
5
6
  case 'a':
7
    led_A_off;
8
    break;
9
10
  case 'B':
11
    led_B_on;
12
    break;
13
    ...
14
  default:
15
    // unbekanntes Zeichen
16
    break;
17
}

von Stefan O. (Gast)


Lesenswert?

Danke, die Idee mit dem Case Switch schau ich mir mal an. Ich befasse 
mich erst seit 2 Tagen mit C, ich habe vorher überwiegend mit Java 
programmiert, dort gibt es den auch.

LG Stefan

von Stefan O. (Gast)


Angehängte Dateien:

Lesenswert?

Stefan Ott schrieb:
> Danke, die Idee mit dem Case Switch schau ich mir mal an. Ich befasse
> mich erst seit 2 Tagen mit C, ich habe vorher überwiegend mit Java
> programmiert, dort gibt es den auch.
>
> LG Stefan

So sieht es gut aus...

Stefan

von nocheinGast (Gast)


Angehängte Dateien:

Lesenswert?

Du hast da noch ein paar Sachen drin, mit denen du dich gewaltig in die 
Nesseln setzen kannst...
1
#define led_A_on  PORTB |=_BV(PB0)
2
#define led_A_off  PORTB &= ~_BV(PB0)
3
#define led_B_on  PORTB |=_BV(PB1)
4
#define led_B_off  PORTB &= ~_BV(PB1)
5
#define led_C_on  PORTB |=_BV(PB2)
6
#define led_C_off  PORTB &= ~_BV(PB2)
Hast du schon mal probiert, was passiert, wenn in einem dieser Makros 
ein Fehler drin ist? Dann wird der Compiler bei der Fehlermeldung nicht 
die Zeile angeben, in der das Makro steht, sondern die Zeile, in der das 
Makro verwendet wird. Da kann das Fehlersuchen ekelhaft werden. Du 
kannst stattdessen inline-Funktionen erstellen, also welche, die der 
Compiler selber anstelle des Funktionsaufrufs einfügt. Das macht im 
Gegensatz zu den Makros nicht der Präprozessor, du kriegst also eine 
exakte Fehlermeldung:
1
inline void led_A_on() {
2
  PORTB |= (1 << PB0);
3
}
4
5
inline void led_A_off() {
6
  PORTB &= ~(1 << PB0);
7
}
8
9
inline void led_B_on() {
10
  PORTB |= (1 << PB1);
11
}
12
13
inline void led_B_off() {
14
  PORTB &= ~(1 << PB1);
15
}
16
17
inline void led_C_on() {
18
  PORTB |= (1 << PB2);
19
}
20
21
inline void led_C_off() {
22
  PORTB &= ~(1 << PB2);
23
}
Dieses _BV-Makro halte ich auch für überflüssig, mehr zu schreiben ist 
es so auch nicht.
1
DDRB =7;    //Ausgänge definieren (LED PB0-PB2)
Das ist sehr schwer zu lesen. Jemand, der kein Datenblatt hat, ist da 
schnell verloren ("Wo kommt denn die 7 her?"). Besser ist es so:
1
DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2);
Diese Ausdrücke berechnet der Compiler beim Kompilieren, das Programm 
wird also nicht größer.
1
while (i<sizeof(program)-1)
"sizeof" ist in C mit Vorsicht zu genießen. Hier funktioniert es, aber 
wie wäre es so:
1
for (uint8_t i = 0; program[i] != '\0'; i++) {
Schließlich wird der String, den du oben festlegst, von einem '\0' 
abgeschlossen.

Ich hab deinen Code mal etwas umgeschrieben und angehängt.

von Stefan O. (Gast)


Lesenswert?

Hallo nocheinGast,

viele Dank für Deine Rückmeldungen. Sind allesamt plausibel und 
nachvollziehbar. Ich werde diese bei meinen weiteren Gehversuchen mit C 
auf jeden Fall berücksichtigen.

LG Stefan

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.