我在string.h
標準庫中的strncat
函數中看到一些奇怪的行爲,並希望能夠幫助您理解正在發生的事情。strncat看起來像它保存呼叫數據?
我的問題的關鍵是在功能我創建了名爲readLine
與返回的文件作爲char *
字符串的行末尾沒有新行終結的目的。這個功能看起來是這樣的:
char * readLine(FILE * fp) {
char * chunk = NULL;
char * line = NULL;
int count = 0;
// iterate through chunks of a line until we reach the end (or an error)
while (fgets((chunk = malloc(sizeof(char) * BUFFER_SIZE)), BUFFER_SIZE, fp) != NULL) {
// realloc on a null pointer works like malloc
line = realloc(line, ++count * BUFFER_SIZE * sizeof(char));
printf("chunk's contents: %s\n", chunk);
// does chunk contain the end of a line?
if(strchr(chunk, '\n') == NULL) {
// concatenate string parts and continue loop
strncat(line, chunk, strlen(chunk) + 1);
free(chunk);
} else {
// we want to return a \0 terminated string without the \n
// expected position of \n in chunk is ({length of chunk}-1)
chunk[(strlen(chunk) - 1)] = '\0';
// concatenate string parts
strncat(line, chunk, strlen(chunk) + 1);
printf("readLine line: %s\n", line);
free(chunk);
break;
}
}
return line;
}
我把它稱爲主在一個循環中,看起來像這樣:
FILE * fp = NULL;
if ((fp = fopen(FILE_PATH, "r")) != NULL) {
char * line = NULL;
while ((line = readLine(fp)) != NULL) {
printf("main line: %s\n\n", line);
free(line);
}
fclose(fp);
}
現在的古怪行爲來到我的#define BUFFER_SIZE 1000
定義。有了它設置一樣,我得到下面的輸出(這不是我想要的):
chunk's contents: I am on line 1
readLine line: I am on line 1
main line: I am on line 1
chunk's contents: Over here I am on line 2
readLine line: I am on line 1Over here I am on line 2
main line: I am on line 1Over here I am on line 2
chunk's contents: Line 3 here
readLine line: I am on line 1Over here I am on line 2Line 3 here
main line: I am on line 1Over here I am on line 2Line 3 here
chunk's contents: Look out for 4
readLine line: I am on line 1Over here I am on line 2Line 3 hereLook out for 4
main line: I am on line 1Over here I am on line 2Line 3 hereLook out for 4
chunk's contents: Johnny 5 alive!
readLine line: I am on line 1Over here I am on line 2Line 3 hereLook out for 4Johnny 5 alive!
main line: I am on line 1Over here I am on line 2Line 3 hereLook out for 4Johnny 5 alive!
但,如果我這一定義更改爲類似#define BUFFER_SIZE 20
,我得到我想要的輸出:
chunk's contents: I am on line 1
readLine line: I am on line 1
main line: I am on line 1
chunk's contents: Over here I am on l
chunk's contents: ine 2
readLine line: Over here I am on line 2
main line: Over here I am on line 2
chunk's contents: Line 3 here
readLine line: Line 3 here
main line: Line 3 here
chunk's contents: Look out for 4
readLine line: Look out for 4
main line: Look out for 4
chunk's contents: Johnny 5 alive!
readLine line: Johnny 5 alive!
main line: Johnny 5 alive!
我想我已經縮小到strncat(line, chunk, strlen(chunk) + 1);
線的問題。我不明白爲什麼當我的BUFFER_SIZE
足夠高時,前面的line
被包括在內。
嘗試在使用它們之前將緩衝區的memset設置爲0。 – 2013-03-01 20:28:36
請注意,您的'strncat'正在實現Schlemiel的Painter算法:http://www.joelonsoftware.com/articles/fog0000000319.html – ecatmur 2013-03-01 20:34:26
請注意,使用'line = realloc(line,...'你將有一個不可恢復的內存泄漏應該realloc失敗,並返回NULL(你應該檢查)。從API的角度來看,'realloc'函數是可怕的,其中一個原因是它會導致寫入不正確的代碼,例如 – hlovdal 2013-03-02 00:49:59