2015-02-08 14 views
1

我對C很新,想知道我是否可以得到一些幫助!我一直在爲這個錯誤工作+15小時。創建子字符串的C錯誤 - 可能是內存錯誤?

所以,這個程序是一個標記器。

基本上,該程序應該採取一個字符串或「標記流」,並將其分解爲「標記」。 「標記」是一個字,十六進制int,八進制int,十進制int,浮點int或符號的字符串。

我發佈的代碼只是代碼出現問題的代碼,我的程序的另一部分是創建令牌的代碼。

下面代碼的工作原理是這樣的:它需要一個「令牌流」,然後從該流找到下一個令牌。一旦完成,它將創建「標記流」的子字符串減去新標記,並將其作爲新的「標記流」返回。

本質上,當字符串"0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /"通過時,除"jlhg kl(/j jlkh 'no thank you' /"通過之外,程序將正確執行所有操作。一旦通過我的程序,就會創建一個"jlhg"令牌,然後再將它添加到令牌流的。因此,要分解的新令牌流變爲" kl(/j jlkh 'no thank you'/jlhg",其中jlhg在最後添加,而之前沒有。它再一次做了這個奇怪的事情,之後,但用"kl"代替。

它只在非常奇怪的條件下這樣做,所以我不確定原因。我在整個程序中都放置了打印語句,除了貌似沒有出現的地方之外,事情正常流轉,程序只會在最後添加這些語句。這我爲什麼我覺得它可能可能是一個內存問題,但我絕對不知道從哪裏去。

任何幫助將非常感謝!

編輯:如果傳遞字符串 「陣列[XYZ] + = PI 3.14159e-10 A12B」 輸出應爲:

字 「陣列」

左大括號 「[」

詞 「XYZ」

右括號 「]」

plusequals 「+ =」

單詞 「PI」

浮動 「3.14159e-10」

詞 「A12B」

我TokenizerT是這樣的:

struct TokenizerT_ 
{ 
    char *tokenType; 
    char *token; 
}; 

typedef struct TokenizerT_ TokenizerT; 

相關代碼:

/* 
* TKNewStream takes two TokenizerT objects. 
* It will locate the index of the end of the last token, 
* and create a substring with the new string to be tokenized. 
* @tokenStream: old token stream 
* @newToken: new token created from old token stream 
* 
*/ 

char *TKGetNextStream(char *tokenStream, char *newToken) 
{ 
    int i, 
     index = 0, 
     count = 0; 

    char last = newToken[strlen(newToken)-1]; 

    for(i = 0; i < strlen(newToken); i++) 
    { 
     if(newToken[i] == last) 
     { 
      count++; 
     } 
    } 

    for(i = 0; i < strlen(tokenStream); i++) 
    { 
     if(tokenStream[i] == last && count == 1) 
     { 
      index = i + 1; 
      break; 
     } 
     else if(tokenStream[i] == last) 
     { 
      count--; 
     } 
    } 

    char *ret = malloc(sizeof(char)*(strlen(tokenStream) - index)); 

    for(i = 0; i < strlen(tokenStream) - index; i++) 
    { 
     ret[i] = tokenStream[i+index]; 
    } 

    return ret; 
} 

/* 
* This is my main 
*/ 
int main(int argc, char **argv) 
{ 

    char *string = "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /"; 

    TokenizerT *newToken = malloc(sizeof(struct TokenizerT_)), 
       *tokenStream = malloc(sizeof(struct TokenizerT_)); 

    tokenStream->token = string; 

    while(newToken != NULL) 
    { 
     newToken = TKCreate(TKGetNextToken(tokenStream)); 

     if(newToken != NULL) 
     { 
      tokenStream->token = TKGetNextStream(tokenStream->token, 
               newToken->token); 

      printf("%s \"%s\"\n", 
        newToken->tokenType, 
        newToken->token); 
     } 
    } 

    TKDestroy(newToken); 

    return 0; 

} 
+0

是您的原代碼,以便格式錯誤?這本身會使其很難調試。 – 2015-02-08 18:05:25

+0

這個'TokenizerT * firstTK = malloc(sizeof(struct TokenizerT_)),* newTK = malloc(sizeof(struct TokenizerT_)),* tmp;'是一個非常糟糕的主意,因爲沒有人會期望'malloc'調用thre,你永遠不會檢查你的'malloc'的返回值。 – 2015-02-08 18:08:14

+0

@iharob嚴格格式化如何?像我的代碼結構不好?就像我說的,我對C和編程一般都很陌生...... 如何檢查malloc的返回值? – kd1994 2015-02-08 18:11:24

回答

1

ret中創建的字符串未正確空終止。所以所有處理字符串的函數都會假設它繼續下去,直到在分配的內存之後發現下一個隨機的零字節。

爲了解決這個問題分配的空間多了一個字節爲ret,並設置爲零,或使用現有的功能就像strdup()複製的字符串:

ret = strdup(tokenStream + index); 
+0

我太新了用戶,不滿意你的答案,但是這很有效!非常感謝!! – kd1994 2015-02-08 19:38:29

+0

@ kd1994 - 我會爲你點亮它。 – ryyker 2015-02-08 19:53:36