Linux講座にようこそ。このページは「C言語プログラミング入門 - 第14章.ライブラリ関数 - 入出力ライブラリ」です。

C言語プログラミング入門

14. ライブラリ関数(11/36) -入出力ライブラリ(10/10)

14.14 ファイル削除及び、名称変更関数

ここで紹介する関数はファイルやディレクトリ(フォルダ)の削除と名称変更を行いますが、次のような前提条件があります。

  • 実行プロセスが削除や名称変更を行える権限を持っていること。(通常、ファイルやディレクトリの所有者及び、システム管理者は権限を持っています)
  • 他のプロセスがファイルやディレクトリを使用中でないこと。
  • ディレクトリを削除する場合は当該ディレクトリは空であること。

14.14.1 remove関数

remove関数はファイルやディレクトリを削除します。

【表14-1-40】 remove関数
形式#include <stdio.h>
int remove(const char *pathname);
返り値正常に処理ができた場合は0を返します。エラーの場合は-1を返します。
引数
const char *pathname
削除するファイルやディレクトリのパス名を指定します。

14.14.2 rename関数

rename関数はファイルやディレクトリの名称(パス名)を変更します。

【表14-1-41】 rename関数
形式#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
返り値正常に処理ができた場合は0を返します。エラーの場合は-1を返します。
引数
const char *oldpath
変更前のパス名を指定します。
const char *newpath
変更後のパス名を指定します。
使用法、
第2引数のnewpathの指定場所により、意味合いが多少変わります。第1引数のoldpathと同じ場所の場合は、名前の変更になりますし、異なる場所の場合は移動になります。

14.14.3 例題

実行時引数で指定されたファイルまたは、ディレクトリの名称を変更します。実行時引数の第1引数が変更前のパス名で、第2引数が変更後のパス名です。

  1. #include <stdio.h>
  2.  
  3. int main(int argc, char **argv)
  4. {
  5.     char    ans;
  6.  
  7.     if(argc == 3)
  8.     {
  9.         printf("%sを%sにリネームします。よろしいですか ==> ", *(argv + 1), *(argv + 2));
  10.         scanf("%c", &ans);
  11.  
  12.         if(ans == 'y' || ans == 'Y')
  13.         {
  14.             if(rename(*(argv + 1), *(argv + 2)) == 0)
  15.             {
  16.               printf("正常終了。\n");
  17.             }
  18.             else
  19.             {
  20.               printf("異常終了。\n");
  21.             }
  22.         }
  23.         else
  24.         {
  25.             printf("キャンセルします。\n");
  26.         }
  27.     }
  28.     else
  29.     {
  30.         printf("実行時引数が不当です。\n");
  31.     }
  32.  
  33.     return 0;
  34. }
$ ls -l ./t*
-rw-r--r-- 1 merry merry 48 2008-10-16 11:14 ./temp_1.txt
$
$ ./ex14_1_13.prg ./temp_1.txt ./temp.txt ← 名前の変更
./temp_1.txtを./temp.txtにリネームします。よろしいですか ==> y
正常終了。
$ ls -l ./t*
-rw-r--r-- 1 merry merry 48 2008-10-16 11:14 ./temp.txt
$
$
$ ls -l ~/TMP/log.csv
-rw-rw-r-- 1 merry merry 32869 2009-03-19 16:52 /home/merry/TMP/log.csv
$
$ ./ex14_1_13.prg ~/TMP/log.csv ./my_log.csv ← 移動
/home/merry/TMP/log.csvを./my_log.csvにリネームします。よろしいですか ==> y
正常終了。
$ ls -l ~/TMP/log.csv
ls: cannot access /home/merry/TMP/log.csv: そのようなファイルやディレクトリはありません
$ ls -l ./my*
-rw-rw-r-- 1 merry merry 32869 2009-03-19 16:52 ./my_log.csv
$
$ ls -ld ./DATA*
drwxr-xr-x 2 merry merry 4096 2008-08-10 11:06 ./DATA_BK
$
$ ./ex14_1_13.prg ./DATA_BK ./DATA ← ディレクトリ名の変更
./DATA_BKを./DATAにリネームします。よろしいですか ==> y
正常終了。
$ ls -ld ./DATA*
drwxr-xr-x 2 merry merry 4096 2008-08-10 11:06 ./DATA
$
14行目
rename関数でファイルまたは、ディレクトリの名称を変更します。*(argv + 1)は実行時引数の第1引数の値(変更前のパス名)で、*(argv + 2)は第2引数の値(変更後のパス名)です。

14.15 一時ファイルの操作

一時的に使用するユニークな名称(パス名)のファイルが必要な場合は、ここでご紹介する関数を使ってファイルを生成するとよいでしょう。ただし、tmpnam関数は名称を生成した時と実際に使用する間に、同じ名称のものが使われてしまう可能性があり、これは重大なセキュリティ上の問題になる可能性がありますので、なるべく使わない方がよいでしょう。

14.15.1 tmpfile関数

tmpfile関数はユニークな名称(パス名)の一時ファイルを作成します。作成したファイルはクローズ時または、プログラム終了時に自動的に削除されます。なお、ファイルはバイナリ・更新モード(w+b)でオープンしますので、Windows系OSでバイナリファイルを取り扱う場合も使用できます。

【表14-1-42】 tmpfile関数
形式#include <stdio.h>
FILE *tmpfile(void);
返り値正常に処理ができた場合は作成したファイルのファイルポインタを返します。ファイルが作成できなかったり、オープン出来なかった場合はNULLを返します。
引数なし。

14.15.2 tmpnam関数

tmpnam関数は一時ファイルの名前(パス名)を生成します。パス名を生成するだけで実際のファイルは作りません。(この関数の使用はできるだけ避けた方がよいでしょう)

【表14-1-43】 tmpnam関数
形式#include <stdio.h>
char *tmpnam(char *s);
返り値正常に処理ができた場合は生成したパス名を返します。エラーの場合はNULLを返します。
引数
char *s
生成したパス名を格納する領域を指定します。NULLを指定すると内部的な領域を使用します。

14.15.3 例題

実行時引数で指定された複数のファイルを連結して行番号を付加して表示します。1回の実行で同じ内容を複数回表示することができます。

  1. #include <stdio.h>
  2. #define BUFFSIZE    1024
  3.  
  4. int main(int argc, char **argv)
  5. {
  6.     FILE    *tmp_fp;
  7.     FILE    *in_fp;
  8.     int     arg_idx;
  9.     int     line_num;
  10.     char    buff[BUFFSIZE];
  11.     char    ans;
  12.  
  13.     if(argc >= 2)
  14.     {
  15.         /* 一時ファイル作成 */
  16.         if((tmp_fp = tmpfile()) == NULL)
  17.         {
  18.             printf("一時ファイルが作成出来ませんでした。\n");
  19.             return 1;
  20.         }
  21.         /* 実行時引数で指定されたファイルを一時ファイルにマージ */
  22.         for(arg_idx = 1; arg_idx < argc; ++arg_idx)
  23.         {
  24.             if ((in_fp = fopen(*(argv + arg_idx), "r")) != NULL)
  25.             {
  26.                 while (fgets(buff, BUFFSIZE, in_fp) != NULL)
  27.                 {
  28.                     fputs(buff, tmp_fp);
  29.                 }
  30.                 fclose(in_fp);
  31.             }
  32.             else
  33.             {
  34.                 printf("%sファイルがオープンできません。\n", *(argv + arg_idx));
  35.             }
  36.         }
  37.  
  38.         /* 一時ファイルの内容を表示 */
  39.         printf("##### 行番を付加して表示します。 #####\n");
  40.         do
  41.         {
  42.             /* 一時ファイルのファイルオフセットをファイルの先頭に戻す */
  43.             rewind(tmp_fp);
  44.             line_num = 1;
  45.  
  46.             while (fgets(buff, BUFFSIZE, tmp_fp) != NULL)
  47.             {
  48.                 printf("%.3d : %s", line_num++, buff);
  49.             }
  50.  
  51.             printf("\n表示終了。再度表示しますか(y/n) ==> ");
  52.             scanf("%c%*c", &ans);
  53.         } while(ans == 'y' || ans == 'Y');
  54.  
  55.         fclose(tmp_fp);
  56.     }
  57.     else
  58.     {
  59.         printf("実行時引数が不当です。\n");
  60.     }
  61.  
  62.     return 0;
  63. }
$ cat /etc/issue
Fedora release 10 (Cambridge)
Kernel \r on an \m (\l)

$ cat ./temp.txt
Hello.
Bye.
$
$ ./ex14_1_14.prg /etc/issue ./temp.txt
##### 行番を付加して表示します。 #####
001 : Fedora release 10 (Cambridge)
002 : Kernel \r on an \m (\l)
003 :
004 : Hello.
005 : Bye.

表示終了。再度表示しますか(y/n) ==> y
001 : Fedora release 10 (Cambridge)
002 : Kernel \r on an \m (\l)
003 :
004 : Hello.
005 : Bye.

表示終了。再度表示しますか(y/n) ==> n
$
16行目
tmpfile関数で一時ファイルを作成して、tmp_fpにファイルポインタを代入します。
28行目
一時ファイルに実行時引数で指定されたファイルを出力します。
46行目
一時ファイルから入力します。
55行目
一時ファイルをクローズします。一時ファイルは自動的に削除されます。