C言語で,POSIXに規定されているlfind関数を使って,配列内の文字列の検索を試しています。

マッチはできるのですが,肝心のマッチした文字列を参照できなくて困っています。

検証環境は以下のとおりです。

  • Ubuntu 16.04
  • gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609

サンプルコードを以下に示します。配列要素内の,"break"にマッチします。

/// \file find_array.c
#include <stdio.h>
#include <string.h>
#include <search.h>

int main(void) {
    char *tab[] = {"auto", "break"};
    size_t nel = sizeof(tab)/sizeof(tab[0]);
    // char *target = "break";
    char *entry = lfind(&(void *){"break"}, tab, &nel, sizeof(tab[0]), (int (*)(const void *, const void*))strcmp);

    if (entry) {
        printf("found: %p:%s\n", (void *)&tab[1], tab[1] );
        printf("found: %p:%s\n", entry, entry);
    } else {
        puts("NOT FOUND");
    }

    // 数値の場合
    // int tab[] = {1, 2, 3};
    // size_t nel = sizeof(tab)/sizeof(tab[0]);
    // void *entry = lfind(&(int){2}, tab, &nel, sizeof(tab[0]), (int (*)(const void *, const void*))strcmp);
    // アクセスは間接参照を使う
    // printf("found: %d\n", *(int *)entry);

    return 0;
}

このfind_array.cをコンパイルして実行すると,以下のような出力が得られます。

found: 0x7ffddffe2748:break
found: 0x7ffddffe2748:�@

lfindはマッチした場合に,マッチした要素のアドレスを返却しており,実際,上記の結果の通り元の配列の該当要素と同じアドレスでした。

そのまま文字列も参照できるかと思ったのですが,ダメでした (*&やキャストなどでいろいろentry変数へのアクセスのしかたを試しても結局ダメ)。何か,根本的なところの理解が足りていないような気がしています。

幸い,非NULLのポインターを取得できておりマッチしているかどうかはわかるので,検索に使ったキーを使えば,間接的にマッチした文字列は参照できます。

しかし,できることならば,マッチした結果 (entry変数) からマッチした値を参照したいのです。何かアクセスのしかたに工夫が必要なのでしょうか?どうかご教授お願いします。

なお,サンプルコードの下の方に掲載している通り,配列が数値の場合は間接参照演算子*で参照することで,マッチした値にアクセスできました。