Teilstring in einen anderen kopieren

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
darkwin
Beiträge: 26
Registriert: So Aug 08, 2021 4:37 pm

Teilstring in einen anderen kopieren

Beitrag von darkwin » So Aug 15, 2021 1:09 pm

Hallo, ich habe ein Char das auch 0 Bytes enthalten kann.
Die Daten kommen so von einem Gerät über die Serielle Schnittstelle.

Nun möchte ich einen Teil davon in einen anderen Char kopieren.

In meinem Beispiel kopiere ich 3 Byte in das Char payload.

Code: Alles auswählen

#include <stdio.h>
#include <stdlib.h>

int main()
{
   char text[80] = {0x66, 0x58, 0x53, 0x4D, 0x0, 0x3, 0x1A, 0x00, 0x50, 0x01, 0x65, 0x58, 0x4D, 0x53, 0x00, 0x03, 0x6B, 0x00, 0x00, 0x01};
   char payload[10];

   payload[0] = text[6]; // 0x1A
   payload[1] = text[7]; // 0x00
   payload[2] = text[8]; // 0x50

   return 0;
};
Ich frage mich ob das ganze eleganter geht oder wirklich so umständlich programmiert werden muss.

Das funktioniert so nicht.

Code: Alles auswählen

payload = {text[6], text[7], text[7]};
Mit der string.h Bibliothek konnte ich das nicht lösen.

nufan
Wiki-Moderator
Beiträge: 2538
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Teilstring in einen anderen kopieren

Beitrag von nufan » So Aug 15, 2021 8:04 pm

Solange Quell- und Zielspeicher fortlaufend sind, kannst du die Funktion memcpy() verwenden:
https://www.proggen.org/doku.php?id=c:lib:string:memcpy

Z.B. so:

Code: Alles auswählen

memcpy(payload, text + 6, 3);

darkwin
Beiträge: 26
Registriert: So Aug 08, 2021 4:37 pm

Re: Teilstring in einen anderen kopieren

Beitrag von darkwin » Mo Aug 16, 2021 11:25 am

Vielen Dank. "memcpy" wird es sein. Die Funktion hatte ich mir noch gar nicht angesehen.

Josef Wismeth
Beiträge: 5
Registriert: So Sep 05, 2021 5:08 pm
Wohnort: Oberpfalz

Re: Teilstring in einen anderen kopieren

Beitrag von Josef Wismeth » Mo Sep 13, 2021 10:13 am

Hallo!

Der Beitrag ist zwar schon älter, aber hier ein kleines Beispiel wie man das mit einer Funktion lösen kann:

Code: Alles auswählen

#include <stdio.h>
#include <string.h> 
#include <stdlib.h>

void strpart(char quelle[], char ziel[], int beginn, int menge)
{
 int tads, laenge, i, j = 0;

 tads = beginn;
 laenge = tads + menge - 1;
 
 for (i = tads; i <= laenge; i++)
 {
  ziel[j] = quelle[i];
  ziel[j + 1] = '\0'; 
  j++;
 }
} 


void ZeigeArray(char text[], int laenge)
{
 int i;
 
 char ASCII_Steuerzeichen[33][60] = {
"00 NULL, no Operation, NUL keine Operation",
"01 Start of Heading SOH Vorspannanfang",
"02 Start of Text STX Textanfang",
"03 End of Text ETX Textende",
"04 End of Transmission EOT Übertragungsende",
"05 Enquiry ENQ Stationsanruf",
"06 Acknowledge ACK Bestaetigung",
"07 Bell BEL Klingel",
"08 Backspace BS Rückwaertsschritt",
"09 HT Horizontal Tabulation",
"10 Line Feed LF Zeilenvorschub",
"11 Vertical Tabulation VT",
"12 Form Feed FF Formularvorschub, Schirm loeschen",
"13 Carrige Return CR Wagenruecklauf",
"14 Shift out SO Umschalten aus",
"15 Shift in SI Umschalten ein",
"16 Data Link Escape DLE Austritt aus der Datenverbindung",
"17 Device Control 1 DC1 Geraetesteuerung 1",
"18 Device Control 2 DC2 Geraetesteuerung 2",
"19 Device Control 3 DC3 Geraetesteuerung 3",
"20 Device Control 4 DC4 Geraetesteuerung 4",
"21 Negative Acknowledge NAK Fehlermeldung",
"22 Synchronous Idle SYN Synchronisierung",
"23 End of Transm.Block ETB Datenblockende",
"24 Cancel CAN ungueltig",
"25 End of Medium EM Datentraegerende",
"26 Substitute SUB Character Zeichen ersetzen",
"27 Escape ESC Ruecksprung",
"28 File Separator FS Filetrennung",
"29 Group Separator GS Gruppentrennung",
"30 Record Separator RS Untergruppentrennung",
"31 Unit Separator US Einheitentrennung",
"32 Space SP Leerschritt"};
 
 
 for (i = 0; i < laenge; i++)
    {
     printf("i=%2d dec=%03d hex=%03x  ", i, text[i], text[i]);   
     if((text[i] > 32) && (text[i] < 127))
      printf(" char= %c\n", text[i]); 
      else printf(" %s\n", ASCII_Steuerzeichen[text[i]]);   
    }     
   
}

int main()
{
   char text[20] = {0x66, 0x58, 0x53, 0x4D, 0x00,
                    0x03, 0x1A, 0x00, 0x50, 0x01, 
                    0x65, 0x58, 0x4D, 0x53, 0x00,
                    0x03, 0x6B, 0x00, 0x00, 0x01};
   char payload[20] = {0};
 
   int start, laenge;

/*
   payload[0] = text[6]; // 0x1A
   payload[1] = text[7]; // 0x00
   payload[2] = text[8]; // 0x50
*/



   printf("Inhalt Array text:\n");
   ZeigeArray(text, 20);
   
   start = 6;
   laenge = 3;
   
   printf("\nKopiere ab Zeichen %d %d Zeichen nach payload:\n", start, laenge);
      
   strpart(text, payload, start, laenge); 
   ZeigeArray(payload, laenge);
   
   return 0;
};
Die Funktion "strpart()" hat aber einen kleinen Hacken. Sie überprüft nicht ob bei der Angabe der Parameters 3 und 4, also
ab wann kopier wird und wie viele Zeichen, nicht auf Überlauf. Sollten da Fehler auftreten droht ein Crash. Eventuell also
einen 5ten Parameter zur Limitierung einbauen. dann könnte diese Funktion so aussehen:

Code: Alles auswählen

void strpart(char quelle[], char ziel[], int beginn, int menge, int kopierlimit)
{
 int tads, laenge, i, j = 0;

 tads = beginn;
 laenge = tads + menge - 1;
 
 if((beginn >= 0) && (beginn < kopierlimit) && (laenge < kopierlimit) &&(laenge >=  0 ) )
 for (i = tads; i <= laenge; i++)
 {
  ziel[j] = quelle[i];
  ziel[j + 1] = '\0'; 
  j++;
 }
} 
Wird in dem letzten Beispiel bei beginn oder menge ein Fehler gemacht, dann wird nicht kopiert.
Rein theoretisch könnte man ja beider Länge des zu kopierenden Teils einen negativen Wert eingeben.
Im diesen Beispiel hat der Parameter 5(kopierlimit) den Wert 20, da ja das Array Text 20 Byte lang ist.

Josef Wismeth
Beiträge: 5
Registriert: So Sep 05, 2021 5:08 pm
Wohnort: Oberpfalz

Re: Teilstring in einen anderen kopieren

Beitrag von Josef Wismeth » Mo Sep 13, 2021 12:37 pm

Ein kleiner Nachschlag:

Hier ein Beispiel wie man so etwas mit strncpy macht:

Code: Alles auswählen

#include <stdio.h>
#include <string.h>


char zfolge[60] = "Der schlaue Mueckes jagt den blassen Wittgi.";
/*                           1         2         3         4         5 *
 *                 012345678901234567890123456789012345678901234567890 */
void  MIDS(char *erge, char *zfolge, int beginn, int ende)
    {
    int laenge;
    laenge = (ende - beginn) + 1;
    strncpy( erge, zfolge + beginn, laenge);
    }

int main(int argc, char **argv)
{

char puffer[65] = {0};
int lge;

    printf("\n%s\n",zfolge );
    printf("012345678901234567890123456789012345678901234567890");
	printf("\nUrsprung: %s\n", zfolge + 15 );
    printf("          012345678901234567890123456789012345678901234567890");
	MIDS( puffer, zfolge, 5, 12);
    printf( "\nErgebnis: %s\n", puffer);
    
	lge = strlen(puffer);
	printf( "\nLaenge: %d Zeichen", lge);

 
  return 0;

}

Antworten