C/Zeichen aus Array vergleichen?

Gast #2257713
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
}
Gast #2257724
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
Persönliche Seite #2257748
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'.
Gast #2257795
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
Angehängte Dateien:
Gast #2257826
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
}
Gast #2259257
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.
Angehängte Dateien:
Gast #2260421
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren