- ベストアンサー
プログラム実行中にファイル名を変更
VC++ Version5.0使用です。 records.oldというファイルを元に清算して records.newというファイルに書き込むというのは成功したんですが そのrecords.newをrecords.oldという名前に変更して保存したいんですが どんな風にすればよいのでしょうか? 検索してみたらrename()という関数があるみたいなんで rename("records.new","records.old"); とやってみましたが、全然変わらないです。 ちなみに http://www.ecs.shimane-u.ac.jp/~hamaguchi/class/c-language/c-lan_12.htm http://www9.plala.or.jp/sgwr-t/lib/rename.html
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
あまり良くないコードですが書いてみました。 コレをコンパイルして実行できますか? #include <stdio.h> #include <direct.h> #include <string.h> int main(void) { char szCurDir[1024]; char szOldFile[1024]; char szNewFile[1024]; /* 初期化 */ memset(szCurDir, 0, 1024); memset(szOldFile, 0, 1024); memset(szNewFile, 0, 1024); printf("ファイルがあるディレクトリを入力してください。"); gets(szCurDir); if(_chdir(szCurDir) != 0) { printf("入力されたディレクトリが正しくありません。"); return -1; } printf("既存のファイル名を入力してください。"); gets(szOldFile); printf("新しいファイル名を入力してください。"); gets(szNewFile); if (remove(szNewFile) == 0) { printf("records.old has been removed successfully.\n"); } else { perror("Remove Error\n"); } if (rename(szOldFile, szNewFile) == 0) { printf("%s のファイル名を %s に変更しました。\n", szOldFile, szNewFile); } else { perror("Rename Error\n"); } return 0; } ちなみに私の環境では正常に動作しました。
その他の回答 (9)
- FAY
- ベストアンサー率49% (95/193)
direct.h をインクルードして char szCurDir[] = "c:\\Program Files\\hoge"; _chdir(szCurDir); をremoveよりも前に書いてください。 そして上の c:\\Program Files\\hoge をファイルのある ディレクトリに書き直して実行してみてください。 _chdirは成功すると0が、失敗すると-1が返ります。
お礼
ありがとうございます。 char szCurDir[] = "c:\\Program Files\\DevStudio\\MyProjects\\Flight\n"; _chdir(szCurDir); if (remove("records.old") == 0) printf("records.old has been removed successfully."); else perror("remove error"); ということですよね?でも、やはり変化がないですね (ディレクトリの後の\nを消しても同じでした): 変更するファイルを入力してください。records.new 新しいファイル名を入力してください。records.tmp remove error: Permission denied rename error: Permission denied Press any key to continue やはりVC++5なのがいけないんでしょうか…
- etaro
- ベストアンサー率31% (46/146)
下の方のPermissionのエラーを見ました。 作成したexeファイルとrecords.oldをMy Documentsかデスクトップにコピーして実行してみてください。
お礼
ありがとうございます。 デスクトップに両方のファイルをコピーしてやってみましたが変化がありませんでした。 records.newはちゃんと作成されるんですが records.tmpは作成さえもされません。
- etaro
- ベストアンサー率31% (46/146)
removeもエラーチェックしましょう。 0以外だったら削除失敗です。 それと、renameはrecords.tmp(つまり、同じディレクトリ内に存在しないファイル名)にリネームしてみてください。
お礼
ありがとうございます。 removeもエラーチェックすべきでしたね。 チェックしたらremoveもrenameも失敗でした。あらら。 records.tmpへの変更もうまくいってないみたいです。 "records.new"は C:\Program Files\DevStudio\MyProjects\Flight の下に作られます。でも念のために.exeファイルのある C:\Program Files\DevStudio\MyProjects\Flight\Debug にも.newと.oldはコピーしておきましたが全然変わりませんね。 うーん、どうしましょう?
- rinkun
- ベストアンサー率44% (706/1571)
エラー内容を確認するにはperrorを使うと良いですよ。 http://www9.plala.or.jp/sgwr-t/lib/rename.html の使用例でも使っていますね。 この関数でエラーの内容を表示してくれます。
お礼
ありがとうございます。 perrorなんて便利な関数があったんですね。 これは他のデバッグにも使えそうでいいですね。 で以下のようにしてみました: fclose(ptold); fclose(ptnew); // char oldname[256], newname[256]; char oldname[256] = "C:\\Program Files\\DevStudio\\MyProjects\\Flight\\records.new\n"; char newname[256] = "C:\\Program Files\\DevStudio\\MyProjects\\Flight\\records.tmp\n"; printf("変更するファイルを入力してください。"); gets(oldname); printf("新しいファイル名を入力してください。"); gets(newname); if (remove("records.old") == 0) printf("records.old has been removed successfully."); else perror("remove error"); if (rename(oldname, newname) == 0) printf("%s のファイル名を %s に変更しました。\n", oldname, newname); else perror("rename error"); } …何かお気付きの点などありますか?
- FAY
- ベストアンサー率49% (95/193)
#4です・・・ごめんなさい VC6 SP6でWinNT系のOSだと MoveFileEx()が普通に使用できてしまうんです。 それで、下のほうに書かれていたコードなのですが、 ファイル名をフルパスで指定するとどうなりますか? また、ファイルがあるディレクトリをカレントディレクトリに 設定してからリネームするとどうなりますか?
お礼
ありがとうございます。 ええっ、VC++6だとそんなことが出来るんですか!ホスィ… ていうか今時VC++5使っている人間の方が珍しいですよね。(^^ゞ フルパスでもやってみました。結果は以下のようです: char oldname[256] = "records.new\n"; char newname[256] = "records.tmp\n"; //と定義して remove error: Permission denied rename error: Invalid argument Press any key to continue 変更するファイルを入力してください。records.new 新しいファイル名を入力してください。records.old //←old remove error: Permission denied rename error: Permission denied Press any key to continue 変更するファイルを入力してください。records.new 新しいファイル名を入力してください。records.tmp //←tmp remove error: Permission denied rename error: Permission denied Press any key to continue 変更するファイルを入力してください。C:\Program Files\DevStudio\MyProjects\Flight \records.new 新しいファイル名を入力してください。C:\Program Files\DevStudio\MyProjects\Flight \records.tmp remove error: Permission denied rename error: Permission denied Press any key to continue Permissionって…いるんですかね? 一応OSはWindows XP SP2です。
- FAY
- ベストアンサー率49% (95/193)
APIの MoveFileEx() を使ってもできますね。 MoveFileEx( "records.new", "records.old", MOVEFILE_REPLACE_EXISTING ); かな。 ファイル名はフルパスを指定したほうが確実かもしれませんね。
お礼
ありがとうございます。 WinAPIというのが全然使い方が分からないんですが。(^^ゞ そのままコピペでは「そんな関数は知らない」とエラーが出ました。 これで変更できるのであれば使いたいんですが…。
- jacta
- ベストアンサー率26% (845/3158)
他の可能性としては、records.newまたはrecords.oldをクローズする前にrenameを呼び出しているとかも考えられます。
お礼
ありがとうございます。 両方のファイルを閉じた後で関数を呼び出していますので それは大丈夫です。
- rinkun
- ベストアンサー率44% (706/1571)
No.1さんの回答で正解でしょうね。 一般的にはrenameの返値をチェックしてエラー内容を確認することが大切と思いますけど。
お礼
ありがとうございます。 その手がありましたね。 しっかり"-1"が返ってきました。 でも、どうデバッグしていいのやら…。
- 麻野 なぎ(@AsanoNagi)
- ベストアンサー率45% (763/1670)
もしかしたら、records.old を事前に削除すればいいかも知れません。 remove("records.old"); rename("records.new","records.old"); あとは、プログラム実行ディレクトリの関係で、"records.new" という名前だけではファイルが見えない可能性があります。ただし、読みこみ/書き込みの処理はできているようなので、こちらの可能性は少ないでしょう。
お礼
ありがとうございます。 remove("records.old");はもう試してたんですよ。 でも変わりませんでした。 ファイルの読み書きの部分ではディレクトリ名は付けていませんので こちらもいらないと思います。 #2さんのエラーチェックを試してみたら-1が返ってきました。 でもどこがおかしいのかはちょっと分かりませんね。 一応、コードを載せておきます。 fclose(ptold); fclose(ptnew); /* MoveFileEx( "records.new", "records.old", MOVEFILE_REPLACE_EXISTING ); */ int check; char oldname[20] = "records.new\n"; char newname[20] = "records.old\n"; remove("records.old"); check = rename("records.new","records.old"); printf("Check: %d\n", check); // -1が返ってきます… // rename(oldname, newname); }
お礼
はい、出来ました! removeもrenameも両方とも正常に動作します。 ################################################## ファイルがあるディレクトリを入力してください。C:\Program Files\DevStudio\MyProje cts\Flight 既存のファイル名を入力してください。records.new 新しいファイル名を入力してください。records.old records.old has been removed successfully. records.new のファイル名を records.old に変更しました。 Press any key to continue ################################################## VC++5のせいじゃなかったんですね。(^^ゞ これで何度でも書いて消して書いて消して出来ます。ひゃっほー! わざわざ実行可能な完全なコードまで書いてくださって 本当にありがとうございました!