ページ 1 / 1
複数行文字列検索・参照
Posted: 2006年5月02日(火) 16:52
by MML
はじめまして。ゆちボンと申します。
いきなりですが、
配列で検索する場合はどうすればよいんでしょうか?
たとえば、
コード: 全て選択
Dim Sample As String
Sample = "Name=ゆちボン
Live=長崎
Work=学生
Comment=よろしくお願いします
"
というところで3列目の「学生」を取得するときはどうすればよいのでしょうか?
また、「学生」という文字列があるかチェックする方法はありますか?
まだ、ActiveBasicダウンロードして、1日目の初心者で
まったくわかりません。
C以外ではインタプリタのプログラミングしか
したことがないので、、、
もし、プログラムが間違っていたらすみません。
Posted: 2006年5月02日(火) 18:52
by イグトランス
コンパイルすると判りますが,文字列の内容を複数行に渡って書く事はできません。
ダブルクォーテーションの数が合わないというエラーになります。
改行を表すには例えばEx文字列で\r\nを使います。
それを連結させてこのようにすれば意図したと思われる内容の文字列ができます。
コード: 全て選択
Dim Sample As String
Sample = Ex"Name=ゆちボン\r\n"
Sample = Sample + Ex"Live=長崎\r\n"
Sample = Sample + Ex"Work=学生\r\n"
Sample = Sample + Ex"Comment=よろしくお願いします\r\n"
また、これは単なる文字列であり配列では無いです。(文字の配列と見なして処理する事はできますが)
さて検索して学生を取得したいとのことですが、どういうアプローチで行うべきでしょうか。
単に"学生"という文字列を検索して取得するのではなく、
"Work="という部分を探してその右にあるものを取り出すなどの方法も考えられます。
Posted: 2006年5月02日(火) 19:12
by MML
イグトランスさん、返信ありがとうございます。
> また、これは単なる文字列であり配列では無いです。(文字の配列と見なして処理する事はできますが)
まだ、インタプリタ言語を使っているころ、
そう呼ぶ言語があったため今でもそう呼んでいます。。。
> さて検索して学生を取得したいとのことですが、どういうアプローチで行うべきでしょうか。
> 単に"学生"という文字列を検索して取得するのではなく、
> "Work="という部分を探してその右にあるものを取り出すなどの方法も考えられます。
「Work=」から取得できたらと思います。
あと、置き換えなどの簡単な文字列処理はできるのでしょうか?
(mid以外で)
Re: 配列検索・参照
Posted: 2006年5月02日(火) 21:14
by 7
> はじめまして。ゆちボンと申します。
はじめまして。7と申します。
> いきなりですが、
> 配列で検索する場合はどうすればよいんでしょうか?
単に文字列の中から特定の文字列を検索する場合、InStr関数というのがあります。
> というところで3列目の「学生」を取得するときはどうすればよいのでしょうか?
これはInStr関数の戻り値とMid$関数を使えば可能じゃないでしょうか。
> 配列で検索する場合はどうすればよいんでしょうか?
> たとえば、
>
コード: 全て選択
> Dim Sample As String
>
> Sample = "Name=ゆちボン
> Live=長崎
> Work=学生
> Comment=よろしくお願いします
> "
>
> というところで3列目の「学生」を取得するときはどうすればよいのでしょうか?
0から始まる行の文字列を取得する関数を前に作ったので置いていきます。
参考にはなるでしょうか...? [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Function OEdit_GetLineText(ByVal lpszText As BytePtr,ByVal nIndex As Long) As BytePtr
' cnt[0]=現在の文字位置
' cnt[1]=現在の行の文字位置
' crlf=現在の行の位置
' length[0]=検索する文字列のバイト数
' length[1]=現在の行の文字列のバイト数
' length[2]=現在の行までの文字列のバイト数
Dim cnt[1] As Long
Dim crlf As Long
Dim length[2] As Long
length[0]=lstrlen(lpszText)
' 文字列の最初から最後まで検索
For cnt[0]=0 To length[0]
' 改行している場合
If (lpszText[cnt[0]]=13) And (lpszText[cnt[0]+1]=10) Then
' 行数と取得したい行数が一致した場合
If crlf=nIndex Then
' 文字列数から現在の行までのバイト数を引く
length[1]=length[0]-length[2]
' 文字列を現在の行までのバイト数から最後まで検索
For cnt[1]=0 To (length[1]-1)
' 改行している場合
If (lpszText[cnt[1]+length[2]]=13) And (lpszText[cnt[1]+length[2]+1]=10) Then
' 現在の行までのバイト数から次の改行コードまでをコピー
OEdit_GetLineText=calloc(cnt[1]+1)
memcpy(OEdit_GetLineText,VarPtr(lpszText[length[2]]),cnt[1])
Exit Function
End If
Next
End If
crlf++
length[2]=cnt[0]+2
'改行コードが見当たらないまま最後まで検索した場合
ElseIf ((lpszText[cnt[0]]=13)=FALSE) And ((lpszText[cnt[0]+1]=10)=FALSE) And (cnt[0]=length[0]) Then
' 現在の行までのバイト数から文字列の最後までをコピー
OEdit_GetLineText=calloc(length[0]-length[2]+1)
memcpy(OEdit_GetLineText,VarPtr(lpszText[crlf]),length[0]-length[2])
End If
Next
End Function
本当はString型に直して載せようと2時間ぐらい頑張ったんですけど無理でした...。
ActiveBasic始めてから2年ぐらい経つ気がするんですけど、Stringってほとんど触ったことがなくて分かりません...。
> また、「学生」という文字列があるかチェックする方法はありますか?
行単位で文字列を取得してその中に「学生」があるかどうか検索するといいと思います。
Re: 配列検索・参照
Posted: 2006年5月04日(木) 20:03
by MML
7さん、はじめまして。
ゆちボンと申します。
> ActiveBasic始めてから2年ぐらい経つ気がするんですけど、Stringってほとんど触ったことがなくて分かりません...。
僕は、String+Long+HWNDぐらいしかわかりません。
あと、Byteです。
実は文字列関係などでまだ質問があります。
デスクトップの幅、高さを求めるにはどうすればよいのでしょうか?
ActiveBasicはバイナリ書き込みができるのでしょうか?
置き換えは自作でするのでしょうか?
色わけエディタ(リッチエディタみたいな)ものはどうすればプログラムできるのでしょうか?
実は、今、文字列+音楽(MIDIコンパイラ)関係のソフトを作っているんです、、、
あと、ActiveBasic練習用+コンパイルする必要がないスクリプトを書くための
プログラム言語とか作っています。
Re: 配列検索・参照
Posted: 2006年5月04日(木) 20:33
by 7
> > ActiveBasic始めてから2年ぐらい経つ気がするんですけど、Stringってほとんど触ったことがなくて分かりません...。
> 僕は、String+Long+HWNDぐらいしかわかりません。
> あと、Byteです。
BOOLなんて簡単で覚えやすいです。TRUEとFALSE、論理値を管理する型なんですけど、LongをTypeDefしたものです。
> 実は文字列関係などでまだ質問があります。
> デスクトップの幅、高さを求めるにはどうすればよいのでしょうか?
GetWindowRect()関数を使って指定されたウィンドウの座標を取得できます。その値を加工することでウィンドウの幅、高さを得ることができます。
デスクトップのウィンドウハンドルを取得するにはGetDesktopWindow()関数を使います。
> ActiveBasicはバイナリ書き込みができるのでしょうか?
よく分からないのですけど、バイナリの書き込みしかできないと思います。
> 置き換えは自作でするのでしょうか?
エディットボックスで置き換えを行う場合、安易な考えですけど、文字列を検索して、当てはまる部分をEM_SETSELで選択、EM_REPLACESELで置き換え、なんて...。
> 色わけエディタ(リッチエディタみたいな)ものはどうすればプログラムできるのでしょうか?
CreateWindowEx()関数でとりあえずウィンドウを作って、そのウィンドウに対し、DrawText()関数やDrawTextEx()関数で文字列を描写します。
前に置いていったコードは自分が独自エディットコントロールを作る時に書いたものです。
自分が参考にしたサイトです。
http://vivi.dyndns.org/tech/tech.phtml
Re: 配列検索・参照
Posted: 2006年5月07日(日) 15:28
by MML
ご回答、ありがとうございます。
7さん。
以前、7さんが、「1行ずつ切り出す」ソースを試してみました。
すると、1行目しか切り出せないんです、、、
どこがだめなのでしょうか、、、?
コード: 全て選択
dim mes As String
dim gyo As Long
mes = "ゆちボン\r\n趣味:MIDI作成\r\nよく使う命令:msgbox"
gyo = 2
OEdit_GetLineText(mes,gyo)
これで動かなかったんです、、、
Stringでは動かないんでしょうか?
考えたんですが、わかりません。
あと、置き換えの方法がわかりません。
教えていただいたのに、ぜんぜんわからなく、、、
TextEditorからではなく、
変数の中にある文字列を(「A」を「B」に)置き換えるという
方法はありませんでしょうか?
Re: 配列検索・参照
Posted: 2006年5月07日(日) 18:53
by 7
> 以前、7さんが、「1行ずつ切り出す」ソースを試してみました。
> すると、1行目しか切り出せないんです、、、
> Stringでは動かないんでしょうか?
すいません。Stringでは動きません...下のようにすると動くと思います。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
dim lineText As BytePtr
dim mes[256] As Byte
dim gyo As Long
lstrcpy(mes,Ex"ゆちボン\r\n趣味:MIDI作成\r\nよく使う命令:msgbox")
gyo = 2
lineText=OEdit_GetLineText(mes,gyo)
MessageBox(0,lineText,Str$(gyo),MB_OK)
free(lineText)
> あと、置き換えの方法がわかりません。
> 変数の中にある文字列を(「A」を「B」に)置き換えるという
> 方法はありませんでしょうか?
置き換えアルゴリズムを考えたことがないので深い所を思いつかないんですけど、 "A" を "B" にするのは簡単ですよね。どっちも1バイト文字ですから。
それが "AA" を "B" にするとか "あ" を "B" にするとか "A" を "ば" にするとかは難しいと思います。
どうやってるんでしょうかね。
試しに作ってみました [ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Dim str[256] As Byte, cmp[256] As Byte, cng[256] As Byte
Dim len As Long, cnt As Long
lstrcpy(str,"abcabcabcabc")
lstrcpy(cmp,"a")
lstrcpy(cng,"i")
len=lstrlen(str)-1
For cnt=0 To len
If str[cnt]=cmp[0] Then
str[cnt]=cng[0]
End If
Next
MessageBox(0,str,"",MB_OK)
動かしてみると、strの中の文字とcmpの文字が一致している所がcngに置き換えられているのが分かると思います。
置き換えってこうやるのかな?的なサンプルなので汎用性に欠けます。
Posted: 2006年5月07日(日) 23:14
by イグトランス
いいえ、ABはString型から暗黙のうちにBytePtr型へ変換します。
コード: 全て選択
#strict
Dim s As String
s = "Hello, world"
MyMsgBox(s)
Sub MyMsgBox(psz As BytePtr)
MessageBox(0, psz, "", MB_OK)
End Sub
それが駄目でもStrPtr関数を使えば確実にString型のデータをBytePtr型として扱えます。
引数の文字列がString型だからできないということはないはずです。できないことがあればそれはコンパイラのバグです。
すみません、今は時間が無いのでどこが悪いかは調べられませんが。
ちなみに戻り値をString型にするにはこういう風に包めば良いと思います。
コード: 全て選択
Function OEdit_GetLineTextStr(ByVal pszText As BytePtr, ByVal nIndex As Long) As String
Dim pszResult As BytePtr
pszResult = OEdit_GetLineText(pszText, nIndex)
OEdit_GetLineTextStr = pszResult
free(pszResult)
End Function
Posted: 2006年5月08日(月) 00:28
by 7
> いいえ、ABはString型から暗黙のうちにBytePtr型へ変換します。
なるほど...最近イグトランスさんにはよく補足してもらっていて頭は下がる一方です...。
> ちなみに戻り値をString型にするにはこういう風に包めば良いと思います。
>
コード: 全て選択
Function OEdit_GetLineTextStr(ByVal pszText As BytePtr, ByVal nIndex As Long) As String
> Dim pszResult As BytePtr
> pszResult = OEdit_GetLineText(pszText, nIndex)
> OEdit_GetLineTextStr = pszResult
> free(pszResult)
> End Function
これは全く気が付きませんでした...( ̄□ ̄;)
Stringで処理せずに、BytePtrで処理した結果をStringに代入してしまえば良かったんですね...。
Posted: 2006年5月08日(月) 13:46
by MML
7さん、イグトランスさん、返信、ありがとうございます。
ActiveBasicのバージョンを見ると僕のは最新版ではありませんでした。
バージョンアップしてからやってみたいと思います。
Posted: 2006年5月16日(火) 18:51
by MML
7さん、イグトランスさん、すみません。
エディタは最新バージョンでした、、、
しかしうまく動きません、、、
どこがおかしいのでしょうか????
1行目までしか読むことができないのですが、、、、
例↓
変数「A」に
「ゆちボン
学生
プログラム
よろしくお願いします」
と、入っていて、
取得しようとすると、
1行目の「ゆちボン」のみしか、取得できません。
Posted: 2006年5月16日(火) 22:36
by 7
> しかしうまく動きません、、、
> どこがおかしいのでしょうか????
> 1行目までしか読むことができないのですが、、、、
直接的な不具合じゃないんですけど、「最終行の文字列が取得できない」という不具合があったので修正しました。
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
Function GetLineText(ByVal lpszText As BytePtr,ByVal nIndex As Long) As BytePtr
' cnt[0]=現在の文字位置
' cnt[1]=現在の行の文字位置
' crlf=現在の行の位置
' length[0]=検索する文字列のバイト数
' length[1]=現在の行の文字列のバイト数
' length[2]=現在の行までの文字列のバイト数
Dim cnt[1] As Long
Dim crlf As Long
Dim length[2] As Long
' 文字列の長さをバイト数で取得
length[0]=lstrlen(lpszText)
' 文字列の最初から最後まで検索
For cnt[0]=0 To length[0]
' 改行している場合
If (lpszText[cnt[0]]=13) And (lpszText[cnt[0]+1]=10) Then
' 行数と取得したい行数が一致した場合
If crlf=nIndex Then
' 文字列数から現在の行までのバイト数を引く
length[1]=length[0]-length[2]
' 文字列を現在の行までのバイト数から最後まで検索
For cnt[1]=0 To (length[1]-1)
' 改行している場合
If (lpszText[cnt[1]+length[2]]=13) And (lpszText[cnt[1]+length[2]+1]=10) Then
' 現在の行までのバイト数から次の改行コードまでをコピー
GetLineText=calloc(cnt[1]+1)
memcpy(GetLineText,VarPtr(lpszText[length[2]]),cnt[1])
Exit Function
End If
Next
End If
crlf++
length[2]=cnt[0]+2
'改行コードが見当たらないまま最後まで検索した場合
ElseIf ((lpszText[cnt[0]]=13)=FALSE) And ((lpszText[cnt[0]+1]=10)=FALSE) And (cnt[0]=length[0]) Then
' 現在の行までのバイト数から文字列の最後までをコピー
GetLineText=calloc(length[0]-length[2]+1)
memcpy(GetLineText,VarPtr(lpszText[length[2]]),length[0]-length[2])
End If
Next
End Function
各変数にコメントを付けているにもかかわらず、clrfとlength[2]を間違えてました。
> 1行目の「ゆちボン」のみしか、取得できません。
以下のコードを実行しても動きませんか?
ウィンドウ作成時の所にでもコピペして実行してください。
コード: 全て選択
Dim str[256] As Byte
Dim pStr As BytePtr
Dim cnt As Long
lstrcpy(str,Ex"変数「A」に\r\n「ゆちボン\r\n学生\r\nプログラム\r\nよろしくお願いします」")
For cnt=0 To 4
pStr=GetLineText(str,cnt)
MessageBox(hMainWnd,pStr,Str$(cnt)+"行目",MB_OK)
free(pStr) : pStr=NULL
Next
こっちはこんな風にメッセージボックスで表示されます。
タイトル : 0行目
メッセージ : 変数「A」に
タイトル : 1行目
メッセージ : 「ゆちボン
タイトル : 2行目
メッセージ : 学生
タイトル : 3行目
メッセージ : プログラム
タイトル : 4行目
メッセージ : よろしくお願いします」
ありがとうございます
Posted: 2006年5月17日(水) 18:56
by MML
ありがとうございます!!
やっと動きました!!