ワイルドカード(*と?)の処理を行うプログラムを作っているのですが、何か便利な関数はあるのでしょうか? strstr関数あたりを駆使するしかないのでしょうか?

(ファイル名のような文字列の一覧表を持っていて、その中から上位から送られてきたワイルドカードを含む文字列に合致する文字列を探し出すルーチンを作っています。蛇足かと思いますが、*は0文字以上の任意の文字、?は1文字の任意の文字です。)

宜しくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

ファイル名正規表現は特例的に簡単に作れます。


この程度なら作っちゃってもいいかも。

共立出版「ソフトウェア作法」(ISBN4-320-02142-8 C3041)に正規表現処理のアルゴリズム解説があります。

アルゴリズム集というより詳細設計の本です。

参考URL:http://kyoritsu-pub.topica.ne.jp/bookhtml/0306/0 …
    • good
    • 0

regcomp,regexecという正規表現を使うための関数がありますが、お使いの処理系にあるかどうかはわかりません(^^;



unixには昔からあるやつで、POSIXにも含まれていますが。

まあ、gnuのライブラリにはあるので,ソースが入手可能ですけど。

参考URL:http://www.linux.or.jp/JM/html/LDP_man-pages/man …
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC(char *s1)の文字列をObjective-Cの文字列(NSS

C(char *s1)の文字列をObjective-Cの文字列(NSString *s2)にするにはどうしたらよいのでしょうか?

char s1[] = "abc";
NSString *s2 = [[NSString alloc] initWithUTF8String:s1];  // (A)

NSLog(@"s2=[%s]", s2);

結果がabcかなと思っていましたが、読めない変な文字が表示されました。
(A)を NSString *s2 = [NSString stringWithFormat:@"%s", s1]; に変えても同じでした。

s1のC文字列は日本語を含まないアルファベットの文字列なのになぜ?と
困っています。

Objective-Cの初心者で申し訳ありません。

Aベストアンサー

> NSLog(@"s2=[%s]", s2);

「initWithUTF8String:」も正しくないけど、直接のまちがいはこちらですね。
正しくは「NSLog(@"s2=[%@]", s2);」です。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html%23//apple_ref/doc/uid/TP40004265

QVC++で文字列から任意の文字を削除するにはどうしたらいいですか?

VC++で文字列から任意の文字を削除するにはどうしたらいいですか?
タイトルのとおりです。
VC++にてあるソフトのプロファイルを作成したいのですが、

[Profile]
Type = Default

となっており、Defaultという部分だけとりたいのです。
ちなみにDefault以外にもGuestやAdminなどもありますので、Type = まで取り出したいのです。

どうしたらいいんでしょうか?
よろしくお願いします。

Aベストアンサー

何がしたいかいまいちわかりませんが、
とりあえず文字列をCStringに一回入れてください。
右側を消したいならTrimRight
特定文字列まで取得したい場合は、FindとLeftとかで。


#include "afx.h"
#include <iostream>
int main()
{
CString str;// ここに文字列を入れる
CString dst;
dst = str = "type = default";
std::cout << str;
// 右側を削除
dst.TrimRight("default");
std::cout << dst << std::endl;
dst = str;
// =までを取得
dst = dst.Left(dst.Find('=')+1);
std::cout << dst << std::endl;

return 0;
}

Q文字列配列をサブルーチンにアドレス渡ししてscanf入力

main関数内で
char strarray[3][21]
という文字列配列を宣言し、
サブルーチンvoid input(・・・)内でscanfを使って
strarray[0]~strarray[2]の各行に入力を行うとします。
ここでポインタを引数としてstrarrayをmainとinputで共有する場合、
strarrayに関して以下の項目はどう記述すればよいのでしょうか?

1)inputを宣言する際の仮引数の書式
2)main内でinputを呼び出す際の引数の書式
3)input内でscanfする際の引数の書式

いろいろ組み合わせを試してはみたのですが、
どうにもSegmentationFaultを回避できません。
いい加減混乱してきたので、そろそろすっきりと整理したいと思っています。
よろしくお願いします。

…まあ「構造体使えばいいじゃないか」と言われてしまえばそれまでなのですが…

Aベストアンサー

まず、配列とポインタの関係から説明します。

C 言語の場合、配列はコンパイラによって、その「先頭要素を指すポインタ」に読み替えられます。

つまり、int hoge[10]; と定義した配列に対して、式の中で hoge と書くと、これは int*型の変数として扱われて、それは &hoge[0] と同じ意味になります。
# 一部例外はあります。
# たとえば、sizeof(hoge) とした場合、ポインタサイズではなくて、配列のサイズが
# 取得できます。

で、これをそのまま配列の配列に適用してみれば良いわけです。

どうなるかというと、char piyo[3][10]; と定義した変数に対して、式の中で piyo と書けば char(*)[10]型の変数として扱われて、それは &piyo[0] と同じ意味になります。

char(*)[10] 型と書きましたが、これは「char型配列(要素数10)を指すポインタ型」のことです。
配列を指すポインタ型の変数を定義する場合には、次のように書きます。
char (*p_piyo)[10];

つまり、piyo はもともと「char型配列(要素数10)の配列(要素数5)」だったわけですよね。
これが、コンパイラによって「char型配列(要素数10)を指すポインタ」として扱われるようになるわけです。

注意点としては、この配列→ポインタの読替え規則は再帰的には行われないことですね。
どういうことかというと、配列の配列は、ポインタのポインタにはならず、配列のポインタにしかならない、ということです。

さて、前置きが長くなりましたが、話を etendard さんのご質問に戻します。

1) これまでの話で、char strarray[3][21] に対してコンパイラが読み替える等価な型が char (*str_ptr)[21] となることはおわかりいただけると思います。

関数の引数に配列を渡す場合は、必ずポインタに読みかえられますので、仮引数の宣言もポインタに読み替えられた方の型で書くことになります。
# というよりも、配列を渡すことができないので、配列の先頭要素を指すポインタを
# 渡している、という言い方のほうが正しいのですけどね。

つまり、プロトタイプは

void input( char (*str_ptr)[21] );

のようになります。
できれば、配列の要素数も一緒に渡せるようにするのが良いでしょう。

その場合は、こんな感じです。

void input( char (*str_ptr)[21], int num );

2) 関数コールする場合は次のようにします。

input( strarray );

要素数付きの場合は、次のようにします。

input( strarray, 3 );

要素数付きにしたほうが良い理由は、ポインタに読み替えられた方の配列の要素数が、関数に渡らないためです。

標準関数では、gets() なんかはその典型ですよね。
# バッファオーバーランの原因となるということで、WARNING を吐くコンパイラも
# あるとか。。。

それに対して fgets() は文字列の数も渡せるので、より安全だといえます。
要するに、それと同じことです。

3) input() の中で scanf() する場合には、次のようにすれば良いです。

for ( i=0; i<3; i++ )
{
scanf( "%s", str_ptr[i] );
}

# なぜこれで良いのかは、よく考えてみてください。

同様に、要素数付きの場合には次のようにします。

for ( i=0; i<num; i++ )
{
scanf( "%s", str_ptr[i] );
}

ちなみに、関数の仮引数の場合に限り、ポインタ宣言と配列宣言は同じ物になります。
# というよりも、いずれもポインタ宣言になります、といった方が正しいです。

つまり、以下の表記はいずれも同じ物になります。

void input( char (*array_ptr)[21] );
void input( char array_ptr[][21] );
void input( char array_ptr[3][21] );

ただし、3番目の表記をした場合であっても、[3] の部分の要素数は無視されます。
# コンパイラが勝手にポインタに読み替えてしまいますからね。

宣言や定義について、このような読替えが起こるのは関数の仮引数宣言の場合だけです。
通常の、宣言や定義ではこのような読替えは起こりませんのでご注意ください。

かなり長くなってしまいましたが、こんな感じでいかがでしょうか。

まず、配列とポインタの関係から説明します。

C 言語の場合、配列はコンパイラによって、その「先頭要素を指すポインタ」に読み替えられます。

つまり、int hoge[10]; と定義した配列に対して、式の中で hoge と書くと、これは int*型の変数として扱われて、それは &hoge[0] と同じ意味になります。
# 一部例外はあります。
# たとえば、sizeof(hoge) とした場合、ポインタサイズではなくて、配列のサイズが
# 取得できます。

で、これをそのまま配列の配列に適用してみれば良いわけです。

どうな...続きを読む

Qマージ型文字列のデリミタ2文字以上のSplit関数のようなものは実現できますか?

素人で間違っているかもしれませんが、String::Splitは wchar_tのように1文字だけしか使えないので、\r\nのような2文字以上のデリミタに対応しているperlのsplit関数みたいのを探しています。
以下のソースで※ここですの部分で、2文字以上の任意のデリミタでマージ型文字列を配列にしたいです。

.NETは覚えたてですが、Vista以降でも廃れることは無いのでしょうか?
覚えて無意味はきついので・・・

/*
VC++2005でperlのようなsplit関数を実現したい
区切り文字は\r\n
*/

using namespace System;

int main( array<String^>^ args ){
String^ str = nullptr;
if (1 > args->Length ){
str = "太郎\r\n花子\\純一郎";
} else {
str = args[0];
}

// strマージ文字列をPerlのsplit関数のようなもので、以下のようなnamesを作成したい。
// $names = split /\r\n/ $str; <=※ここです。
array<String^> ^names = { "太郎", "花子", "純一郎" };

String^ name;
for each ( name in names ) {
Console::WriteLine("{0}", name);
}

return 0;
}

素人で間違っているかもしれませんが、String::Splitは wchar_tのように1文字だけしか使えないので、\r\nのような2文字以上のデリミタに対応しているperlのsplit関数みたいのを探しています。
以下のソースで※ここですの部分で、2文字以上の任意のデリミタでマージ型文字列を配列にしたいです。

.NETは覚えたてですが、Vista以降でも廃れることは無いのでしょうか?
覚えて無意味はきついので・・・

/*
VC++2005でperlのようなsplit関数を実現したい
区切り文字は\r\n
*/

using namespace S...続きを読む

Aベストアンサー

String.Split メソッド (String[], StringSplitOptions) のタイプでメソッド使えば可能ですよ

array<string^>^separator = {L"\r\n"};
names = str->Split( separator, System::SptringSplitOptions::RemoveEmptyEntries);

Console::WriteLine( L"{0}", names->Length );
for each ( name in names ) {
  Console::WriteLine( L"{0}", name );
}
といった具合です

Q大文字の文字列→小文字の文字列

C言語初心者です。
ある演習問題をやっていて詰まっています。
自分で入力した大文字の文字列を小文字にするプログラムを作るという問題なのですが、↓の条件があり、こんがらがってしまいました。
・入力した文字列に小文字が含まれていたら、エラーと表示して再び入力を促し、0を入力するとプログラム終了という流れにする。
・ポインタ変数を使う。
・continue文を使う。
・標準ライブラリ関数は使わない。
です。

・continue文というのがよくわからない。
・宣言した関数でどの処理をすればいいのかわからない。
・大文字を小文字にするというプログラムがわからない。
(アスキーコードをどう使うのか)
でつまっています。


どなたかアドバイス・解説・模範解答・指摘などしていただけないでしょうか。
よろしくお願い致します。

Aベストアンサー

> 文字列定数の前に 構文解析エラー
> 警告: 組み込み関数 `printf' と型が矛盾します
> 警告: データ定義が型や記憶クラスを持っていません
>
> というエラーがでました
> これは何ですか・・・?

printfの直前にある } は、int main(void){ の { と対応しています。
つまり、printfは関数の外で呼び出していることになります。
また、<stdio.h>もインクルードしていないようです。

ところで、アルファベットが連続していることは規格上保証されていません。処理系不明の状況で、

> while(a<='A' && a>='Z'){
> if(a>='a' && a<='z') {
> a-='a'-'A';

といった処理は不適切です。

参考URL:http://www.kijineko.co.jp/tech/superstitions/A-to-Z-is-sequence.html


人気Q&Aランキング

おすすめ情報