Forum: Mikrocontroller und Digitale Elektronik Char Array in string in C und dann abfragen


von Äräi (Gast)


Lesenswert?

Folgendes Problem in C:
Programmiert wird auf einem 8Bit - PIC (c18 Compiler).

Ich habe ein Char Array:
1
char buffer[64] = {0};

In dieses Array schreibe ich jetzt sequenziell verschiedene Character, 
die aneinander gehangen einen string ergeben würden. Dieser String kann 
beliebige Länge haben (bzw. maximal 63 Characters). Das Ende des Strings 
wird dann mit '0' terminiert.

Hintergrund ist, dass ich den kompletten Buffer gerne abfragen möchte 
und dies mit
1
 if(buffer[0] == 'a' && buffer[1] == 'b' && buffer[2] == 'c' && buffer[3] == 'd' && buffer[4] == '3') ...

sehr mühselig wird.

Ich bräuchte also etwas wie (Achtung jetzt wird es schwammig - dient nur 
zur Visualisierung):
1
string kette;
2
unsigned int i = 0;
3
for(i; i <= 64; i++)
4
{
5
// hier jetzt irgendwie Array in kette laden
6
}

Danach könnte ich dann den String über...
1
Switch(kette)
2
{
3
     case "abcde":
4
     // mache was
5
     break;
6
7
}

Wie macht man sowas?
Es kommt mit Sicherheit der berechtigte Ratschlag "Lies ein C - Buch".
Kann Jemand ein zeitgemäßes C - Buch empfehlen?

von Felix A. (madifaxle)


Lesenswert?

Erstmal den Index korrigieren. Bei i<= 64 sind es insgesamt 65 Zeichen 
im Puffer...

Warum sendest du nicht bei jedem Transmit Ready Interrupt ein weiteres 
zeichen aus dem String und hörst auf, wenn eine 0 im Puffer steht?

von Karl H. (kbuchegg)


Lesenswert?

Äräi schrieb:

> Wie macht man sowas?
1
#include "string.h"
2
3
4
....
5
6
7
   if( strcmp( buffer, "abcd" ) == 0 )
8
     .... war dieser String, mach was


> Es kommt mit Sicherheit der berechtigte Ratschlag "Lies ein C - Buch".
> Kann Jemand ein zeitgemäßes C - Buch empfehlen?

Wie immer der Klassiker: Kernighan&Ritchi Programmieren in C

Aber auf dieser Ebene tut es eigentlich auch so zimelich jedes andere 
Buch.

von B. S. (bestucki)


Lesenswert?

Äräi schrieb:
> Hintergrund ist, dass ich den kompletten Buffer gerne abfragen möchte
> und dies mit
>  if(buffer[0] == 'a' && buffer[1] == 'b' && buffer[2] == 'c' &&
> buffer[3] == 'd' && buffer[4] == '3') ...
>
> sehr mühselig wird.

Dafür kann die Funktion strcmp verwendet werden. Als Nachschlagewerk 
empfehle ich http://www.cplusplus.com/reference/clibrary/

Äräi schrieb:
> Es kommt mit Sicherheit der berechtigte Ratschlag "Lies ein C - Buch".
> Kann Jemand ein zeitgemäßes C - Buch empfehlen?

Die 2. Auflage The C Programming Language von K&R ist meiner Meinung 
nach immer noch zeitgemäss, die Änderungen von C89 bis C11 sind 
überschaubar und können schnell im Internet recherchiert werden.

Felix A. schrieb:
> Erstmal den Index korrigieren. Bei i<= 64 sind es insgesamt 65 Zeichen
> im Puffer...

Genau, und zwar zu
1
sizeof(buffer)

von Karl H. (kbuchegg)


Lesenswert?

Um das auch noch aufzugreifen
1
char buffer[64] = {0};
2
3
unsigned int i = 0;
4
for(i; i <= 64; i++)
5
6
...

nicht 'kleiner gleich'. kleiner!

Ein Array, welches du mit 4 Elementen definiert hast
1
char tst[4];

hat die Elemente
1
  tst[0]
2
  tst[1]
3
  tst[2]
4
  tst[3]

zähl nach. Sind genau 4 Stück.
Aber: der höchste zulässige Index ist um 1 kleiner als die Anzahl der 
Elemente.

von Karl H. (kbuchegg)


Lesenswert?

Karl H. schrieb:
> Äräi schrieb:
>
>> Wie macht man sowas?
>
>
1
> #include "string.h"
2
>

Fehler.

Muss natürlich
1
#include <string.h>
lauten.

string.h ist ja ein mit dem Compiler mitgeliefertes Standard 
Header-File.

von Felix A. (madifaxle)


Lesenswert?

Ich habe den Fragestelle offensichtlich mis(t)verstanden...

von Karl H. (kbuchegg)


Lesenswert?

> Das Ende des Strings wird dann mit '0' terminiert.

Der String wird auch nicht mit '0' terminiert.
'0' ist ein Zeichen wie jedes andere. So wie 'a' oder aber auch '1', '2' 
etc.

Was du meinst, das ist das Zeichen '\0'.
Das ist ein Unterschied!

Das Zeichen '0' hat den ASCII Code 0x30. Jedes Terminal, das ASCII 
versteht, wird beim Erhalt eines derartigen Zeichens eine 0 auf das 
Display malen.

Wohingegen '\0' das Zeichen ist, dessen ASCII Code auch wirklich 0x00 
ist.

Hier ist Genauigkeit schon wichtig. Denn C Strings sind nun mal genau so 
definiert, dass sie eine Abfolge von Zeichen darstellen, an deren Ende 
ein Zeichen mit dem Code 0x00 steht.

von Äräi (Gast)


Lesenswert?

Ui, Ok schon mal vielen Dank für die ganzen Ratschläge.

Buch werde ich mir zulegen, auch wenn ich es nicht ganz billig finde.

strcmp Function habe ich mir angeguckt und scheint einleuchtend. Lauf 
index für Array - induzierung auch.

Jetzt zum Abschluss nochmal eine nicht ganz schlaue Frage:
1
#include <string.h>
2
char buffer[64] = {0};
3
...
4
buffer[0] = 'A';
5
if( strcmp( buffer, "abcd" ) == 0 )

Ist jetzt buffer schon eine Variable vom Datentyp string?
Gerade diese Umrechnung von einem char Array in eine string Variable 
fehlt mir nämlich.

von Karl H. (kbuchegg)


Lesenswert?

Äräi schrieb:

>
1
> #include <string.h>
2
> char buffer[64] = {0};
3
> ...
4
> buffer[0] = 'A';
5
> if( strcmp( buffer, "abcd" ) == 0 )
6
>
>
> Ist jetzt buffer schon eine Variable vom Datentyp string?

Ja.
Aber eher zufällig, weil du das Array mit lauter 0-Bytes initialisiert 
hast.
1
  buffer[0] = 'A';
2
  buffer[1] = '\0';

jetzt hast du in buffer auf jeden Fall einen gültigen C-style String, 
egal was vorher im Array stand.

von Karl H. (kbuchegg)


Lesenswert?

Karl H. schrieb:
> Äräi schrieb:
>
>>
1
>> #include <string.h>
2
>> char buffer[64] = {0};
3
>> ...
4
>> buffer[0] = 'A';
5
>> if( strcmp( buffer, "abcd" ) == 0 )
6
>>
>>
>> Ist jetzt buffer schon eine Variable vom Datentyp string?
>
> Ja.

Muss mich hier korrigieren.
Jain.
In C gibt es keinen Datentyp 'string'.
buffer ist ein Array von char und wird es das auch immer bleiben.

Ob der Inhalt eines Arrays als C-style String angesehen werden kann oder 
nicht, definiert sich einzig und alleine über diesen Inhalt. Damit etwas 
als C-style String durchgeht, muss es die Bedingung erfüllen: Nach dem 
letzten gültigen Zeichen muss es ein Byte mit dem binären Wert 0 geben. 
Erst dann qualifiziert sich dieser Inhalt als String - der in einem char 
Array Zeichen für Zeichen gespeichert ist.

: Bearbeitet durch User
von Ralph S. (jjflash)


Lesenswert?


von Äräi (Gast)


Lesenswert?

Wiedermal vielen Dank,

icha´habe das Folgende versucht:
1
    buffer[0] = 'A';
2
    buffer[1] = 'B';
3
    buffer[2] = '\0';
4
    if( strcmp(buffer, "AB" ) == 0 )
5
    {
6
    // setze Breakpoint zur Überprüfung
7
    }

Ich hätte erwartet, dass ich jetzt an dem Breakpoint gelange, da der 
Inhalt des Array buffer als String angesehen werden kann (da binäre Wert 
0 auf letztes gültiges Zeichen folgt).

Die Bedingung müßte also imo TRUE ergeben.

Ich bekomme jedoch auch die Compiler Warnung:

WARNING:  This version of MPLAB C18 does not support procedural 
abstraction.  Procedural abstraction will not be run.
Warning [2066] type qualifier mismatch in assignment

#include <string.h> ist inkludiert.

von Äräi (Gast)


Lesenswert?

AH ok,
strings in ROM RAM sind für den C18 nicht dasselbe.

Kriege ich schon raus.
Danke schon einmal

von Äräi (Gast)


Lesenswert?

Gibt es jetzt noch ein Konstrukt, wie ich ähnlich der Switch() case 
Anweisung diesen Buffer üver strcmp abfragen kann?

Momentan habe ich es wie folgt realisiert:
1
if(strcmppgm2ram(buffer,(const far rom char*)"AB") == 0 )
2
{...}
3
4
if(strcmppgm2ram(buffer,(const far rom char*)"AC") == 0 )
5
{...}
6
7
if(strcmppgm2ram(buffer,(const far rom char*)"AD") == 0 )
8
{...}

Dies ist auf die Dauer bei vielen Abfragen natürlich mehr als mühselig.

Kann man das ganze in eine Switch case Anweisung packen?
Eine Funktion wie strcmp in eine Switch case zu packen ist schwierig :)

von Peter II (Gast)


Lesenswert?

Äräi schrieb:
> Dies ist auf die Dauer bei vielen Abfragen natürlich mehr als mühselig.

dann schreibt dir ein Makro.

> Kann man das ganze in eine Switch case Anweisung packen?
nein

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.