簡體   English   中英

使用strsep在C中解析字符串(替代方法)

[英]Parsing a string in C with strsep (alternative methods)

我想解析一個字符串,我使用strsep函數:

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

int main()
{

  char str[] = "Marco:Q:2F7PKC";
  char *token1, *token2, *token3;
  char *r = malloc(30);

  strcpy(r, str);

  token1 = strsep(&r, ":");
  token2 = strsep(&r, ":");
  token3 = strsep(&r, ":");

  printf("tok1 = %s\n", token1);
  printf("tok2 = %s\n", token2);
  printf("tok3 = %s\n", token3);

  free(r);

  return 0;

}

該函數完成了它的工作,但是如果我啟動valgrind ,分配的字符串char * r沒有正確釋放( 肯定會丟失:1個塊中的30個字節 )。

我想知道為什么以及是否有其他方法可以做同樣的事情,也許沒有呼叫strsep

我用valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out調用valgrind valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./a.out

strsep覆蓋其第一(指針到指針)參數的目標,這樣你就失去了指針malloc “d緩沖區的基礎。 事實上,如果你確實放了一個printf("%p\\n", r); 就在free之前,你會發現你正在釋放一個無效的空指針。

簡單的解決方案是引入一個額外的變量來保持指針並在完成后free它。 習慣用法是

char *r = strdup("Marco:Q:3F7PKC");
// check for errors

char *tok = r, *end = r;
while (tok != NULL) {
    strsep(&end, ":");
    puts(tok);
    tok = end;
}

free(r);

我想稍微簡化Fred Foo的回復:

char *end, *r, *tok;

r = end = strdup("Marco:Q:3F7PKC");
assert(end != NULL);

while ((tok = strsep(&end, ":")) != NULL) {
    printf("%s\n", tok);
}

free(r);

它給出了相同的結果。 但值得一提的是, strsep(3)將分隔符存儲到end變量后存儲下一個值並返回當前值(轉換為tok變量)。

strsep函數更新其第一個參數(因此它指向它找到的標記之后)。 您需要將malloc返回的值存儲在單獨的變量中並釋放此變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM