string.h
표준 라이브러리의 strncat
기능에서 이상한 동작을보고 있으며, 어떤 일이 벌어지고 있는지 이해하는 데 도움이되고 싶습니다.strncat은 호출간에 데이터를 보존하는 것처럼 보입니까?
내 문제의 핵심은 내가 뒤에 줄 바꿈 종료하지 않고 char *
문자열로 파일의 라인을 반환 목적으로 readLine
라고 만든 함수입니다. 이 함수는 다음과 같습니다
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
이 포함되는 이유를 이해할 수 없습니다.
버퍼를 사용하기 전에 버퍼를 0으로 설정하십시오. –
'strncat'은 Painter의 알고리즘 인 Schlemiel을 구현하고 있습니다 : http://www.joelonsoftware.com/articles/fog0000000319.html – ecatmur
'line = realloc (line, ...'으로 복구 할 수없는 메모리를 갖게 될 것입니다 누수가 realloc 실패하고 NULL을 반환해야합니다 (당신이 확인해야합니다.)'realloc' 함수는 API의 관점에서 볼 때 끔찍한데, 그 이유는 다음과 같습니다. – hlovdal