ファイル名を変更するシステム
ファイル名を変更するシステム
はじめまして。
早速お聞きしたいことがあるのですが、ファイル名を変更(または修正)をするプログラムを組みたいのですが、初学者なのでわからないのです、、、
よろしければご教授のほどをよろしくお願いします。
OS、Windows7 コンパイラー、VisualStudio2013express
システムの内容
・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
・この動作を複数同時に行える。
まだファイル名の読み込み方もわからない初心者です。
解説などをつけてもらえると大変ありがたいです。
長文失礼しました。
早速お聞きしたいことがあるのですが、ファイル名を変更(または修正)をするプログラムを組みたいのですが、初学者なのでわからないのです、、、
よろしければご教授のほどをよろしくお願いします。
OS、Windows7 コンパイラー、VisualStudio2013express
システムの内容
・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
・この動作を複数同時に行える。
まだファイル名の読み込み方もわからない初心者です。
解説などをつけてもらえると大変ありがたいです。
長文失礼しました。
Re: ファイル名を変更するシステム
使用したいプログラミング言語を教えてください。tatyumi さんが書きました:OS、Windows7 コンパイラー、VisualStudio2013express
ファイル名を変更する対象はどのようにして指定したいですか?tatyumi さんが書きました:システムの内容
・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
・この動作を複数同時に行える。
では、まず文字列をハードコードして、仕様にあった変換を行うことを試みてください。tatyumi さんが書きました:まだファイル名の読み込み方もわからない初心者です。
失礼なほどの長文はどこですか?tatyumi さんが書きました:長文失礼しました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
情報が少なくて申し訳ありません。
使用する言語はc言語で、指定のしかたですか、、、フォルダの中に格納されてるファイルを対象としたいのですが、すみません言葉足らずで。
使用する言語はc言語で、指定のしかたですか、、、フォルダの中に格納されてるファイルを対象としたいのですが、すみません言葉足らずで。
Re: ファイル名を変更するシステム
すみません。試してみたのですがよくわからなかったです。
少し具体的に内容をまとめてみました。
・指定した(フォルダ名を入力)フォルダ内のファイル名を修正。
といったものなのですが、お聞きしたいことがまたありまして
・入力することでフォルダ検索はできるのでしょうか
・ファイル名の書き換えが可能かどうか
よければ関数など教えていただけると助かります。
度々申し訳ありません。
少し具体的に内容をまとめてみました。
・指定した(フォルダ名を入力)フォルダ内のファイル名を修正。
といったものなのですが、お聞きしたいことがまたありまして
・入力することでフォルダ検索はできるのでしょうか
・ファイル名の書き換えが可能かどうか
よければ関数など教えていただけると助かります。
度々申し訳ありません。
Re: ファイル名を変更するシステム
もう少し具体的に教えてください。何をどんなインターフェースから入力することで、何を検索したいのでしょうか?tatyumi さんが書きました:・入力することでフォルダ検索はできるのでしょうか
MoveFile 関数を使えばおそらく可能でしょう。tatyumi さんが書きました:・ファイル名の書き換えが可能かどうか
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
次のプログラムは参考になりますか?
フォルダはディレクトリとほぼ同じ意味なので、
ここでは dirname という名称を使っています。
というファイル名はどのように変換するつもりですか?
#include <windows.h>
#include <stdio.h>
int main(void)
{
char dirname[252], filename[256];
while (printf("dirname: "), scanf("%251s", dirname) == 1) {
WIN32_FIND_DATA fd;
HANDLE h;
sprintf(filename, "%s/*", dirname);
printf("[%s]\n", filename);
h = FindFirstFile(filename, &fd);
if (h == INVALID_HANDLE_VALUE)
printf("FindFirstFile failed\n");
else {
do {
printf(" %s\n", fd.cFileName);
} while (FindNextFile(h, &fd));
FindClose(h);
}
}
return 0;
}
ここでは dirname という名称を使っています。
"売り上げデータA2-20150519.TXT"tatyumi さんが書きました: ・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
というファイル名はどのように変換するつもりですか?
Re: ファイル名を変更するシステム
みけさん、文字をキーボードから入力してそれと一致するフォルダを検索し、その中にあるファイル名を修正するといったものなのですが、質問に答えていられるでしょうか。
Re: ファイル名を変更するシステム
かずまさん、コードありがとうございます!ですが今で出先なので試すことができなくて・・・夕方頃に参考にさせてもらいます。
ファイル名は売り上げデータA2‐20150519.txtと変換したいです。ファイル名はカタカナを半角にしそれ以外はそのまま、拡張子は常に小文字に変換させたいです。
ファイル名は売り上げデータA2‐20150519.txtと変換したいです。ファイル名はカタカナを半角にしそれ以外はそのまま、拡張子は常に小文字に変換させたいです。
Re: ファイル名を変更するシステム
かずまさん、せっかく載せてもらったコードなのですがエラーがでました。
<エラー内容>
・errorC2664'HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)' : 引数 1 を 'char [256]' から 'LPCWSTR' へ変換できません。
・IntelliSense: 型 "char *" の引数は型 "LPCWSTR" のパラメーターと互換性がありません
<エラー内容>
・errorC2664'HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)' : 引数 1 を 'char [256]' から 'LPCWSTR' へ変換できません。
・IntelliSense: 型 "char *" の引数は型 "LPCWSTR" のパラメーターと互換性がありません
Re: ファイル名を変更するシステム
char tolowr(char c);
char toupr(char c);
int _tmain(int argc, _TCHAR* argv[])
{
int i;
char *mypath = "C:\\abc\\def\\mybook.Txt"; //絶対パス
char szDrive[8], szPath[64], szFName[32], szExt[8];
_splitpath_s(mypath, szDrive, sizeof(szDrive), szPath, sizeof(szPath), szFName,
sizeof(szFName), szExt, sizeof(szExt));
printf("ドライブは%s\nパスは%s\nファイル名は%s\n拡張子は%s\n",
szDrive, szPath, szFName, szExt); //分けて表示される
for (i = 1; i < 32; i++)
if (isupper(szFName[i]) != 0 && isupper(szFName[i]) != 0) //もしファイル名が大文字でかつカタカナなら半角にする
char toupr(char szFName[i]); //ここでエラー。C2057:定数式が必要。C2466:サイズが0の配列を割りまたは宣言しましょう。
printf("%s", szFName[i]);
for (i = 1; i < 8;i++)
if (isupper(szExt[i]) != 0) //もし拡張子が大文字であるなら小文字に変換する
char tolowr(char szExt[i]); //ここでエラー。C2057:定数式が必要。C2466:サイズが0の配列を割りまたは宣言しましょう。
printf("%s", szExt[i]);
return 0;
}
char tolowr(char c) { //小文字変換
return (c + 0x20);
}
char toupr(char c) { //半角変換をしたいのですが
//mbctombb(c);
return ();
}
C:\\abc\\def\\mybook.Txtという絶対パスを取り出しそれぞれ、ドライブ、パス、ファイル名、拡張子と分ける。
それから以下の処理を行う。
・ファイル名は全角のカタカナがあったら半角カタカナに変換。
・拡張子は大文字のものがあったら小文字に変換。
・変換したものを表示
ということをしたいのですが、どのようにすればいいのでしょうか。
また全角のカタカナを半角のカタカナに変換する関数が作れなくて・・・
ご教授のほうをよろしくお願いします。
Re: ファイル名を変更するシステム
このようにしてみてください。tatyumi さんが書きました:かずまさん、せっかく載せてもらったコードなのですがエラーがでました。
<エラー内容>
・errorC2664'HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)' : 引数 1 を 'char [256]' から 'LPCWSTR' へ変換できません。
・IntelliSense: 型 "char *" の引数は型 "LPCWSTR" のパラメーターと互換性がありません
※コンパイルしていないので、ミスがあるかもしれません
#include <windows.h>
#include <stdio.h>
int main(void)
{
char dirname[252], filename[256];
while (printf("dirname: "), scanf("%251s", dirname) == 1) {
WIN32_FIND_DATAA fd;
HANDLE h;
sprintf(filename, "%s/*", dirname);
printf("[%s]\n", filename);
h = FindFirstFileA(filename, &fd);
if (h == INVALID_HANDLE_VALUE)
printf("FindFirstFileA failed\n");
else {
do {
printf(" %s\n", fd.cFileName);
} while (FindNextFile(h, &fd));
FindClose(h);
}
}
return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
エラー1error C2664: 'BOOL FindNextFileW(HANDLE,LPWIN32_FIND_DATAW)' : 引数 2 を 'WIN32_FIND_DATAA *' から 'LPWIN32_FIND_DATAW' へ変換できません。
2IntelliSense: 型 "WIN32_FIND_DATAA *" の引数は型 "LPWIN32_FIND_DATAW" のパラメーターと互換性がありません
とでました。
} while (FindNextFile(h, &fd));
ここがエラーの対象みたいです。
2IntelliSense: 型 "WIN32_FIND_DATAA *" の引数は型 "LPWIN32_FIND_DATAW" のパラメーターと互換性がありません
とでました。
} while (FindNextFile(h, &fd));
ここがエラーの対象みたいです。
Re: ファイル名を変更するシステム
FindNextFileの後ろにもAを追加してください。tatyumi さんが書きました:エラー1error C2664: 'BOOL FindNextFileW(HANDLE,LPWIN32_FIND_DATAW)' : 引数 2 を 'WIN32_FIND_DATAA *' から 'LPWIN32_FIND_DATAW' へ変換できません。
2IntelliSense: 型 "WIN32_FIND_DATAA *" の引数は型 "LPWIN32_FIND_DATAW" のパラメーターと互換性がありません
とでました。
} while (FindNextFile(h, &fd));
ここがエラーの対象みたいです。
#include <windows.h>
#include <stdio.h>
int main(void)
{
char dirname[252], filename[256];
while (printf("dirname: "), scanf("%251s", dirname) == 1) {
WIN32_FIND_DATAA fd;
HANDLE h;
sprintf(filename, "%s/*", dirname);
printf("[%s]\n", filename);
h = FindFirstFileA(filename, &fd);
if (h == INVALID_HANDLE_VALUE)
printf("FindFirstFileA failed\n");
else {
do {
printf(" %s\n", fd.cFileName);
} while (FindNextFileA(h, &fd));
FindClose(h);
}
}
return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
みけさん、わざわざありがとうございます。失礼ながら今外出中でしてコンパイルするのは12時くらいになりそうです。tatyumi さんが書きました:今、コーディングをしていたのですが多数のエラーが出て対処のしかたがわからないので投稿させてもらいました。char tolowr(char c); char toupr(char c); int _tmain(int argc, _TCHAR* argv[]) { int i; char *mypath = "C:\\abc\\def\\mybook.Txt"; //絶対パス char szDrive[8], szPath[64], szFName[32], szExt[8]; _splitpath_s(mypath, szDrive, sizeof(szDrive), szPath, sizeof(szPath), szFName, sizeof(szFName), szExt, sizeof(szExt)); printf("ドライブは%s\nパスは%s\nファイル名は%s\n拡張子は%s\n", szDrive, szPath, szFName, szExt); //分けて表示される for (i = 1; i < 32; i++) if (isupper(szFName[i]) != 0 && isupper(szFName[i]) != 0) //もしファイル名が大文字でかつカタカナなら半角にする char toupr(char szFName[i]); //ここでエラー。C2057:定数式が必要。C2466:サイズが0の配列を割りまたは宣言しましょう。 printf("%s", szFName[i]); for (i = 1; i < 8;i++) if (isupper(szExt[i]) != 0) //もし拡張子が大文字であるなら小文字に変換する char tolowr(char szExt[i]); //ここでエラー。C2057:定数式が必要。C2466:サイズが0の配列を割りまたは宣言しましょう。 printf("%s", szExt[i]); return 0; } char tolowr(char c) { //小文字変換 return (c + 0x20); } char toupr(char c) { //半角変換をしたいのですが //mbctombb(c); return (); }
C:\\abc\\def\\mybook.Txtという絶対パスを取り出しそれぞれ、ドライブ、パス、ファイル名、拡張子と分ける。
それから以下の処理を行う。
・ファイル名は全角のカタカナがあったら半角カタカナに変換。
・拡張子は大文字のものがあったら小文字に変換。
・変換したものを表示
ということをしたいのですが、どのようにすればいいのでしょうか。
また全角のカタカナを半角のカタカナに変換する関数が作れなくて・・・
ご教授のほうをよろしくお願いします。
あと、申し訳ないのですが上記のコードのアドバイスを頂けないでしょうか。
Re: ファイル名を変更するシステム
とりあえず、これでエラーは消えるかもしれません。tatyumi さんが書きました:あと、申し訳ないのですが上記のコードのアドバイスを頂けないでしょうか。
#include <ctype.h>
char tolowr(char c);
char toupr(char c);
int _tmain(int argc, _TCHAR* argv[])
{
int i;
char *mypath = "C:\\abc\\def\\mybook.Txt"; //絶対パス
char szDrive[8], szPath[64], szFName[32], szExt[8];
_splitpath_s(mypath, szDrive, sizeof(szDrive), szPath, sizeof(szPath), szFName,
sizeof(szFName), szExt, sizeof(szExt));
printf("ドライブは%s\nパスは%s\nファイル名は%s\n拡張子は%s\n",
szDrive, szPath, szFName, szExt); //分けて表示される
for (i = 1; i < 32; i++)
if (isupper(szFName[i]) != 0 && isupper(szFName[i]) != 0) //もしファイル名が大文字でかつカタカナなら半角にする
//char toupr(char szFName[i]); //ここでエラー。C2057:定数式が必要。C2466:サイズが0の配列を割りまたは宣言しましょう。
szFName[i] = toupr(szFName[i]);
printf("%s", szFName[i]);
for (i = 1; i < 8;i++)
if (isupper(szExt[i]) != 0) //もし拡張子が大文字であるなら小文字に変換する
//char tolowr(char szExt[i]); //ここでエラー。C2057:定数式が必要。C2466:サイズが0の配列を割りまたは宣言しましょう。
szFName[i] = tolowr(szFName[i]);
printf("%s", szExt[i]);
return 0;
}
char tolowr(char c) { //小文字変換
return (char)tolower((unsigned char)c);
//return (c + 0x20);
}
char toupr(char c) { //半角変換をしたいのですが
// charに全角カタカナは入りません。設計の変更が必要です。
return c;
//mbctombb(c);
//return ();
}
標準入力ではなくキーボードから入力すればいいのでしたら、ダイアログを作成してテキストボックスに入力させ、tatyumi さんが書きました:文字をキーボードから入力して
GetWindowTextW関数を用いてwchar_t型でパスを取得すれば、(多くの)全角文字も半角文字も1要素で表せるので、実装が楽になります。
ただし、_splitpath_sやprintf(、isupper)は使えないかもしれません。wchar_t[]型のメッセージの表示にはMessaageBoxW関数などが使えます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
大文字のカタカナとは何ですか?
同じ条件を2回並べていて無駄に見えますし、C言語の標準関数のisupperはカタカナかを判定する関数ではありません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
みけCAT さんが書きました:tatyumi さんが書きました:あと、申し訳ないのですが上記のコードのアドバイスを頂けないでしょうか。#include <ctype.h> char toupr(char c) { //半角変換をしたいのですが // charに全角カタカナは入りません。設計の変更が必要です。 return c; //mbctombb(c); //return (); }
標準入力ではなくキーボードから入力すればいいのでしたら、ダイアログを作成してテキストボックスに入力させ、tatyumi さんが書きました:文字をキーボードから入力して
GetWindowTextW関数を用いてwchar_t型でパスを取得すれば、(多くの)全角文字も半角文字も1要素で表せるので、実装が楽になります。
ただし、_splitpath_sやprintf(、isupper)は使えないかもしれません。wchar_t[]型のメッセージの表示にはMessaageBoxW関数などが使えます。
設計の変更というとやり直しということですよね。がんばります。
Re: ファイル名を変更するシステム
先ほどみけさんに修正してもらったコードなのですが、結果画面が出る前に
Debug Assertion Failed!
Program:F:\c\al\Debug\a.exe
File:f:\dd\vctools\crtw32\convert\isctype.c
Line:56
Expression:c>=-1 && c <= 255
For information on how your program can cause an assertionfailure,see the VisualC++ documentation on asserts.
(Press Retry to debug the application)
と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。
Debug Assertion Failed!
Program:F:\c\al\Debug\a.exe
File:f:\dd\vctools\crtw32\convert\isctype.c
Line:56
Expression:c>=-1 && c <= 255
For information on how your program can cause an assertionfailure,see the VisualC++ documentation on asserts.
(Press Retry to debug the application)
と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。
Re: ファイル名を変更するシステム
とりあえず、かずまさんのプログラムを何故動かせないのか理解してはどうでしょうか。
プロジェクトのプロパティで、文字セットをUNICODEからマルチバイトに変えてみてください。
↑のキーワードをいろいろ調べてみましょう。
そうしないと、みけCATさんのアドバイスも、不思議な呪文で終わってしまいます。
プロジェクトのプロパティで、文字セットをUNICODEからマルチバイトに変えてみてください。
↑のキーワードをいろいろ調べてみましょう。
そうしないと、みけCATさんのアドバイスも、不思議な呪文で終わってしまいます。
Re: ファイル名を変更するシステム
以下のis_upper関数を定義し、isupperの呼び出しを全てis_upperに置き換えてください。tatyumi さんが書きました:先ほどみけさんに修正してもらったコードなのですが、結果画面が出る前に
Debug Assertion Failed!
Program:F:\c\al\Debug\a.exe
File:f:\dd\vctools\crtw32\convert\isctype.c
Line:56
Expression:c>=-1 && c <= 255
For information on how your program can cause an assertionfailure,see the VisualC++ documentation on asserts.
(Press Retry to debug the application)
と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
みけCAT さんが書きました:以下のis_upper関数を定義し、isupperの呼び出しを全てis_upperに置き換えてください。tatyumi さんが書きました:先ほどみけさんに修正してもらったコードなのですが、結果画面が出る前に
Debug Assertion Failed!
Program:F:\c\al\Debug\a.exe
File:f:\dd\vctools\crtw32\convert\isctype.c
Line:56
Expression:c>=-1 && c <= 255
For information on how your program can cause an assertionfailure,see the VisualC++ documentation on asserts.
(Press Retry to debug the application)
と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。
エラー画面みたいなのはでなくなりました!
ですが動作が停止して、先ほど表示されていたところまでしか出なくてやはり文字修正の処理が行われていませんでした。
これはもう書き直したほうがいいですよね・・・
Re: ファイル名を変更するシステム
printfの引数で確保された領域の外にアクセスしており、printfにポインタとして不正な値が渡された結果、死んでいるのでしょう。tatyumi さんが書きました:ですが動作が停止して、
printf("%s", szFName);ではなくprintf("%s", szFName);
printf("%s", szExt);ではなくprintf("%s", szExt);
としてください。
tatyumi さんが書きました:これはもう書き直したほうがいいですよね・・・
そうですね。wchar_tを用いた方が楽でしょう。
カタカナの全角→半角の変換は、最悪テーブルを作って線形探索すればできるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
みけさん、今日はありがとうございました。
printfのところを書き直してコンパイルしたら動作は停止することがなくなりました。
ですがやはり大文字を小文字にするといった処理はされずそのままでした。一から書き直してみます。
最後にいくつか聞きたいことがいくつかありまして
これは無事に動作することが出来たのですが、どういった処理が行われているのでしょうか。
入力したものがなかったらFindFirstFileA failedと表示され、ヒットしたらfilenameが表示されるものと理解していいのでしょうか。
最後になのですがダイアログを作ってプログラムを組んでいくことはC言語のみで可能なのでしょうか。
長々と今日はありがとうございました。また、お世話になると思います。
printfのところを書き直してコンパイルしたら動作は停止することがなくなりました。
ですがやはり大文字を小文字にするといった処理はされずそのままでした。一から書き直してみます。
最後にいくつか聞きたいことがいくつかありまして
int _tmain(int argc, _TCHAR* argv[])
{
char dirname[252], filename[256];
while (printf("dirname: "), scanf("%251s", dirname) == 1) {
WIN32_FIND_DATAA fd;
HANDLE h;
sprintf(filename, "%s/*", dirname);
printf("[%s]\n", filename);
h = FindFirstFileA(filename, &fd);
if (h == INVALID_HANDLE_VALUE)
printf("FindFirstFileA failed\n");
else {
do {
printf(" %s\n", fd.cFileName);
} while (FindNextFileA(h, &fd));
FindClose(h);
}
}
return 0;
}
入力したものがなかったらFindFirstFileA failedと表示され、ヒットしたらfilenameが表示されるものと理解していいのでしょうか。
最後になのですがダイアログを作ってプログラムを組んでいくことはC言語のみで可能なのでしょうか。
長々と今日はありがとうございました。また、お世話になると思います。
Re: ファイル名を変更するシステム
ダイアログは「リソース」を使って作ると楽です。「リソース」は「リソーススクリプト」をコンパイルすることて作るので、C言語のみではできません。tatyumi さんが書きました:ダイアログを作ってプログラムを組んでいくことはC言語のみで可能なのでしょうか。
「リソース」を使わず、自分でウィンドウを作って部品を配置することも可能です。これはC言語(のコンパイラとWindows API)のみで可能です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: ファイル名を変更するシステム
Windows の API には LCMapString() というのがありまして、全角⇔半角の変換
なんかをやってくれるんですが、この場合は使えないようですね(なんかいい
方法があるかもしれませんが)。昔作って某所へ投稿したプログラムを少し、
かえてみました。
Shift_Jis のことしか考えてませんし、Visual C++ 以外ではコンパイルできないかもしません。
全角のカタカナには「ヮヰヱヵヶ」などの文字があるのですが、対応する半角文字がない
ので、変換は出来ません。もししたければ、テーブルに追加してください。
なんかをやってくれるんですが、この場合は使えないようですね(なんかいい
方法があるかもしれませんが)。昔作って某所へ投稿したプログラムを少し、
かえてみました。
//全角カタカナを半角に変換する
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <mbctype.h>
#include <mbstring.h>
int katakana_han(unsigned char *src, unsigned char *dst)
{
static unsigned char zen_kana_tbl1[] =
"ァアィイゥウェエォオカキクケコサシスセソ"
"タチッツテトナニヌネノハヒフヘホマミムメモ"
"ャヤュユョヨラリルレロワヲン"
"。「」、・゛゜ー";
static unsigned char han_kana_tbl1[] =
"ァアィイゥウェエォオカキクケコサシスセソ"
"タチッツテトナニヌネノハヒフヘホマミムメモ"
"ャヤュユョヨラリルレロワヲン"
"。「」、・゙゚ー";
static unsigned char zen_kana_tbl2[] =
"ガギグゲゴザジズゼゾダヂヅデド"
"バビブベボヴパピプペポ";
static unsigned char han_kana_tbl2[] =
"ガギグゲゴザジズゼゾダヂヅデド"
"バビブベボヴパピプペポ";
unsigned char *p;
unsigned int c;
unsigned int ch1;
unsigned int ch2;
int pos;
while (*src != 0) {
ch1 = *src++;
if (_ismbblead(ch1)) {
ch2 = *src++;
c = (ch1 << 8) + ch2;
//c = _mbctombb(c);
if (p = _mbschr(zen_kana_tbl1, c)) {
pos = (p - zen_kana_tbl1) / 2;
*dst++ = han_kana_tbl1[pos];
} else if (p = _mbschr(zen_kana_tbl2, c)) {
pos = p - zen_kana_tbl2;
*dst++ = han_kana_tbl2[pos];
*dst++ = han_kana_tbl2[pos+1];
} else {
*dst++ = ch1;
*dst++ = ch2;
}
} else {
*dst++ = ch1;
}
}
*dst = 0;
return 0;
}
int main(void)
{
char old_file[] = "売り上げデータA2-20150519.TXT";
char new_file[256];
#if 0
LCMapString(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH | LCMAP_KATAKANA, old_file, -1, new_file, sizeof new_file);
#else
katakana_han((unsigned char *)old_file, (unsigned char *)new_file);
#endif
puts(new_file);
return 0;
}
全角のカタカナには「ヮヰヱヵヶ」などの文字があるのですが、対応する半角文字がない
ので、変換は出来ません。もししたければ、テーブルに追加してください。
Re: ファイル名を変更するシステム
プロジェクトのプロパティを開いて、
構成プロパティの全般の文字セットが
「Unicode文字セットを使用する」になっていたら、
「マルチバイト文字セットを使用する」に変更してください。
変更先のファイル名が既に存在するときはどうしましょうか?
このプログラムでは MoveFile が失敗しますが、それは見ていません。
構成プロパティの全般の文字セットが
「Unicode文字セットを使用する」になっていたら、
「マルチバイト文字セットを使用する」に変更してください。
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include <string.h>
#define KATA kana2[0]
#define XA kana2[1]
#define VU kana2[3]
BYTE *kana = (BYTE *)"ァ.ア.ィ.イ.ゥ.ウ.ェ.エ.ォ.オ.カ.ガキ.ギク.グケ.ゲコ.ゴサ.ザシ.ジ"
"ス.ズセ.ゼソ.ゾタ.ダチ.ヂッ.ツ.ヅテ.デト.ドナ.ニ.ヌ.ネ.ノ.ハ.バパヒ.ビピフ.ブプヘ.ベ"
"ペホ.ボポマ.ミ...ム.メ.モ.ャ.ヤ.ュ.ユ.ョ.ヨ.ラ.リ.ル.レ.ロ.ヮワ.ヰヱヲ.ン.ヴ";
BYTE *kana2 = (BYTE *)"ァヴ";
char *kana3 = "ー、。「」・";
char *kana4 = "ー、。「」・";
void hkana(const char *name1, char *name2)
{
BYTE *p1 = (BYTE *)name1, *p2 = (BYTE *)name2, c;
while (c = *p1++) {
if (IsDBCSLeadByte(c)) {
char *p = strstr(kana3, (char*)p1 - 1);
if (p)
*p2++ = kana4[(p - kana3) >> 1];
else if (c == KATA && c >= XA && c <= VU) {
int i = (*p1++ - XA) * 2;
*p2++ = kana[i];
if (kana[i + 1] != '.') *p2++ = kana[i + 1];
}
else *p2++ = c, *p2++ = *p1++;
}
else *p2++ = c;
}
*p2 = 0;
}
void extlower(char *name)
{
char *p = strrchr(name, '.');
if (p)
while (*++p) *p = tolower((BYTE)*p);
}
int main(void)
{
char dirname[MAX_PATH], filename[MAX_PATH], current[MAX_PATH];
GetCurrentDirectory(MAX_PATH, current);
while (printf("dirname: "), scanf("%255s", dirname) == 1) {
WIN32_FIND_DATA fd;
HANDLE h;
printf("[%s]\n", dirname);
if (!SetCurrentDirectory(dirname)) {
printf("SetCurrentDirectory failed\n");
continue;
}
h = FindFirstFile("*", &fd);
if (h == INVALID_HANDLE_VALUE) {
printf("FindFirstFile failed\n");
continue;
}
do {
hkana(fd.cFileName, filename);
extlower(filename);
if (strcmp(fd.cFileName, filename)) {
MoveFile(fd.cFileName, filename);
printf(" %s -> %s\n", fd.cFileName, filename);
}
} while (FindNextFile(h, &fd));
FindClose(h);
SetCurrentDirectory(current);
}
return 0;
}
このプログラムでは MoveFile が失敗しますが、それは見ていません。
Re: ファイル名を変更するシステム
バグがありました。
18~36行目の hkana() を次のコードに変更してください。
まだバグがあると思うので、見つけたらご指摘ください。
18~36行目の hkana() を次のコードに変更してください。
char *find(const char *s)
{
char *p;
for (p = kana3; *p; p += 2)
if (p[0] == s[0] && p[1] == s[1]) return p;
return 0;
}
void hkana(const char *name1, char *name2)
{
BYTE c;
while (c = *name1++) {
if (IsDBCSLeadByte(c)) {
char *p = find(name1 - 1);
if (p)
*name2++ = kana4[(p - kana3) >> 1], name1++;
else if (c == KATA && c >= XA && c <= VU) {
int i = ((BYTE)*name1++ - XA) * 2;
*name2++ = kana[i];
if (kana[i + 1] != '.') *name2++ = kana[i + 1];
}
else *name2++ = c, *name2++ = *name1++;
}
else *name2++ = c;
}
*name2 = 0;
}