2017-02-13 112 views
1

我正在使用Keil編譯器編寫一個單片機程序。該程序創建了幾個CSV-Like字符串(記錄線)。例如「A; 001;錯誤; C05; ... \ n」 爲了節省空間,我現在想通過記錄差異來減少數據。 因此,我保存最後一次記錄的行並將其與新的行進行比較。如果一列中的值相同,我想省略它。例如: 「A; 001;誤差; C05; ... \ n」 < - 以前的日誌使用KEIL編譯器令牌化C中的多個字符串

「A; 002;誤差; C06; ... \ n」 < - 新登錄

將導致「; 002 ;; C06; ... \ n」

起初我只包括<string.h>,並使用'strtok'來逐步通過我的CSV行。由於我需要比較2個字符串/行,所以我需要在2個不同的字符串上同時使用它,這是行不通的。所以我切換到「strtok_r」這似乎並不是在所有的工作:

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

這只是給了我奇怪的行爲。通常,對'strtok_r'的第二次調用只返回一個NULL,並且循環被留下。 那麼是否有另一種達到理想行爲的方式?

編輯:

爲了澄清我的意思,這就是我目前試圖去工作: 我輸入(m_cMeasureLogLine)是「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); 
    } 
} 

功能是一個更大的嵌入式項目,所以我沒有控制檯輸出,但使用調試器來檢查我的變量的內容的一部分。在上面的例子中,第一次調用'strtok_r'token1之後是'M',這是正確的。然而,第二次調用後(在循環中)令牌1變爲0x00000000(NULL)。

如果我改用 'strtok的',而不是:

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

循環迭代就好了。但是這樣我就無法一次處理兩個字符串,並按列方式比較值。

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

我們需要更多的代碼之前,我們可以告訴你,最好是[MCVE]和* *肯定的聲明和所涉及的變量的任何適用的初始化。 –

+0

請參閱http:// stackoverflow。com/questions/15961253/c-correct-usage-of-strtok-r並比較你在做什麼 –

+0

(我的猜測是你沒有通過char **作爲strtok_r()的最後一個參數) –

回答

2

您需要將指針傳遞給一個有效char*strtok_r()最後一個參數:

string.h中的功能被聲明。你傳遞的是一個指針,指針指向一個指針,但是它是一個NULL(因爲它是一個全局作用域的變量,沒有賦值),所以當strtok_r()去存儲時,它將指針指向你傳入的指針它試圖寫地址0x00000000。

的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); 
}