strncat
標準ライブラリの関数に奇妙な動作が見string.h
られます。何が起こっているのかを理解する助けが必要です。
私の問題の核心は、ファイルの行を末尾の改行ターミネータなしで文字列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);
ラインに絞り込んだと思います。myが十分に高いのに、先行line
する s が含まれている理由がわかりません。BUFFER_SIZE