効率的な部分文字列一致検出アルゴリズムの実装方法

このQ&Aのポイント
  • string1とstring2の部分文字列一致を効率的に検出するアルゴリズムを実装する方法について解説します。
  • 文字列の長さや処理時間を考慮しつつ、部分一致の判定を行うアルゴリズムを提案します。
  • 英数字のみを対象として部分一致を判定する場合の処理方法についても考慮しています。
回答を見る
  • ベストアンサー

部分文字列の一致を検出

2つの文字列がありstring1とstring2とします。 やりたいことは、string1の中のある部分文字列がstring2の部分文字列と一致する場合、真を返す関数を作りたいのです。関数プロトタイプのイメージはこんな感じです。 bool CheckPartialMatch(char* string1, char* string2, int minChars); [機能] string1とstring2の部分文字列(minChars文字数以上)の一致の有無を調査する。 大文字と小文字の区別はしない。 [パラメータ] string1:比較元のNULL終端文字列 string2:比較先のNULL終端文字 minChars:最小一致文字数 例として下記のようなケースを考えます。 string1="BananaAppleOrange" string2="LemonPineappleKiwi" minChars=4の場合、上記例では"appl"の4文字が一致しますのでtrueが返ることになります。 上記例では、minChars<=5ならtrue, minChars>=6ならfalseとなります。 部分一致が1か所でも見つかれば、その時点で以降の調査を打ち切ります。 何か所一致したとか、一致した位置といった情報は返しません。(位置情報は追加コストなしで返せるでしょうが、今回は必要ありません) もちろん、ベタにstring1の1文字目から順に逐一string2と比較すれば実現できるのですが、それでは時間がかかります。 実際には、この処理をあるフォルダ内の全ファイル名に対して行いたいと思っています。 例えばファイル数が100とすると、組み合わせの数は100*(100-1)/2で4950となります。 仮に1ペアのチェックの所要時間が10msとしても、トータルで約50秒かかることになります。 1000ファイルともなると優に1時間を超える所要時間となり、現実的ではありません。 メモリを食い尽くすような処理ではないので放っておけば終わるのでしょうが、本当は数千のファイルに対してこの処理を行いたいと思っています。 以上を高速に処理する手段やアルゴリズムはないでしょうか? boostなど外部のライブラリを使用した方が早いのであれば、それをご提案頂いても構いません。 実際の使用環境ではminCharsが4程度、比較文字列は平均して20文字程度(2バイト文字含む)を想定しています。 処理時間を低減するため、対象文字を英数字('A-Z'、'a-z'、'0-9')のみに限定することもオプションとして考慮したいと思っています。ファイル名ですので、実際には文字列内に2バイト文字や記号類も混じっています。 あらかじめ全ての入力文字列に対して英字を小文字に変換しておくとか、英数字以外の文字を(連続する場合はまとめて)代替文字("@"等)に置換しておけば少しは負荷軽減になるかとは思いますが、効果のほどは不明です。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.11

> 文字コードをUNICODEにしても、サロゲートペアがあるので問題ないとは言えないでしょう。 なるほど。部分文字列の切り出し時に注意が必要ですね。 実際にどの程度の時間がかかるのか、試しにプログラムしてみました。 20-29文字の乱数文字列を複数作成、部分文字列の比較を総当たりで判定。 部分文字列の判定は strstr を使用した力技。 ただし、文字列の切り出しを少しだけ工夫。 OS:Windows7 Home(64ビット) SP1, コンパイラ:VC2012 update 3 部分文字列長(minChars=4) 文字列数 1000=> 1737ms 文字列数 2000=>10004ms 文字列数 3000=>13189ms 文字列数 4000=>36628ms 実行時間が文字列数の二乗に比例していない理由は不明。 誤差にしても1000,3000の場合が短すぎる。 (プログラムが間違っている?) 文字列数1000で2秒以下なので、力技で十分では? このプログラムを再利用するには、unicode対応(char=>wchar_t、サロゲートペアの処理)が必要です。 プログラムは以下の通り。 #include "stdafx.h" #include <cstdio> #include <ctime> #include <iostream> #include <string> #include <vector> #pragma warning(disable:4996) using namespace std; const size_t FileNameLengthBase = 20; // ファイル名の長さ(ベース) const size_t FileNameLengthRand = 10; const size_t FileCount = 1000; const size_t MinChars = 4; // 比較に用いる部分文字列の長さ void init(vector<string>& names) { srand(0); for (vector<string>::iterator it = names.begin(); it != names.end(); ++it) { size_t n = rand() % FileNameLengthRand + FileNameLengthBase; for (size_t i = 0; i < n; ++i) { it->push_back(char('a' + rand() % 26)); } } } bool IsPartialMatch(const char* const str1, const char* const str2, size_t minChars) { bool bResult = false; size_t len = strlen(str2); char* temp = new char[len + 1]; // 比較文字列用のバッファを準備 strcpy(temp, str2); char* last = temp + len; // 比較文字列の最後へのポインタ char* pos = last - minChars; // 比較文字列の最後のパターンへのポインタ for (; temp <= pos; --pos) // 比較文字列の後ろから比較を行う { const char* result = strstr(str1, pos); if (result != nullptr) { bResult = true; break; } *(--last) = 0; // 比較パターンの文字列を終端 } delete [] temp; return bResult; } // 文字列が一致した位置を取得する // 復帰値:文字列が一致した文字列1の位置 // 文字列が一致していない場合、戻り値は0を返す size_t GetPartialMatchPosition ( const char* const str1 , const char* const str2 , size_t minChars , size_t& nPos // 文字列2の一致した位置(出力) ) { size_t nResult = 0; size_t len = strlen(str2); char* temp = new char[len + 1]; // 比較文字列用のバッファを準備 strcpy(temp, str2); char* last = temp + len; // 比較文字列の最後へのポインタ char* pos = last - minChars; // 比較文字列の最後のパターンへのポインタ for (; temp < pos; --pos) // 比較文字列の後ろから比較を行う { const char* pResult = strstr(str1, pos); if (pResult != nullptr) { nResult = pResult - str1; nPos = pos - temp; break; } *(--last) = 0; // 比較パターンの文字列を終端 } delete [] temp; return nResult; } int _tmain(int /*argc*/, _TCHAR* /*argv[]*/) { vector<string> FileNames(FileCount); init(FileNames); int n1(0), n2(0); clock_t start = clock(); size_t MatchCount = 0; for (vector<string>::const_iterator i = FileNames.cbegin(); i != FileNames.cend(); ++i) { n2 = n1 + 1; for (vector<string>::const_iterator j = i + 1; j != FileNames.cend(); ++j) { if (IsPartialMatch(i->c_str(), j->c_str(), MinChars)) { // size_t pos2 = 0; // size_t pos1 = GetPartialMatchPosition(i->c_str(), j->c_str(), MinChars, pos2); // cout << "\"" << *i << "\":" << pos1 << "\t\"" << *j << "\":" << pos2 << endl; ++MatchCount; } ++n2; } ++n1; } clock_t end = clock(); cout << "実行時間:" << end-start << "ms" << endl; cout << "一致した数:" << MatchCount << endl; IsPartialMatch(FileNames[340].c_str(), FileNames[755].c_str(), MinChars); return 0; } 自作の高速化(10倍以上)したプログラムですが、やはり文字列数に依存します。 興味があれば公開してもいいですが。...

katorea21
質問者

お礼

提示頂いたプログラムを私の環境(Win7 x64/Core i7/16GB)で実行してみたところ、下記のような数字が出ました。概ね文字列数の2乗に比例しているようです。 文字列数 1000=>174ms 文字列数 2000=>622ms 文字列数 3000=>1430ms 文字列数 4000=>2550ms 文字列数 10000=>15768ms 上記コードでは、実行ごとに毎回同じ乱数が生成されます。たまたまその乱数のパターンによってそのような結果になったのではないでしょうか?

その他の回答 (10)

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.10

#1 です たぶん現状で移植性と実装のしやすさを考慮するなら、char32_t (UTF-32) 使うのがいいかとは思います。それ以下の Unicode では多バイト文字同様の面倒さが残ります。(別に固定長で表現できれば UTF-32 (32bit) でなくともいい) さきの wchar_t のテストルーチンの件も、事前に多バイト文字データからワイド文字データ (UTF-32) に変換しています。

回答No.9

文字コードをUNICODEにしても、サロゲートペアがあるので問題ないとは言えないでしょう。

katorea21
質問者

お礼

恥ずかしながらサロゲートペアなる言葉を初めて知りました。実際どのような問題があり、解決するためには何が必要でしょうか?アルゴリズムそのものに手を入れる必要がありますか?

回答No.8

> 実際の検索文字列には2バイト文字が含まれています。 > 1バイト文字のみから構成される文字列と比べて性能が劣ることはありますか? 確か文字列は unicode と書いておられたのでは? 文字列比較が char 単位から TCHAR(wchar_t) 単位になるだけでありアルゴリズムによる性能の違いはありません。 問題はシフトJISによる文字列比較であり、2バイト文字の2バイト目の扱いです。 検索パターンの先頭文字がアスキーコードであったとき、被検索文字列中の2バイト文字の2バイト目が一致してしまうことがあります。これを避けるためには文字列比較を工夫する必要がありますが、 unicode であれば問題は無いはずです。 今回の課題は、複数(2~1000程度)のファイル名(約20文字)に対して部分文字列(4文字程度)が一致するかを判定したいとのことですが、実行時間を支配するのはファイル数であり、その計算量はファイル数の二乗に比例し、これを減らすことは困難です。まあ力技でやってもいいのではないかと思います。 プログラムの作成に時間をかけてもいいのであれば、私なら前述した「ラビン-カープ文字列検索アルゴリズム」を応用してみたいです。 まず、各ファイル名について部分文字列のハッシュ値群を作成する(手順1)。 次に、各ファイル名ペアについてハッシュ値群の比較を行い、一致するものがあった場合、そのハッシュ値の元となる部分文字列を比較する(手順2)。 という方法にします。手順1はファイル数に比例する処理時間であり、手順2はファイル数の二乗に比例する処理時間なので、手順2が単純な文字列比較を使用したものより高速ならばこの方法で高速化がはかれます。 手順1で作成するハッシュ値群をソートしておけば、手順2のハッシュ値群の比較では、ソート済の集合から一致するものを探す処理になり、計算量はO(n)になり、効率よく一致判定が可能になります。 ただし、この方法ではひとつひとつのハッシュ値に対して元の部分文字列(元の部分文字列へのリンク)を持っている必要があり、メモリが大量に必要になりそうです。

katorea21
質問者

お礼

詳しいご説明ありがとうございます。ただ自分で実装するのは困難そうです。既に確立したアルゴリズムのようですし、どこかに既成のライブラリがありませんかね?このようなことをやりたい人はそれなりにいると思いますし、フリーのツールもありそうな感じなのですが。

回答No.7

文字列検索のアルゴリズムには「ボイヤー-ムーア文字列検索アルゴリズム」が有名です。 検索パターン文字列長をm、非探索文字列長をnとするとパターンがテキスト内に存在しない場合のボイヤー-ムーア法の最悪ケースは O(n+m) です。パターンがテキスト内に出現する場合の最悪ケースは O(nm) とだそうです。 今回の場合、検索パターン文字列が部分文字列なので、検索パターン文字列全体のサイズをlとすると検索パターンの数kは(l-m+1)なので計算回数の最悪値はl>>mと仮定するとO(nml)となります。一般にはn>>m.lなのでO(n)と考えます(長い文字列から短い文字列を検索する場合)。 検索パターンが複数ある場合は「ラビン-カープ文字列検索アルゴリズム」が有効です。 上記のように単一のパターンの検索の計算量をO(n)とした場合、検索パターン数をk(=l-m+1)とすると、複数パターンの場合、O(nk)となりますが、このアルゴリズムではO(n+k)となるようです。 以上のように文字列比較の計算量を見積もりましたが、l,nが20程度ではこれらのアルゴリズムを適用するコストのほうが大きくなりそうですね。 アルゴリズムの詳細はwikiくんに聞いてください。

katorea21
質問者

お礼

ご回答ありがとうございます。 なるほど、そのようなアルゴリズムがあったのですか。確かに条件によっては比較回数を大幅に削減出来そうですが、実際の検索文字列には2バイト文字が含まれています。1バイト文字のみから構成される文字列と比べて性能が劣ることはありますか?

回答No.6

>比較文字数が奇数の場合はちょっと面倒になりそうですね。 バッファを4バイトの倍数にしておけば、何も面倒なことはありません。 例えば5文字比較の場合、バッファは8バイト用意されていて、最初に全体を'\0'で初期化しておけば6~8バイト目はどのバッファでも'\0'なので比較の妨げにはなりません。

katorea21
質問者

お礼

確かにおっしゃるとおりでした。その例ですと、全ての部分文字列に対して3バイト分余分に消費しますが、たとえ部分文字列が100万個あったとしても3MBに過ぎませんね。GB単位のメモリを積んでいることを考えれば、その程度のオーバーヘッドより比較回数を3分の1に減らす方が効果が高いというわけですね。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.5

> 上記は説明のためにcharと書きましたが、実際は文字列はUnicodeで扱っています。char->TCHARと読み替えてください。 MS depend でしたか。 単純に次のロジックで、試しに適当な文字データで 1000000 くらい回してみましたが、ペア当り数 us というところです。MS でも同じでしょう。 int wcscheck(wchar_t *s1, int l1, wchar_t *s2, int l2, int n) { int i, j, k; for (i = 0; i <= l2 - n; i++) { for (j = 0; j <= l1 - n; j++) { for (k = 0; k < n && s2[i+k] == s1[j+k]; k++) ; if (k == n) return j; } } return -1; }

katorea21
質問者

お礼

TCHARはMS独自の型でしたか。C++はMS以外の世界を知らないもので。 そんな簡潔に書けるんですね。恥ずかしながら無駄に長い40行程度のロジックを書いてしまいました。まあやろうとしていることは同じです。アルゴリズムはライブラリに頼りすぎて自分で書くということを長らくしてこなかったツケが出ています。こんな単純な標準関数がWin32APIやATLに用意されていないんですかね。色々とググってみてもそれらしい物がありませんでした。

回答No.4

私が処理するとしたら、ファイル名ごとに比較用データを持つクラスを作成します。 そのクラスが持つデータとして、 1. 比較文字数で細分化した部分文字列データ (例) 4文字比較するなら、1文字目から4文字目の部分文字列、2文字目から5文字目の部分文字列、... 部分文字列作成時に、大文字小文字の変換やマルチバイト文字を途中で分断しないような処理をしておく。 2. 部分文字列の先頭文字によるテーブル 先頭文字ごとのテーブルを作成して、部分文字列を比較する際に総当たりしなくて済むようにする。 (例) 'B'から始まる部分文字列は1番目のみ、'A'から始まる部分文字列は2番目、4番目... 'D'から始まる部分文字列はない、といった情報テーブル こういった前処理を行ったデータを比較すれば、結構早くなると思います。 が、それでもまだ遅い場合は、ちょっとトリッキーなことをします。 3. 部分文字列を格納するバッファを4バイトの倍数で確保するようにし、最初に'\0'で初期化しておく なぜこのようなことをするかというと、比較を文字列ではなくlongで行うためです。 最近のほとんどのCPUは4バイトのデータを1命令で比較できます。文字列として比較する場合は、終端文字の検出が必要なため、1バイトごとに比較するしかないですが、前準備をしておけば、4バイトごとに比較が可能になり、その方が高速に比較できる可能性があります。

katorea21
質問者

お礼

ご回答ありがとうございます。 部分文字列をあらかじめインデックス化しておくのですね。その処理に要する追加コストを上回る効率化が実現出来れば良いのですが。一度試してみて結果を報告します。 文字列を4バイト単位に区切ってlong型で比較するという発想はありませんでした。CPUのメカニズムに精通していないと分かりませんね。Unicodeであればlong1つ分で2文字になりますか。比較文字数が奇数の場合はちょっと面倒になりそうですね。知的好奇心が湧いてきたので、こちらも一度試してみることにします。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.3

#1 ですが補足として、 高速化としては char * だと multi-byte で面倒なので、事前に wchar_t や char32_t などの内部表現に変換しておく、同時に英小文字を大文字に変換しておく (全角も含むのか?) など処理しておけばやりやすいでしょう。 後は処理量によってはスレッド化すれば。

katorea21
質問者

お礼

ご回答ありがとうございます。 上記は説明のためにcharと書きましたが、実際は文字列はUnicodeで扱っています。char->TCHARと読み替えてください。 おっしゃるとおり、事前準備により効率化出来ないか検討してみます。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

比較対象の文字列が平均20文字程度ということですから、私も力技で十分なのではと思います。 各文字が最初に出現する位置を覚えておく(メモリは使いますが)とかの方法も考えられますが、比較対象の文字数がもっと大きくないと、効果は薄いように思えます。

katorea21
質問者

お礼

ご回答ありがとうございます。 もう少し事前準備を頑張ってみることにします。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.1

> 仮に1ペアのチェックの所要時間が10msとしても、トータルで約50秒かかることになります。 どんな環境なのか知りませんが、今時だと ms レベルは掛からないでしょう。 multi-lang をどう処理するかにも依るとは思いますが、普通に力技で実装してみて -pg でも付けて計測してみたらどうですか?

関連するQ&A

  • java 文字列の部分一致について

    /* 1から50まで順に数を表示する。 但し、その数が3の倍数か3の付く数字の場合、数字の後に!を表示する。 5 の倍数の場合は、数字の後に?と表示する。 両方の条件に合致した場合、数字の後に!?と表示する。 */ class Show{ public static void main(String[] args){ int i = 1;    while(i <= 50){       if(i % 3 == 0 && i % 5 ==0){        System.out.println(i + "!?");      }else if(i % 5 == 0){        System.out.println(i + "?");      }else if(i % 3 == 0){        System.out.println(i + "!");      }else{        System.out.println(i);      }      i++;   } } このような問題で、3を含む数字、とあるので、文字列の部分一致を検索する時に使用するStringクラスのindexOfを使用するのでは?と考えています。しかし、こちらはequalsで判定しますが、3の倍数は上記のコードにもある通り、==で判定しています。文字列判定と ==演算子は同じif(条件)の中には入れる事が出来ないので、じゃあどうする?という具合になってしまっています。どなたか「数が3の倍数か3の付く数字の場合」の処理を教えて頂けないでしょう?よろしくお願い致します。

    • ベストアンサー
    • Java
  • ,で句切って部分一致をファイル出力

    昨日も出したのですが自分で作成してみたんですけどヒントをいただいて作成してみたんですけど間をどうしていいかわからないので教えていただきたく載せました。 よろしくお願いいたします。 コメント部分をつくればいいみたいなのですが… (1)フォルダにファイルを用意する(CSV形式の文字列のファイル) (2)最初に文字列をキーボードから入力させる(文字列は半角で5文字まで、それ以外ならば繰り返し入力させる) (3)フォルダのファイル読み込み、(2)で入力した文字列が含まれている単語をファイルに出力(ファイルは新規作成 例: 読込み元ファイル: river,request,fire,maybe,best,over,coin,confortable, today,task,mary,face,popular,music,rock, mark,fight,replay,listen,pop, ------------------- 入力文字列:fi ファイル出力結果 fire, fight, ---------------------- 入力文字列:re ファイル出力結果 request, fire, replay public class Kadai4 { /** * @param args */ public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ String inputString; // ユーザーがキーボードから入力 // ファイルから1行読み込む String fileString =BufferedReader(FileReader); StringDetect sDetect = new StringDetect( );// ()の中に入れる new StringTokenizer( );// ()の中に入れる if(findMatch(nextToken)){ // ファイルに出す } } public class StringDetect{ private static String inputString = null // コンストラクタ public StringDetect(String str){ //ここに入れる } public static boolean findMatch(String word){ //wordとinputを比較して部分一致があれば //true、一致しなければfalseを返す } } }

    • ベストアンサー
    • Java
  • 文字列比較

    最長10文字の文字列を2件入力し、char型の配列にそれぞれ格納する。2つの文字列を比較し、文字列が同じだったら「equal」を表示し異なっていたら「Not equal」を表示するプログラムを作成せよという課題が出ました。 条件として、11文字以上の文字が入力されたら、先頭から10文字までを有効とし、11文字目以降を無視する。下記のプログラムで文字列1に11文字以上入力すると、うまく動きません。なぜ、うまくいかないかと、どうなおしたらよいかを教えてください。 #include<stdio.h> #include<string.h> #define max_length 10 void get_string (char *p_str, int size); int main() { char string1[max_length+2]; char string2[max_length+2]; printf("文字列1:"); get_string(string1,max_length+2); printf("文字列2:"); get_string(string2,max_length+2); if(!strncmp(string1,string2,max_length)) puts("equal"); else puts("Not equal"); } void get_string (char *p_str, int size) { fgets(p_str,size,stdin); }

  • Javaの文字列の大小比較についてです。

    Javaでは、文字列の大小比較をする時、StringのcompareToを使用しまが… compareToの中の処理は一旦char型に直して、それを比較しているのでしょうか? また、compareToを使用せずに、プログラム内に自分で書いた場合、処理速度は変化ありますか?

    • ベストアンサー
    • Java
  • Excel 文字列 一致

    2つの文字を比較して一致した文字の数を数える関数があれば教えてください。 例えばExcelでA1セルに「海山商事」A2セルに「海猫商事」を入れて比較し、一致している文字数(この場合は「3」)をA3に出力したいのですがどうしたらよいですか?大変恐縮ですがアドバイスください。よろしくお願いします。

  • 文字列を抜き出してきてファイルを生成

    当方はC++を用いております。文字列の部分列にアクセスして、 それを新たに文字列としたいのですが、可能でしょうか? 具体的には、英数字、空白のみからなるレコードがあったとします。 例: 01 po 0979876 7行目から10行目までをとりだします。 0979 これをひとつの文字列とします。 なお、目的は、0979という名のファイルを作ることです。

  • 文字列の動的確保とポインタ配列について

    C言語についての質問です。 現在、キーボードから文字列を読み込みファイルに保存するプログラムを作成しています。 プログラムの条件は、以下の通りです。 1: キーボードから英数字(最長でMAX_LEN(1000)-1文字)を入力して文字列(文字配列)dataに格納後、画面に表示する。 2: 入力された文字列と同じ長さの文字列を格納する領域を動的に確保し、文字列dataをその領域に コピーする。なお、必要な文字配列の長さは文字列の長さ+1バイトである。 3: 文字列endが入力されるか、入力された文字列がNUM_STRING(10)個になるまで1~2の処理を繰り返す 4: 各文字列へのポインタを格納する(char *)型ポインタの配列str_p(サイズ:NUM_STRING)を定義して利用する。 5:1~2の処理が終了した後で、メモリに格納されたすべての文字列をファイルに出力する。ファイル名はoutput.txtとし、最初の行に文字列の個数を、次の行以降に入力された順番と「逆の順番」で文字 列を出力すること。 実行例 input ->st22 st22 input->st1 st1 end ファイルの中身 2 st1 st22 現在完成しているプログラムは以下の通りです。 #include<stdio.h> #include<string.h> #include <stdilb.h> #define NUM_STRING 10 #define MAX_LEN 1000 int main (void) { int n, i; char data[MAX_LEN] = {}; char *str_p[NUM_STRING]; FILE *fp; do { printf("input->"); scanf("%s", data); if (strcmp(data, "end") == 0) { break; } else { printf("%s\n", data); n++ 2の処理 } while(n <= NUM_STRING); if ((fp = fopen("output.txt", "w")) == NULL) { fprintf(stdout, "File open error\n"); } fprintf(fp, "%d\n", n); for (i = n-1; i>0; i--) fprintf(fp, "5s\n", str_p[i]); fclose (fp); return 0; } 特に動的確保のところがよく分かりません。 回答よろしくお願いします。       

  • 配列にある文字と文字列との一致を調べたい

    PHPについては素人同然で このような質問を失礼します。 $hensu に入っている文字と $myword の文字(配列)とを比較して、 一致、不一致の処理を行いたいと考えています。 $myword にはNGのワードを複数入れたいので $myword = explode(",", "ああ,いい,うう"); という処理をするつもりです。 NGワードですので今後も増える可能性が ありますので。 このような形で処理する方法をお教えください。 何卒よろしくお願いします。

    • ベストアンサー
    • PHP
  • 文字列の中の1文字を比較するには?

    XP,Studio.NETでC++を書いています。 文字列の中の1文字を比較したいのですがどのようにしたらいいのかわかりません。 今以下のような文字列がstring[300]に入っているとします。 「\nは改行コードです。printf("");では"から"までの文字が画面に表示されます。」 このとき、1文字ずつを取り出し、文字を比較したいのですが (iを増加) if(string[i]=='\') flag=1; //処理→次にnが来る。 if(string[i]=='"') flag=2; //処理→文字はダブルコーテーション という処理をしたいのですが、 エラー:定数が多すぎます。 エラー:定数が2行目に続いています。 と出ます。どうしたらいいのでしょうか? どなたか教えていただけると幸いです。

  • 文字列

    ・文字列をキーボードから入力する関数を作成する。 書式:char *StrInp(char *pDefStr, int nLen); 引数:char *pDefStf; 初期文字列 int nLen; 入力可能文字数(1~79) 戻り値:正常ならば、入力した文字列の先頭ポインタ、エラー時はNULL。 処理:pDefStrに与えた文字列を初期値とする文字入力を行う。    nLenで指定した文字数まで入力可能とし、その範囲は1~79    までする。入力時の初期カーソル位置は与えた文字列の最後    になります。初期文字列が必要ない場合はヌル文字を与えます。    初期文字列を与えられた場合は、その文字列も更新可能とする。   ・入力の終了は「リターン」キーとする。   ・「BS」キーを押すと、カーソルの1文字前の文字前の文字を    消去する。 という、問いです。難しくてわかりません。どなたかたすけてください。        

専門家に質問してみよう