ファイル名を変更するシステム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tatyumi
記事: 15
登録日時: 8年前

ファイル名を変更するシステム

#1

投稿記事 by tatyumi » 8年前

はじめまして。
早速お聞きしたいことがあるのですが、ファイル名を変更(または修正)をするプログラムを組みたいのですが、初学者なのでわからないのです、、、
よろしければご教授のほどをよろしくお願いします。
OS、Windows7  コンパイラー、VisualStudio2013express
システムの内容
・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
・この動作を複数同時に行える。
まだファイル名の読み込み方もわからない初心者です。
解説などをつけてもらえると大変ありがたいです。

長文失礼しました。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#2

投稿記事 by みけCAT » 8年前

tatyumi さんが書きました:OS、Windows7  コンパイラー、VisualStudio2013express
使用したいプログラミング言語を教えてください。
tatyumi さんが書きました:システムの内容
・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
・この動作を複数同時に行える。
ファイル名を変更する対象はどのようにして指定したいですか?
tatyumi さんが書きました:まだファイル名の読み込み方もわからない初心者です。
では、まず文字列をハードコードして、仕様にあった変換を行うことを試みてください。
tatyumi さんが書きました:長文失礼しました。
失礼なほどの長文はどこですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#3

投稿記事 by tatyumi » 8年前

情報が少なくて申し訳ありません。
使用する言語はc言語で、指定のしかたですか、、、フォルダの中に格納されてるファイルを対象としたいのですが、すみません言葉足らずで。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#4

投稿記事 by みけCAT » 8年前

これらの関数を使うと、あるフォルダ内のファイルを列挙できます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#5

投稿記事 by tatyumi » 8年前

ありがとうございます!
列挙して、あとは関数で修正していけばいいですよね。

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#6

投稿記事 by tatyumi » 8年前

すみません。試してみたのですがよくわからなかったです。
少し具体的に内容をまとめてみました。
・指定した(フォルダ名を入力)フォルダ内のファイル名を修正。
といったものなのですが、お聞きしたいことがまたありまして
・入力することでフォルダ検索はできるのでしょうか
・ファイル名の書き換えが可能かどうか
よければ関数など教えていただけると助かります。
度々申し訳ありません。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#7

投稿記事 by みけCAT » 8年前

tatyumi さんが書きました:・入力することでフォルダ検索はできるのでしょうか
もう少し具体的に教えてください。何をどんなインターフェースから入力することで、何を検索したいのでしょうか?
tatyumi さんが書きました:・ファイル名の書き換えが可能かどうか
MoveFile 関数を使えばおそらく可能でしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: ファイル名を変更するシステム

#8

投稿記事 by かずま » 8年前

次のプログラムは参考になりますか?

コード:

#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 という名称を使っています。
tatyumi さんが書きました: ・すべて半角のファイル名に変える。(直すのはカタカナ、英数字はそのまま)
・拡張子は常に小文字にする。
"売り上げデータA2-20150519.TXT"
というファイル名はどのように変換するつもりですか?

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#9

投稿記事 by tatyumi » 8年前

みけさん、文字をキーボードから入力してそれと一致するフォルダを検索し、その中にあるファイル名を修正するといったものなのですが、質問に答えていられるでしょうか。

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#10

投稿記事 by tatyumi » 8年前

かずまさん、コードありがとうございます!ですが今で出先なので試すことができなくて・・・夕方頃に参考にさせてもらいます。
ファイル名は売り上げデータA2‐20150519.txtと変換したいです。ファイル名はカタカナを半角にしそれ以外はそのまま、拡張子は常に小文字に変換させたいです。

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#11

投稿記事 by tatyumi » 8年前

かずまさん、せっかく載せてもらったコードなのですがエラーがでました。
<エラー内容>
・errorC2664'HANDLE FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW)' : 引数 1 を 'char [256]' から 'LPCWSTR' へ変換できません。
・IntelliSense: 型 "char *" の引数は型 "LPCWSTR" のパラメーターと互換性がありません

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#12

投稿記事 by tatyumi » 8年前

コード:

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という絶対パスを取り出しそれぞれ、ドライブ、パス、ファイル名、拡張子と分ける。
それから以下の処理を行う。
・ファイル名は全角のカタカナがあったら半角カタカナに変換。
・拡張子は大文字のものがあったら小文字に変換。
・変換したものを表示
ということをしたいのですが、どのようにすればいいのでしょうか。
また全角のカタカナを半角のカタカナに変換する関数が作れなくて・・・
ご教授のほうをよろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#13

投稿記事 by みけCAT » 8年前

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で殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#14

投稿記事 by tatyumi » 8年前

エラー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));
ここがエラーの対象みたいです。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#15

投稿記事 by みけCAT » 8年前

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));
ここがエラーの対象みたいです。
FindNextFileの後ろにもAを追加してください。

コード:

#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で殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#16

投稿記事 by tatyumi » 8年前

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という絶対パスを取り出しそれぞれ、ドライブ、パス、ファイル名、拡張子と分ける。
それから以下の処理を行う。
・ファイル名は全角のカタカナがあったら半角カタカナに変換。
・拡張子は大文字のものがあったら小文字に変換。
・変換したものを表示
ということをしたいのですが、どのようにすればいいのでしょうか。
また全角のカタカナを半角のカタカナに変換する関数が作れなくて・・・
ご教授のほうをよろしくお願いします。
みけさん、わざわざありがとうございます。失礼ながら今外出中でしてコンパイルするのは12時くらいになりそうです。


あと、申し訳ないのですが上記のコードのアドバイスを頂けないでしょうか。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#17

投稿記事 by みけCAT » 8年前

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で殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#18

投稿記事 by みけCAT » 8年前

tatyumi さんが書きました:

コード:

if (isupper(szFName[i]) != 0 && isupper(szFName[i]) != 0)   //もしファイル名が大文字でかつカタカナなら半角にする
大文字のカタカナとは何ですか?
同じ条件を2回並べていて無駄に見えますし、C言語の標準関数のisupperはカタカナかを判定する関数ではありません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#19

投稿記事 by tatyumi » 8年前

みけCAT さんが書きました:
tatyumi さんが書きました:

コード:

if (isupper(szFName[i]) != 0 && isupper(szFName[i]) != 0)   //もしファイル名が大文字でかつカタカナなら半角にする
大文字のカタカナとは何ですか?
同じ条件を2回並べていて無駄に見えますし、C言語の標準関数のisupperはカタカナかを判定する関数ではありません。
すみません、全角のカタカナでした。
全角とカタカナというのを判定したかったのですが間違えていたみたいです。

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#20

投稿記事 by tatyumi » 8年前

みけ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関数などが使えます。

設計の変更というとやり直しということですよね。がんばります。

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#21

投稿記事 by tatyumi » 8年前

先ほどみけさんに修正してもらったコードなのですが、結果画面が出る前に
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)

と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。

たいちう
記事: 418
登録日時: 13年前

Re: ファイル名を変更するシステム

#22

投稿記事 by たいちう » 8年前

とりあえず、かずまさんのプログラムを何故動かせないのか理解してはどうでしょうか。
プロジェクトのプロパティで、文字セットをUNICODEからマルチバイトに変えてみてください。

↑のキーワードをいろいろ調べてみましょう。
そうしないと、みけCATさんのアドバイスも、不思議な呪文で終わってしまいます。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#23

投稿記事 by みけCAT » 8年前

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)

と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。
以下のis_upper関数を定義し、isupperの呼び出しを全てis_upperに置き換えてください。

コード:

int is_upper(char c)
{
	return isupper((unsigned char)c);
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#24

投稿記事 by tatyumi » 8年前

みけCAT さんが書きました:
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)

と書かれているウインドウが表示されました。
中止を選択すると
デバック画面でドライブ、パス、ファイル名、拡張子が分けて表示されたところで終わってました。
たぶん文字を一つ一つ修正するところがわるかったのでしょうか。
以下のis_upper関数を定義し、isupperの呼び出しを全てis_upperに置き換えてください。

エラー画面みたいなのはでなくなりました!
ですが動作が停止して、先ほど表示されていたところまでしか出なくてやはり文字修正の処理が行われていませんでした。
これはもう書き直したほうがいいですよね・・・

コード:

int is_upper(char c)
{
	return isupper((unsigned char)c);
}

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#25

投稿記事 by みけCAT » 8年前

tatyumi さんが書きました:ですが動作が停止して、
printfの引数で確保された領域の外にアクセスしており、printfにポインタとして不正な値が渡された結果、死んでいるのでしょう。
printf("%s", szFName);ではなくprintf("%s", szFName);
printf("%s", szExt);ではなくprintf("%s", szExt);
としてください。

tatyumi さんが書きました:これはもう書き直したほうがいいですよね・・・

そうですね。wchar_tを用いた方が楽でしょう。
カタカナの全角→半角の変換は、最悪テーブルを作って線形探索すればできるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

tatyumi
記事: 15
登録日時: 8年前

Re: ファイル名を変更するシステム

#26

投稿記事 by tatyumi » 8年前

みけさん、今日はありがとうございました。
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言語のみで可能なのでしょうか。


長々と今日はありがとうございました。また、お世話になると思います。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: ファイル名を変更するシステム

#27

投稿記事 by みけCAT » 8年前

tatyumi さんが書きました:ダイアログを作ってプログラムを組んでいくことはC言語のみで可能なのでしょうか。
ダイアログは「リソース」を使って作ると楽です。「リソース」は「リソーススクリプト」をコンパイルすることて作るので、C言語のみではできません。
「リソース」を使わず、自分でウィンドウを作って部品を配置することも可能です。これはC言語(のコンパイラとWindows API)のみで可能です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Bull
記事: 149
登録日時: 9年前

Re: ファイル名を変更するシステム

#28

投稿記事 by Bull » 8年前

Windows の API には LCMapString() というのがありまして、全角⇔半角の変換
なんかをやってくれるんですが、この場合は使えないようですね(なんかいい
方法があるかもしれませんが)。昔作って某所へ投稿したプログラムを少し、
かえてみました。

コード:

//全角カタカナを半角に変換する
#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;
}
Shift_Jis のことしか考えてませんし、Visual C++ 以外ではコンパイルできないかもしません。
全角のカタカナには「ヮヰヱヵヶ」などの文字があるのですが、対応する半角文字がない
ので、変換は出来ません。もししたければ、テーブルに追加してください。

かずま

Re: ファイル名を変更するシステム

#29

投稿記事 by かずま » 8年前

プロジェクトのプロパティを開いて、
構成プロパティの全般の文字セットが
「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: ファイル名を変更するシステム

#30

投稿記事 by かずま » 8年前

バグがありました。
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;
}
まだバグがあると思うので、見つけたらご指摘ください。

閉鎖

“C言語何でも質問掲示板” へ戻る