2017-02-13 4 views
1

Ich schreibe ein Mikrocontroller-Programm mit dem Keil-Compiler. Das Programm erstellt mehrere CSV-ähnliche Strings (Logging-Lines). Zum Beispiel "A; 001; ERROR; C05; ... \ n" Um Platz zu sparen, möchte ich jetzt die Daten reduzieren, indem ich nur die Unterschiede protokolliere. Deshalb speichere ich die letzte geloggte Zeile und vergleiche sie mit der neuen. Wenn ein Wert in einer Spalte derselbe ist, möchte ich ihn einfach weglassen. Zum Beispiel: "A; 001; ERROR; C05; ... \ n" < - vorherige LogToken mehrere Zeichenketten in C mit KEIL Compiler

"A; 002; ERROR; C06; ... \ n" < - neue Log

würde zu "; 002 ;; C06; ... \ n"

Zuerst habe ich einfach <string.h> eingefügt und 'strtok' benutzt, um durch meine CSV-Zeile zu gehen. Da ich 2 Strings/Lines vergleichen muss, müsste ich es gleichzeitig auf 2 verschiedenen Strings verwenden, was nicht funktioniert. Also wechselte ich zu ‚strtok_r‘, das scheint gar nicht zu arbeiten:

token1 = strtok_r(m_cActLogLine, ";", pointer1); 
while (token1 != NULL) { 
    token1 = strtok_r(NULL, ";", pointer1); 
} 

Das gibt mir nur seltsames Verhalten. Normalerweise gibt der zweite Aufruf von 'strtok_r' nur einen NULL zurück und die Schleife bleibt übrig. Gibt es vielleicht eine andere Möglichkeit, das gewünschte Verhalten zu erreichen?

EDIT:

Um zu klären, was ich meine, ist das, was ich zur Zeit an der Arbeit zu machen versuche: Mein Input (m_cMeasureLogLine) ist „M; 0001; 001; 01; 40; 1000,00; 0,00; 1000,00; 0,00; 360,00; 0,00; 400,00; 24,90; 400,00; -9999,00; -9999,00; -9999,00; 0; LED ;;;;; 400,00; 34,40; 25,41; 27,88; 29,01; 0,00; 0,00; 0,00; - 100,00; 0,00; -1000,00; -1000,00; -103,032; -70,192; 19; 8192,00; 0,00; 0; "

char m_cActLogLine[MAX_SIZE_PARAM_LINE_TEXT]; 
char* token1; 
char* token2; 
char** pointer1; 
char** pointer2; 
void vLogProtocolMeasureData() 
{ 
    strcpy(m_cActLogLine, m_cMeasureLogLine); 
    token1 = strtok_r(m_cActLogLine, ";", pointer1); 
    while (token1 != NULL) { 
    token1 = strtok_r(NULL, ";", pointer1); 
    } 
} 

Die Funktion ist Teil eines größeren Projekts eingebettet, damit ich Konsolenausgabe nicht haben, aber verwenden Sie den Debugger den Inhalt meiner Variablen zu überprüfen. Im obigen Beispiel ist nach dem ersten Aufruf von 'strtok_r' token1 'M', was korrekt ist. Nach dem zweiten Aufruf jedoch (in der Schleife) wird Token 1 zu 0x00000000 (NULL).

Wenn ich stattdessen statt 'strtok' verwenden:

strcpy(m_cActLogLine, m_cMeasureLogLine); 
token1 = strtok(m_cActLogLine, ";"); 
while (token1 != NULL) { 
    token1 = strtok(NULL, ";"); 
} 

die Schleife läuft gut. Aber so kann ich nicht zwei Strings gleichzeitig verarbeiten und Werte spaltenweise vergleichen.

In string.h die Funktionen erklärt werden als:

extern _ARMABI char *strtok(char * __restrict /*s1*/, const char * __restrict /*s2*/) __attribute__((__nonnull__(2))); 
extern _ARMABI char *_strtok_r(char * /*s1*/, const char * /*s2*/, char ** /*ptr*/) __attribute__((__nonnull__(2,3))); 
#ifndef __STRICT_ANSI__ 
extern _ARMABI char *strtok_r(char * /*s1*/, const char * /*s2*/, char ** /*ptr*/) __attribute__((__nonnull__(2,3))); 
#endif 
+2

Wir werden mehr Code benötigen, bevor wir Sie beraten können, vorzugsweise eine [MCVE] und * sicher * die Erklärungen und ggf. Initialisierungen der beteiligten Variablen. –

+0

Siehe http: // stackoverflow.com/questions/15961253/c-korrekt-verwenden-von-strtok-r und vergleichen Sie mit dem, was Sie tun –

+0

(meine Vermutung ist, dass Sie nicht ein Char ** als letzter Parameter von strtok_r() übergeben) –

Antwort

2

Sie benötigen einen Zeiger auf eine gültige char* für den letzten Parameter von strtok_r() passieren. Sie übergeben einen Zeiger auf einen Zeiger mit Zeiger1, aber es ist ein NULL (weil es eine globale Bereichsvariable ist, die keinen Wert zugewiesen ist), wenn strtok_r() geht, um es zu speichern, ist Zeiger auf die Adresse zu einem Zeiger, den Sie übergeben Es versucht, etwas zu schreiben, um 0x00000000 zu adressieren.

Try ...

char m_cActLogLine[MAX_SIZE_PARAM_LINE_TEXT]; 
char* token1; 
char* pointer1; 

void vLogProtocolMeasureData() 
{ 
    strcpy(m_cActLogLine, m_cMeasureLogLine); 
    token1 = strtok_r(m_cActLogLine, ";", &pointer1); 
    while (token1 != NULL) { 
    token1 = strtok_r(NULL, ";", &pointer1); 
}