2016-12-10 217 views
0

我試圖通過定界符與此代碼字符串分割到兩個字符串由分隔符

int indexOf(char *msg, char c) { 
    int i; 
    for (i = 0; msg[i] != '\0'; i++) { 
     if (msg[i] == c) 
      return i; 
    } 
    return -1; 
} 

char *substring(char *msg, int startIndex, int endIndex) { 
    int length = endIndex - startIndex; 
    char *input = (char *)malloc(length * sizeof(char) + 1); 

    int i; 
    for (i = startIndex; i != endIndex; i++) { 
     input[i - startIndex] = msg[i]; 
    } 
    input[endIndex] = '\0'; 

    return input; 
} 

一個字符串分割成兩個串在main我:

index = indexOf(msg, ':'); 

first = substring(line, 0, index - 1); 
second = substring(line, index + 2, strlen(line)); 

這段代碼產生正確的輸出,當我測試它與valgrind。在第二個變量中分配的子字符串會產生一個錯誤。

這個函數的問題在哪裏?有另一種方法將字符串拆分爲兩個字符串嗎?

char *msg = readMessage(stdin); 
index = indexOf(msg, '\n'); 
char *line, *first, *second; 

line = substring(msg, 0, index); 

末的valgrind Address 0x5203a52 is 5 bytes after a block of size 13 alloc'd

編輯:對於

index = indexOf(line, ':'); 

另一個bug現在Valgrind的錯誤是在子線input[endIndex] = '\0';

Invalid write of size 1 

編輯:我的代碼解決方案有兩個錯誤

在主

index = indexOf(msg, ':'); 

應該

index = indexOf(line, ':'); 

,並在子

input[endIndex] = '\0'; 

應該

input[length] = '\0'; 

感謝所有

+0

什麼錯誤?順便說一句,不要施加'malloc'返回。 – coredump

+0

您正在施放'malloc',如果不是'strlen(msg)'? '線路'在哪裏進來? – t0mm13b

+0

可能會查看'strtok'?始終將指針變量初始化爲NULL,以保持完整性。你有調試過嗎? readMessage的代碼是什麼?我認爲從函數返回的指針變量會因爲在函數的堆棧中分配而被破壞。 – t0mm13b

回答

1

有在你的代碼中的一些問題:

  • input[endIndex] = '\0';使用錯誤的索引。它應該是input[length] = '\0';

  • main(),你不應該暗示關於indexOf的返回值的假設。張貼的代碼調用未定義的行爲,如果:line發現:

這裏是一個更安全的版本:

int index = indexOf(line, ':'); 
if (index >= 0) { 
    // found the `:` separator 
    char *first = substring(line, 0, index); 
    if (line[index + 1] == ' ') { 
     index++; // skip the space after the : 
    } 
    char *second = substring(line, index + 1, strlen(line)); 
    ... 
} 

可以使用strcspn()代替indexOf用更少的測試,以提取部分:

char *msg = readMessage(stdin); 
size_t index = strcspn(msg, "\n"); 
char *line = substring(msg, 0, index); 
... 

strcspn()返回高達但不包括其參數字符串中的字符d。如果字符存在(size_t類型,而不是int),它將返回與indexOf()相同的值,如果不是,則返回字符串的長度,這是您希望的情況。

+0

檢查一行是否有':'我在其他代碼中有 – mardon

+0

@mardon:4386427實際上在'main'函數中發現了一個錯誤。它應該是'index = indexOf(line,':');' – chqrlie

1
index = indexOf(msg, ':'); 
       ^^^ 
       line ? 

這裏

second = substring(line, index+2, strlen(line)); 

您認爲該行比指數+ 2更長。在malloc呼叫中應該檢查一些內容以避免零。換句話說 - 如果分隔符是最後一個字符,則會遇到問題。

您應該添加由malloc

if (!input) 
{ 
    // Print error message 
    exit(1); 
} 

BTW返回值的檢查 - 看看strdupmemcpystrncpy

+0

請不要提倡使用'strncpy'。 https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/ – chqrlie

+0

@chqrlie - 終止問題是正確的。我不確定任何標準的C函數都能解決這個問題 - 你知道嗎?您的鏈接通過編寫使用C++的自定義函數來解決此問題。在C語言中使用'strncpy'來執行相同的操作。 – 4386427