今,Cの関数で0-9,A-Zの4文字以内の文字列かどうか
を調べたいのですが,
int main()
{
int i;
char str[] = "ABCD" /* 調べたい文字列1 */
char str1[]= "ABC@" /* 調べたい文字列1 */
char str2[]= "ABCDE" /* 調べたい文字列1 */
char *p;
p = str; /* ここをstr1,str2に変える */
if (strlen(p) != 4)
printf("エラーです\n");
for (i = 0; i < 4; i++)
{
if (!isupper(p[i]) && !isdigit(p[i]))
{
printf("えらーです\n");
return EXIT_FAILURE;
}
}
printf("すべてOKです\n");
return EXIT_SUCCESS;
}
というようにすれば,strとstr1とstr2がフォーマットに合うかわかるのですが,これをsscanfの正規表現を使用して実装したいのですが,可能でしょうか。
int main()
{
int ret;
char str[] = "ABCD" /* 調べたい文字列1 */
char str1[]= "ABC@" /* 調べたい文字列1 */
char str2[]= "ABCDE" /* 調べたい文字列1 */
char *p;
chat tmp[30];
p = str;
ret = sscanf(p, "%4[0-9A-Z]", tmp);
if (ret != 1)
{
printf("エラーです\n");
return EXIT_FAILURE;
}
printf("すべてOKです\n");
return EXIT_SUCCESS;
}
といしょうとするならば,str1のときは,@までのABCの文字列がとれて,retには1が帰ってきてしまいます。
なにか4文字以内ということを実装できる正規表現の使い方はあるのでしょうか?
ちなみに
sscanf(str, "%1[0-9A-Z]%1[0-9A-Z]%1[0-9A-Z]%1[0-9A-Z]", tmp1, tmp2, tmp3, tmp4)
という以外でわかる方,よろしくおねがいします。
No.3ベストアンサー
- 回答日時:
#1です。
#2さんの書かれている事はもっともで、私もscanfを使っている質問者に対しては、「scanfは初心者は絶対使ってはいけない関数」といつも答えてます。初心者で無くてもキーボード入力に対しては使わないほうがよいでしょう。
ファイルからの読み取りに関しては中上級者でも、各種イリーガルなデータに対する十ニ分なテストが必要です。
sscanfはこれらに比べると行を跨った問題が起こらず、どこからスキャンを始めるかも明確なので比較的使いやすいと思います。fgetsした1行の解析もatoi等だけで済めばいいですが、複雑な場合はsscanfの力を借りるのもいいでしょう。ただ、sscanfを使うならマニュアルの熟読が必要です。
#1に書いたのと別の解法としては、
int n;
n=0;
sscanf(p,"%29[0-9A-Z]%n",tmp,&n);
とすると、nに英数字部分の長さが入ります(29はtmpのサイズに合わせる)。英数字部分が先頭に無い場合はnには何も代入されないので、0で初期化しておきます。
チェックのためだけでtmp[]に値をセットする必要は無いのなら、下記のように*で代入を抑止すると、tmp変数が不要になり、tmpのサイズを気にする必要も無くなります。
sscanf(p,"%*[0-9A-Z]%n",&n);
実行速度についてはこのケースでは#2さんの通り、sscanfを使わないほうが速いと思います。
No.2
- 回答日時:
余計なお世話的なアドバイスをします。
気に入らなければ無視してください。もっと複雑な文字列スキャンを実装したいのならともかく、4文字以内の大文字英数という程度の条件だったら、質問文前半にあるように1文字ずつ調べた方が早い(速い)です。
わざわざsscanf()を用いる理由は、学習のためでしょうか? だったらなおさら無駄です。そもそもscanf()系関数は複雑怪奇な仕様で、バグの温床になりやすく、安易に使用すべきではないのです。
上記のことから、ご質問のような実装は推奨できません。
ちなみに、scanf()系関数のフォーマットの %[ は、正規表現とは違いますので、混同されませんように。。。
No.1
- 回答日時:
int tmp2; を追加して、
ret = sscanf(p, "%4[0-9A-Z]%c", tmp,&tmp2);
でどうでしょうか。
5文字以上あれば、5文字目がtmp2に入って、retが2になる。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
sscanfとscanfの違いがよくわか...
-
CStringのFindで文字列検索を行...
-
反転した数値を表示させるやり方
-
C言語で16進数文字列から16進数...
-
fgets関数を使用したときの文字...
-
小文字のみを数える方法
-
記号を入出力する際の指定子
-
strstrを利用しない文字列検索...
-
itoaわかりません
-
C言語:配列の中の文字を。。。
-
2進数から10進数へ変換プログラム
-
C言語のステップ数をカウントす...
-
[Java]文字列分割
-
10進数文字列の変換
-
Cで「大文字、小文字の判定」は...
-
charと%c , %s の関係について
-
へんな現象
-
Enterキーを押されたら次の処理...
-
#define _CRT_SECURE_NO_WARNIN...
-
マイナスからプラスへ転じた時...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CStringのFindで文字列検索を行...
-
sscanfとscanfの違いがよくわか...
-
反転した数値を表示させるやり方
-
fgets関数を使用したときの文字...
-
C言語 空白の行(改行のみ)が...
-
charと%c , %s の関係について
-
C言語のステップ数をカウントす...
-
fgetsで拾われる改行文字を削除...
-
itoaわかりません
-
C言語で16進数文字列から16進数...
-
strstrを利用しない文字列検索...
-
文字列中に含まれる文字の個数...
-
Cで「大文字、小文字の判定」は...
-
エディットボックスに入力され...
-
1行の文字列を時間差で表示する...
-
文字列の途中に「0」がある場...
-
[Java]文字列分割
-
教えていただけませんか?C言語...
-
atoiでの文字列以外のエラー処...
-
ブランクのチェック
おすすめ情報