mikrocontroller.net

Forum: Compiler & IDEs Funktionen und Array's


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche mich gerade daran, Zeichenketten zu sortieren. Folgende
Funktion soll Zeichen für Zeichen vom Quellarray zum Zielarray kopieren,
bis das zu übergebende End of Text Zeichen kommt.

void sortiere_zeichen(char *ziel, char *quelle, char eot)
{
  uint8_t ready=0;
  char zeichen;
  while(!ready)
    {
    zeichen=*quelle;
          if(zeichen!=eot)
          {
            *ziel=zeichen;
            ziel++;
            quelle++;
          }
          else
          {
            ready=1;
            *ziel='\0';
          }
        }
}

Ich tue mich momentan etwas schwer mit den Pointern. Geht das so oder 
gibt es eine elegantere Lösung?

Gruß Sascha

Autor: Curby23523 N. (nils_h494)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
Wenn es ein korrekter String ist, ist immer min. das \0 enthalten. Du 
willst kopieren und nicht sortieren.

void kopieren(char *ziel, char *quelle, char eot)
{
  do{
    *ziel++ = *quelle;
  } while(*quelle++ != '\0');
  //} while(*quelle++ != eot);
}

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also erstmal, das mit diesem Flag braucht man in C nicht, ist ja nicht 
Pascal. Man kann einfach "break" nehmen.
void kopiere_zeichen(char *ziel, const char *quelle, char eot)
{
  for(;;)
  {
    char zeichen=*quelle++;
    if(zeichen!=eot)
    {
      *ziel++=zeichen;
    }
    else
    {
      *ziel='\0';
      break;
    }
  }
}

Besser ist es allerdings, wenn man solche Stringfunktionen gleich mit 
Längencheck macht. n ist dabei die Größe des Zielbuffers, damit man 
keinen buffer overflow baut. Zudem kann man auch einfach eine Funktion 
aus der Standard Library nehmen, da muß man nur für die terminierende 
Null noch etwas dranbasteln:
#include <string.h>

void kopiere_zeichen(char *ziel, const char *quelle, int eot, size_t n)
{
    if (n-- == 0)
        return;
    
    ziel = memccpy(ziel, quelle, eot, n);
    if (ziel != NULL)
    {
      *ziel = '\0';
    } else
    {
      ziel[n] = '\0';
    }
}

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha schrieb:
> Geht das so

Sieht richtig aus. Ich würde aber das "ready" durch "fertig" ersetzen.
Das trifft den Sinn besser und passt sprachlich besser zum restlichen
Code.

> oder gibt es eine elegantere Lösung?

Was man als elegant empfindet, hängt ein wenig vom persönlichen
Geschmack ab. Mein Geschmack empfindet dieses als elegant:

void kopiere(char *ziel, char *quelle, char eot) {
  while((*ziel++ = *quelle++) != eot);
  *ziel = '\0';
}

Nop schrieb:
> ziel = memccpy(ziel, quelle, eot, n);

Seit wann hat memcpy aus der Standardbibliothek 4 Argumente?

Autor: Nop (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Yalu X. schrieb:

> Nop schrieb:
>> ziel = memccpy(ziel, quelle, eot, n);
>
> Seit wann hat memcpy aus der Standardbibliothek 4 Argumente?

Gar nicht. Gegenfrage: wo siehst Du memcpy? :-)

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Nop schrieb:
>> Seit wann hat memcpy aus der Standardbibliothek 4 Argumente?
>
> Gar nicht. Gegenfrage: wo siehst Du memcpy? :-)

Die Frage ist berechtigt. Ja, ich habe das zweite c übersehen :)

Zu beachten ist allerdings, dass memccpy nicht Teil der
ISO-Standardbibliothek, sondern eine POSIX-Erweiterung ist.

: Bearbeitet durch Moderator
Autor: Mikro 7. (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Was man als elegant empfindet, hängt ein wenig vom persönlichen
> Geschmack ab. Mein Geschmack empfindet dieses als elegant:
 
void kopiere(char *ziel, char *quelle, char eot) {
  while((*ziel++ = *quelle++) != eot);
  *ziel = '\0';
}

Das ist aber nicht die Funktion des TS.

Autor: Keiner N. (nichtgast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mikro 7. schrieb:
> Das ist aber nicht die Funktion des TS.

Wow, bloß nicht zu viele Informationen geben. Nicht, dass noch einer 
einfach nachvollziehen kann was du meinst.

dann eben so:
void kopiere(char *ziel, char *quelle, char eot) {
  while ((*ziel++ = *quelle++) != eot);
  *(ziel-1) = '\0';
}

Puh, ist ja völlig anders geworden.

Was trozdem fehlt, ist die Überprüfung auf ein Ende des Strings. Hat der 
TE aber auch nicht drin. Was wenn der eot gar nicht vorkommt.

: Bearbeitet durch User
Autor: Mikro 7. (mikro77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner N. schrieb:
> Wow, bloß nicht zu viele Informationen geben.

Das war Absicht: "Persönlicher Geschmack" ist nicht unbedingt 
"übersichtlich". Besser gefällt mir daher:
void kopiere(char *ziel,const char *quelle,char eot) 
{
    while (*quelle != eot)
        *ziel++ = *quelle++ ; 
    *ziel = '\0';
}

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

erstmal Danke für die Antworten. Mir geht es darum, in einem vorhanden 
String einen Bereich zu kopieren, Bus ein definiertes Trennzeichen 
erscheint. Habe mich vielleicht etwas ungünstig ausgedrückt.
Mein Problem bestand darin, Die Pointer zu interpretieren. Aber die 
Lösung von Mikro77 sieht super aus.

Gruss Sascha

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.