wprint_file_wtext_locale_cstdio

wprint_file_wtext_cstdioにロケールを追加指定できるwprint_file_wtext_locale_cstdioを作る。
main.cで、

と書く。

実行して、
実行して、

実行して、

test1.txtはUTF-8
test1.txtはUTF-8

test1.txtはUTF-8

test2.txtはEUC-JP。
test2.txtはEUC-JP。

test2.txtはEUC-JP。

Test/c/wprint_file_wtext_locale_cstdio/wprint_file_wtext_locale_cstdio/src/wprint_file_wtext_locale_cstdio at master · bg1bgst333/Test · GitHub

print_file_wtext_locale_cstdio

print_file_wtext_cstdioにロケールを追加指定できるprint_file_wtext_locale_cstdioを作る。
main.cで、

と書く。

実行すると、こうなる。
実行すると、こうなる。

実行すると、こうなる。
test1.txtは、

UTF-8で出力
UTF-8で出力

UTF-8で出力。
test2.txtは、

EUC-JPで出力
EUC-JPで出力

EUC-JPで出力される。

Test/c/print_file_wtext_locale_cstdio/print_file_wtext_locale_cstdio/src/print_file_wtext_locale_cstdio at master · bg1bgst333/Test · GitHub

wget_file_wtext_cstdio

fgetwsを使ったwget_file_wtext_cstdioを作る。
その前に、fgetsを使ったget_file_text_cstdioがロケールの影響を受けるか確認する。
main.cを、

/* ヘッダファイルのインクルード */
#include <stdio.h> /* 標準入出力 */
#include <stdlib.h> /* 標準ユーティリティ */
#include <string.h> /* 文字列処理 */
#include <locale.h> /* ロケール */
#include <sys/stat.h> /* ファイル状態 */
#include <wchar.h> /* ワイド文字 */
#include <iconv.h> /* 文字コード変換 */

/* 関数のプロトタイプ宣言 */
size_t get_file_size(const char *path); /* 関数get_file_sizeの宣言. */
char * get_file_text_cstdio(const char *path, char *text, size_t buf_size); /* 関数get_file_text_cstdioの宣言. */

/* main関数の定義 */
int main(void){

  /* 変数・ポインタの宣言・初期化. */
  size_t file_size_0; /* size_t型変数file_size_0. */
  size_t file_size_1; /* size_t型変数file_size_1. */
  size_t file_size_2; /* size_t型変数file_size_2. */
  char *buf0 = NULL; /* wchar_t型ポインタbuf0をNULLで初期化. */
  char *buf1 = NULL; /* wchar_t型ポインタbuf1をNULLで初期化. */
  char *buf2 = NULL; /* wchar_t型ポインタbuf2をNULLで初期化. */
  int ret_0 = 0;
  int ret_1 = 0;
  int ret_2 = 0;
  iconv_t iconv_dsc;
  char src_buf[256] = {0};
  char *src_ptr = NULL;
  char dest_buf[256] = {0};
  char *dest_ptr = NULL;
  size_t src_len = 0;
  size_t dest_len = 0;
  size_t ret_len = 0;

  /* test1.txtのサイズ取得. */
  file_size_0 = get_file_size("test1.txt"); /* get_file_sizeで"test1.txt"のサイズ取得. */

  /* メモリの確保. */
  buf0 = (char *)malloc((file_size_0 + 1) * sizeof(char)); /* mallocで((file_size_0 + 1) * sizeof(char))分のメモリ確保. */

  /* "test1.txt"からの入力をbuf0に格納. */
  get_file_text_cstdio("test1.txt", buf0, file_size_0 + 1); /* get_file_text_cstdioで"test1.txt"を読み込み. */
  ret_0 = strlen(buf0); /* 長さをret_0に格納. */
  buf0[ret_0] = '\0'; /* NULL終端 */

  /* buf0を出力. */
  printf("buf0 = %s\n", buf0); /* printfでbuf0を出力. */

  /* メモリの解放. */
  free(buf0); /* freeでbuf0を解放. */

  /* "ja_JP.UTF-8"ロケールのセット. */
  setlocale(LC_ALL, "ja_JP.UTF-8"); /* setlocaleでLC_ALL, "ja_JP.UTF-8"をセット. */

  /* test1.txtのサイズ取得. */
  file_size_1 = get_file_size("test1.txt"); /* get_file_sizeで"test1.txt"のサイズ取得. */

  /* メモリの確保. */
  buf1 = (char *)malloc((file_size_1 + 1) * sizeof(char)); /* mallocで((file_size_1 + 1) * sizeof(char))分のメモリ確保. */

  /* "test1.txt"からの入力をbuf1に格納. */
  get_file_text_cstdio("test1.txt", buf1, file_size_1 + 1); /* get_file_text_cstdioで"test1.txt"を読み込み. */
  ret_1 = strlen(buf1); /* 長さをret_1に格納. */
  buf1[ret_1] = '\0'; /* NULL終端 */

  /* buf1を出力. */
  printf("buf1 = %s\n", buf1); /* printfでbuf1を出力. */

  /* メモリの解放. */
  free(buf1); /* freeでbuf1を解放. */

  /* "ja_JP.EUC-JP"ロケールのセット. */
  setlocale(LC_ALL, "ja_JP.EUC-JP"); /* setlocaleでLC_ALL, "ja_JP.EUC-JP"をセット. */

  /* test2.txtのサイズ取得. */
  file_size_2 = get_file_size("test2.txt"); /* get_file_sizeで"test2.txt"のサイズ取得. */

  /* メモリの確保. */
  buf2 = (char *)malloc((file_size_2 + 1) * sizeof(char)); /* mallocで((file_size_2 + 1) * sizeof(char))分のメモリ確保. */

  /* "test2.txt"からの入力をbuf2に格納. */
  get_file_text_cstdio("test2.txt", buf2, file_size_2 + 1); /* get_file_text_cstdioで"test2.txt"を読み込み. */
  ret_2 = strlen(buf2); /* 長さをret_2に格納. */
  buf2[ret_2] = '\0'; /* NULL終端 */

  /* buf2を出力. */
  setlocale(LC_ALL, "ja_JP.UTF-8"); /* これがないと出力されない. */
  printf("buf2 = %s\n", buf2); /* printfでbuf2を出力. */

  /* 変換ディスクリプタの取得. */
  iconv_dsc = iconv_open("UTF-8", "EUC-JP"); /* iconv_openで"EUC-JP"から"UTF-8"への変換ディスクリプタを取得. */
  if (iconv_dsc == (iconv_t)-1){ /* -1なら. */
    printf("iconv_open error!\n"); /* "iconv_open error!"を出力. */
    free(buf2);
    return -1; /* -1を返して異常終了. */
  }

  /* 文字コード変換. */
  strcpy(src_buf, buf2);
  src_ptr = src_buf;
  src_len = strlen(src_buf);
  dest_ptr = dest_buf;
  dest_len = sizeof(dest_buf);
  ret_len = iconv(iconv_dsc, &src_ptr, &src_len, &dest_ptr, &dest_len); /* iconvで変換. */
  if (ret_len == -1){ /* -1なら. */
    printf("iconv error!\n"); /* "iconv error!"と出力. */
    free(buf2);
    return -2; /* -2を返して異常終了. */
  }

  /* dest_bufを出力. */
  printf("dest_buf = %s\n", dest_buf); /* printfでdest_bufを出力. */

  /* 変換ディスクリプタを閉じる. */
  iconv_close(iconv_dsc); /* iconv_closeでiconv_dscを閉じる. */

  /* メモリの解放. */
  free(buf2); /* freeでbuf2を解放. */

  /* プログラムの終了 */
  return 0; /* 0を返して正常終了. */

}

/* ファイルサイズの取得. */
size_t get_file_size(const char *path){

  /* 構造体の初期化. */
  struct stat sst = {0}; /* stat構造体sstを{0}で初期化. */

  /* ファイル情報の取得. */
  stat(path, &sst); /* statでpathで示されたファイルの情報をsstに格納. */

  /* ファイルサイズを返す. */
  return sst.st_size; /* returnでsst.st_sizeを返す. */

}

/* C標準入出力ライブラリ関数でテキストファイル入力. */
char * get_file_text_cstdio(const char *path, char *text, size_t buf_size){

  /* 構造体・ポインタの宣言・初期化. */
  FILE *fp = NULL; /* ファイルポインタfpをNULLで初期化. */
  char *ret; /* 格納した文字列ポインタret. */

  /* ファイルを開く. */
  fp = fopen(path, "r"); /* fopenでテキスト読み込みで開く. */
  if (fp != NULL){ /* fpがNULLでない時. */

    /* ファイルからテキストを読み込む. */
    ret = fgets(text, buf_size, fp); /* fgetsでfpから入力しtextに格納, 戻り値はretに格納. */

    /* fpを閉じる. */
    fclose(fp); /* fcloseでfpを閉じる. */

    /* retを返す. */
    return ret; /* returnでretを返す. */

  }

  /* ファイルを開けない場合は, NULLを返す. */
  return NULL; /* returnでNULLを返す. */

}

とすると、

影響受ける。
影響受ける。

影響受ける。
これも、test1.txtは元々UTF-8なのをUTF-8として、test2.txtは元々EUC-JPなのをEUC-JPとして、読み込んでるだけで文字コード変換ではない。
そのロケール文字コードに変換するわけではなく、一致していればその文字コードでしっかり読み込むだけ。

wget_file_wtext_cstdioは、

実行すると、

こちらも読み込める。
こちらも読み込める。

こちらも読み込める。

Test/c/wget_file_wtext_cstdio/wget_file_wtext_cstdio/src/wget_file_wtext_cstdio at master · bg1bgst333/Test · GitHub

wput_file_wtext_cstdio

fputwsを使ったwput_file_wtext_cstdioを作る。
その前に、fputsを使ったput_file_text_cstdioがロケールの影響を受けるか確認する。
main.cを、

/* ヘッダファイルのインクルード */
#include <stdio.h> /* 標準入出力 */
#include <locale.h> /* ロケール */

/* 関数のプロトタイプ宣言 */
int put_file_text_cstdio(const char *path, const char *text); /* 関数put_file_text_cstdioの宣言. */

/* main関数の定義 */
int main(void){

  /* 配列の初期化. */
  char japanese_str[] = "あいうえお\nかきくけこ\nさしすせそ"; /* '\n'が含まれた日本語文字列. */

  /* japanese_strを"test1.txt"に出力. */
  put_file_text_cstdio("test1.txt", japanese_str); /* put_file_text_cstdioでjapanese_strを"test1.txt"に出力. */

  /* ロケール"ja_JP.UTF-8"のセット. */
  setlocale(LC_ALL, "ja_JP.UTF-8"); /* setlocaleでLC_ALL, "ja_JP.UTF-8"をセット. */

  /* japanese_strを"test2.txt"に出力. */
  put_file_text_cstdio("test2.txt", japanese_str); /* put_file_text_cstdioでjapanese_strを"test2.txt"に出力. */

  /* ロケール"ja_JP.EUC-JP"のセット. */
  setlocale(LC_ALL, "ja_JP.EUC-JP"); /* setlocaleでLC_ALL, "ja_JP.EUC-JP"をセット. */

  /* japanese_strを"test3.txt"に出力. */
  put_file_text_cstdio("test3.txt", japanese_str); /* put_file_text_cstdioでjapanese_strを"test3.txt"に出力. */

  /* プログラムの終了 */
  return 0; /* 0を返して正常終了. */

}

/* C標準入出力ライブラリ関数で文字テキストファイル出力. */
int put_file_text_cstdio(const char *path, const char *text){

  /* 変数・構造体の初期化. */
  FILE *fp = NULL; /* ファイルポインタfpをNULLで初期化. */
  int ret; /* fputsの戻り値ret. */

  /* ファイルを開く. */
  fp = fopen(path, "w"); /* fopenでテキスト書き込みで開く. */
  if (fp != NULL){ /* fpがNULLでない時. */

    /* ファイルにテキストを書き込む. */
    ret = fputs(text, fp); /* fputsでfpにtextを出力し, 戻り値はretに格納. */

    /* fpを閉じる. */
    fclose(fp); /* fcloseでfpを閉じる. */

    /* fputsが成功ならretは0. */
    return ret; /* returnでretを返す. */

  }

  /* ファイルを開けない場合は, -1を返す. */
  return -1; /* returnで-1を返す. */

}

とする。

すべてUTF-8になるので影響を受けない。
すべてUTF-8になるので影響を受けない。

すべてUTF-8になるので影響を受けない。
wput_file_wtext_cstdioを実装する。

と書く。

test1.txtは文字化け。
test1.txtは文字化け。

test1.txtは文字化け。

test3.txtはEUC-JP。
test3.txtはEUC-JP。

test3.txtはEUC-JP。
test2.txtはUTF-8になるので影響を受ける。

Test/c/wput_file_wtext_cstdio/wput_file_wtext_cstdio/src/wput_file_wtext_cstdio at master · bg1bgst333/Test · GitHub

wscan_file_wtext_cstdio

fwscanfでワイド文字を読み込む関数wscan_file_wtext_cstdioを作る。
main.cで、

と書く。

こうなる。
こうなる。

こうなる。

Test/c/wscan_file_wtext_cstdio/wscan_file_wtext_cstdio/src/wscan_file_wtext_cstdio at master · bg1bgst333/Test · GitHub