私はCでAdvent of Codeの問題を解決していましたが、私は理解できないことにヒットしました。私のCは非常に錆びており、私はこれがCコードの素晴らしい例ではないことを知っています。私は、このプログラムを、私を混乱させるような行動を示す最小のセクションまで切り離しました。なぜstrtokは間違った数のトークンを返しますか?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ae_load_file_to_memory(const char *filename, char **result)
{
int size = 0;
FILE *f = fopen(filename, "rb");
if (f == NULL)
{
*result = NULL;
return -1;
}
fseek(f, 0, SEEK_END);
size = ftell(f);
fseek(f, 0, SEEK_SET);
*result = (char *)malloc(sizeof(char) * (size + 1));
if (size != fread(*result, sizeof(char), size, f))
{
free(*result);
return -2;
}
fclose(f);
(*result)[size] = 0;
return size;
}
int main(void)
{
const char delim = '\n';
int fill_index = 0;
char *token = NULL;
char *content = NULL;
ae_load_file_to_memory("input.txt", &content);
token = strtok(content, &delim);
while (token != NULL)
{
fill_index++;
token = strtok(NULL, &delim);
}
printf("Fill index %d\n", fill_index);
}
このコードは、ディスクからファイルを読み取り、改行文字を区切り文字として使用してトークンに分割します。トークンの最終printf
戻って正しい番号、しかし1044
、私はfill_index
の宣言に移動するmain
方法の開始を変更する場合:
int main(void)
{
int fill_index = 0;
const char delim = '\n';
...今strtok
戻って1050個のトークンを、それは間違っている。これが2つのファイルの唯一の違いです。私はMac OS X Sierraで動作しています。gcc --version
はそのApple LLVM version 9.0.0 (clang-900.0.38)
を報告しています。
私はどこかの記憶を踏みにじっていると確信しています。最初のバージョンは偶然にしか動作しません。しかし、私はその宣言を動かすことでそのような違いが生じるのではないかと思っています。誰でも何が起こっているのか説明できますか?
[ 'strtok'](第2引数http://en.cppreference.com/w/c/ string/byte/strtok)は、***ヌル終了**バイト文字列*です。単一の文字へのポインタではありません。 –
すべてのコンパイラの警告が有効になっていることを確認し、それを読んでください。これはまったくまったくコンパイルすべきではありません。 – unwind
@unwind 'gcc -Wall'はきれいにコンパイルされました。 – TarkaDaal