VC++6.0・Win32APIを用いて、ウィンドウズアプリケーションを作成しています。
エディットボックスに入力されている文字列が、スペース(全角スペース又は半角スペース)のみ
(それらの組み合わせでも構わない)で構成されているかどうかを判別するアルゴリズムを教えてください。
ヒントでも構いません。
エディットボックスの作成や、そこからの文字列の取得については理解しています。
あっ、でもよく考えてみたらエディットボックスかどうかは関係ないですね(^_^;)
『ある文字列が・・・』で十分ですね。
お手数をお掛けしますが、よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
★アドバイス
>判別するアルゴリズムを教えてください。
↑
1文字ずつ調べるしかないと思います。
あるいはシェル関数の StrTrim() を使うと簡単にチェックできます。
・下に確認用のサンプルを載せます。
サンプル:
#include <stdio.h>
#include <shlwapi.h>
#include <windows.h>
// チェック関数
void check( char string[] )
{
printf( "チェック前 = [%s]\n", string );
StrTrim( string, " " );
printf( "チェック後 = [%s]\n", string );
if ( string[0] == '\0' ){
printf( "判定結果:空白文字のみ\n" );
}
else{
printf( "判定結果:空白文字以外あり\n" );
}
printf( "\n" );
}
// メイン関数
int main( void )
{
TCHAR s1[] = " ";
TCHAR s2[] = " a b c ";
// 半角空白,全角空白のみ
check( s1 );
// 空白以外が混ざっている
check( s2 );
return 0;
}
解説:
・まずエディットボックスなどから文字列を取得します。
その後に StrTrim() 関数により文字列の両端から半角空白文字と全角空白文字を取り除く。
その結果、まだ文字列が残っていれば空白文字以外が存在する事になります。
・check() 関数の if で '\0' 文字と同じか判定しています。
この判定こそがすべて空白文字だけで構成されているかの判定となります。
なお StrTrim() API 関数を利用するには <shlwapi.h> をインクルードしてさらに
shlwapi.lib ライブラリをインポートする必要があります。注意。
StrTrim() 関数は C 言語の標準関数(ランタイム・ライブラリ)ではなくて Win32 API に属します。
・以上。
毎度お世話になっております。
StrTrim()という関数があるのは初めて知りました。
もし知っていたとしても、こういう場面で使うといういことは思いつかなかったと思います。
ちなみに、ご回答いただく前に自分なりに考えたソースを載せさせていただきます。
問題点などがありましたら、ご指摘いただけると幸いです。
if(GetWindowText(hEdit, str, sizeof(str))){
char *pPoint = str;
BOOL bSpace = TRUE; // 文字列が『全角スペース』又は『半角スペース』のみで構成されているかどうか
while(*pPoint != '\0'){
if(!memcmp(pPoint, " ", 2)){
pPoint += 2;
}else if(!memcmp(pPoint, " ", 1)){
pPoint++;
}else{
bSpace = FALSE;
break;
}
}
}
No.5
- 回答日時:
if(GetWindowText(hEdit, str, sizeof(str))){
char *pPoint = str;
BOOL bSpace = TRUE; // 文字列が『全角スペース』又は『半角スペース』のみで構成されているかどうか
while(*pPoint != '\0'){
if(!memcmp(pPoint, " ", 2)){
pPoint += 2;
}else if(!memcmp(pPoint, " ", 1)){
pPoint++;
}else{
bSpace = FALSE;
break;
}
}
}
動作も意図していますし、スマートで良いと思いますよ。
さらにスマートにするなら、
char *pPoint = str;
int rel;
while(*pPoint && rel){
rel=!memcmp(pPoint, " ", 2)?2:(!memcmp(pPoint, " ", 1)?1:0)
pPoint+=rel;
}
if (*pPoint) 全てスペースです;
else スペース以外の文字があります;
と言うのもOKですね。
No.4
- 回答日時:
★ソースの感想。
・プログラムがマルチバイト文字の専用なら問題ないでしょう。
でも私なら strncmp() 関数を使ったり、isspace()、全角文字(0x8140)との比較を
使うようにソースを書きますけど。そこでマルチバイト文字専用のソースを載せます。
サンプル:
// 全角の空白文字コード
#define CHR_SPACE (0x8140)
// 半角空白文字,全角空白文字のチェック
BOOL IsStrSpace( const char string[] )
{
while ( *string != '\0' ){
if ( MAKEWORD(string[1],string[0]) == CHR_SPACE ){
string += 2;
}
else if ( isspace(*string) ){
string += 1;
}
else{
return FALSE;
}
}
return TRUE;
}
解説:
・ほとんど kenkenpo さんと同じ仕組みです。
違う場所は memcmp() 関数を利用しないで MAKEWORD() マクロ関数と isspace() マクロを
利用している点です。関数を呼ばない分だけ高速にチェックできると思います。
・また、memcmp() の代わりに strncmp() 関数に差し替えても同じになります。
理由は関数名だけが異なり、引数や戻り値の意味は同じですので。
別名として用意されている点が面白いですね。
その他:
・今回はマルチバイト文字を専用とした関数ですが、もし今後 Unicode 文字にも対応させる場合は
関数を作り変える必要があります。なのでシェル関数の StrTrim() で同じようなことが出来る場合は
大いに活用しましょう。StrTrim() には StrTrimA()、StrTrimW() の2つが用意されています。
コンパイル・オプションにより適切な関数がリンクされます。よって簡単に Unicode 文字への対応が
できます。お勧めは StrTrim() を使った判定方法です。
・以上。
memcmp()関数と、strncmp()関数という同じ処理をする関数が存在することは初めて知りました。
同じ処理を実装するのにも、いろんな書き方があることが分かり、大変勉強になりました。
処理速度や、可読性など、そのときの状況に応じて、より適切な方法を選べるようにならないといけませんね。
ありがとうございました。
No.3
- 回答日時:
追記です。
複数行エディットに対応させました。
IsSpace 関数を変更しますね。
int IsSpace(const char* str)
{
int i,len=0;
for (i=0;*(str+i);)
{
if (*(str+i)>=0x20 && *(str+i)<=0x7f)
{
if (*(str+i)==0x20) len++;
i++;
}
else if (*(str+i)==0xd && *(str+i+1)==0xa)
{
len+=2,i+=2;
}
else
{
if (*(str+i)==(~0xff|0x81) && *(str+i+1)==0x40) len+=2,i+=2;
else i++;
}
}
return i-len-!(i+len);
}
オーバーフローのエラーにも対応させました。
この回答への補足
様々な場合に対応できるようなソースを提示していただき、誠にありがとうございます。
ちなみに、今の私の環境は単一行エディットで、入力文字制限を掛けてあります。
ご回答をいただく前に、自分なりに考えたソースを載せさせていただきますので、問題点等ありましたらご指摘いただけると幸いです。
if(GetWindowText(hEdit, str, sizeof(str))){
char *pPoint = str;
BOOL bSpace = TRUE; // 文字列が『全角スペース』又は『半角スペース』のみで構成されているかどうか
while(*pPoint != '\0'){
if(!memcmp(pPoint, " ", 2)){
pPoint += 2;
}else if(!memcmp(pPoint, " ", 1)){
pPoint++;
}else{
bSpace = FALSE;
break;
}
}
}
No.2
- 回答日時:
アルゴリズムとおっしゃるので、すべて自作でやってみましょう。
尚、エディットボックスから文字列を得る際は、
GetWindowTextA など、Ansi バージョンを使ってください。
int IsSpace(const char* str)
{
int i,len=0;
for (i=0;*(str+i);)
{
if (*(str+i)>=0x20 && *(str+i)<=0x7f)
{
if (*(str+i)==0x20) len++;
i++;
}
else
{
if (*(str+i)==(~0xff|0x81) && *(str+i+1)==0x40) len+=2;
i+=2;
}
}
return i-len-!(i+len);
}
int main()
{
char str[]="取得文字列";
switch (IsSpace(str))
{
case -1:
printf("空の文字列です\r\n");
break;
case 0:
printf("すべてスペースです\r\n");
break;
default:
printf("すべてスペースではありません\r\n");
}
return 0;
}
を例に、IsSpace() の戻り値で判定します。
一応、参考として・・・。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 特定の文字を簡単な操作で半角スペースに変換するか削除したい 2 2022/11/01 10:35
- その他(プログラミング・Web制作) プログラミング pythonの問題について 2 2022/04/19 00:41
- Visual Basic(VBA) 指定列最終行までのスペースを改行するVBAについて 2 2022/06/01 19:50
- Excel(エクセル) capeofdragonと申します Excel2016を使っておりまして 半角又は全角の任意文字列が 2 2022/10/31 13:51
- Visual Basic(VBA) 指定した文字から指定した文字のスペースまでを削除するVBAの構文について 6 2022/07/24 22:20
- Excel(エクセル) エクセルの数式で教えてください。 1 2023/02/02 10:20
- Excel(エクセル) 【Excel】指定した文字列に該当する行を重複しないようにリスト 3 2022/03/30 12:27
- Excel(エクセル) 【マクロ】フォルダAからダBへファイルを、ファイルの更新日時の条件で、1つづつ移動するには? 3 2022/08/25 09:56
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- オープンソース 【ChatGTPのオープンソースソフトウェアを解析したことがある方、教えてくださ 2 2023/03/08 18:57
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教えるわが家の防犯対策術!
ホームセキュリティのプロが、家庭の防犯対策を真剣に考える 2組のご夫婦へ実際の防犯対策術をご紹介!どうすれば家と家族を守れるのかを教えます!
-
UpdateData( FALSE); による文字列データの表示更新(VC++6.0)
C言語・C++・C#
-
エディットボックスのフォントを変えたい
C言語・C++・C#
-
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
-
4
MFCでコンボボックスを選択不可状態にしたい
C言語・C++・C#
-
5
ボタンの配置を変更したい
C言語・C++・C#
-
6
MFCダイアログボックスを最前面に表示
C言語・C++・C#
-
7
CString Format にて全角空白文字連続して格納する方法は?
C言語・C++・C#
-
8
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
9
C言語にて構造体のメンバがNULLであるかを判定するサンプルを作成して
C言語・C++・C#
-
10
適切な変換関数が存在しない???
C言語・C++・C#
-
11
CEdit の内容が変わった時にメッセージを表示させたい
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
反転した数値を表示させるやり方
-
fgets関数を使用したときの文字...
-
CStringのFindで文字列検索を行...
-
sscanfとscanfの違いがよくわか...
-
C言語 空白の行(改行のみ)が...
-
C言語で16進数文字列から16進数...
-
sscanfでフォーマットに合って...
-
文字の入れ替えについて
-
C言語 strlen 再入力を促す
-
charと%c , %s の関係について
-
全角文字のチェック
-
fgetsで拾われる改行文字を削除...
-
itoaわかりません
-
単語数のカウントについて
-
getchar分を用いて入力された文...
-
VC++ 再帰関数
-
文字列の途中に「0」がある場...
-
C言語 ポインタを使用した文字...
-
プログラミング シーザー暗号 ...
-
Enterキーを押されたら次の処理...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringのFindで文字列検索を行...
-
sscanfとscanfの違いがよくわか...
-
反転した数値を表示させるやり方
-
fgets関数を使用したときの文字...
-
C言語 空白の行(改行のみ)が...
-
charと%c , %s の関係について
-
C言語のステップ数をカウントす...
-
fgetsで拾われる改行文字を削除...
-
itoaわかりません
-
C言語で16進数文字列から16進数...
-
strstrを利用しない文字列検索...
-
文字列中に含まれる文字の個数...
-
Cで「大文字、小文字の判定」は...
-
1行の文字列を時間差で表示する...
-
エディットボックスに入力され...
-
[Java]文字列分割
-
文字列の途中に「0」がある場...
-
教えていただけませんか?C言語...
-
fgetsでバッファ残留文字列を無...
-
atoiでの文字列以外のエラー処...
おすすめ情報