ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年4月27日(土) 19:07

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 6 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2005年7月01日(金) 16:48 
関数で、引数として与えられた文字列から、
一行(開始位置から改行まで)を取り出して返すという関数を
作っているのですが、うまくいきません^^;

なぜか、改行以降の文字列まで取り出されてしまいます^^;

えと、ソースは……

'' 与えられた文字列から、改行までの一行を取り出します。
Function GetLine(ByRef inBuf As String, instpos As Long) As Long
Dim crpos As Long ''改行が見つかった位置
crpos = InStr(instpos,inBuf,ex"\r\n")
inBuf = Mid$(inBuf,instpos,crpos)
GetLine = crpos
End Function

ちなみにバージョンは、4.02.01です。

よろしくお願いします^^;


通報する
ページトップ
   
投稿記事Posted: 2005年7月01日(金) 18:08 
オフライン

登録日時: 2005年5月31日(火) 07:49
記事: 162
変数crposは、inBufの先頭から何文字目にCR+LFコードがあるのかを示しています。
Mid$()関数の第三引数lengrhには取り出す文字数を指定します。
だから、
コード:
inBuf = Mid$(inBuf, instpos, crpos - instpos)
と、こんな感じにしてやればうまく動くはずです。ただし未検証です。データを準備するのが面倒臭かったもので。
頭の中で「こんな感じでいいかな」みたいな (^^;

それから、終端にCR+LFコードがない文字列を関数に渡した場合、どのように動くか予想できますか?
InStr()関数はCR+LFを検知せずcrposには 0 が格納されます。
したがって Mid$()関数のlength引数には負数が渡されることになります。
さて、どうなるでしょう?


通報する
ページトップ
投稿記事Posted: 2005年7月02日(土) 09:07 
ありがとうございました! 今度はちゃんと動きました!

> それから、終端にCR+LFコードがない文字列を関数に渡した場合、どのように動くか予想できますか?
> InStr()関数はCR+LFを検知せずcrposには 0 が格納されます。
> したがって Mid$()関数のlength引数には負数が渡されることになります。
> さて、どうなるでしょう?

おっと、この可能性には考え付いていませんでした^^;
CRLFがない文字列だとエラーになっちゃうんですね^^;

If crpos > 0 Then
  inBuf = Mid$(inBuf,instpos,crpos - instpos)
Else
  ''CRLFが見つからなかったときは、開始位置から最後までを取り出す
  buflen = Len(inBuf)
  inBuf =Mid$(inBuf,instpos,buflen - instpos)
End If

こうしなければいけなかった、と。
まぁ、簡略化のため、

If crpos < 0 Then
  crpos = Len(inBuf)
End If

こういう風にするという手もありますけど。
というより、こっちのほうが簡単なのかな?

ありがとうございました~


通報する
ページトップ
   
投稿記事Posted: 2005年7月02日(土) 14:30 
オフライン

登録日時: 2005年5月31日(火) 07:49
記事: 162
> おっと、この可能性には考え付いていませんでした^^;
> CRLFがない文字列だとエラーになっちゃうんですね^^;
>
> If crpos > 0 Then
>   inBuf = Mid$(inBuf,instpos,crpos - instpos)
> Else
>   ''CRLFが見つからなかったときは、開始位置から最後までを取り出す
>   buflen = Len(inBuf)
>   inBuf =Mid$(inBuf,instpos,buflen - instpos)
> End If

If の条件式部分では、大小比較式の > 0 は必要ないです。
なぜならば、必ず crpos ≧ 0 であるため、負数を考える必要が無いからです。
また、

> If crpos < 0 Then
>   crpos = Len(inBuf)
> End If
>
> こういう風にするという手もありますけど。
> というより、こっちのほうが簡単なのかな?

これは間違いです。書くとすれば、 crpos <= 0 となります。
ただし、やはり crpos は負数を考える必要がないため、
コード:
If crpos = 0 Then
とするのが正解です。


通報する
ページトップ
投稿記事Posted: 2005年7月02日(土) 22:05 
なるほど。 確かに考えてみればそうですね^^
INSTRでは、見つからなければ0が返されてくるので、
負数が戻ってくることはありませんから。

了解しました。

どうも、ありがとうございました~。


通報する
ページトップ
   
投稿記事Posted: 2005年7月06日(水) 00:31 
オフライン

登録日時: 2005年7月03日(日) 10:37
記事: 27
お住まい: 愛知県岡崎市
> > If crpos < 0 Then
> >   crpos = Len(inBuf)
> > End If
> これは間違いです。書くとすれば、 crpos <= 0 となります。
この場合、改行が連続すると行が読み飛ばされますよね?
という訳で、面倒でも私はいちいちシークしています。
メモリ上のバッファに蓄えられた文字列であれば、
シークに驚くような時間は掛かりませんし。

一応サンプルを載せておきます。

====================================================================
'変数宣言
Dim s[100] As Byte '<< 元の文字列
Dim c As String '<< 変換後の文字列
Dim i As Long '<< カウンタ変数
Dim st As Long '<< 始点の記憶用変数
Dim max As Long '<< 文字列の最大バイト数

'文字の登録
lstrcpy( s,Ex"まけイヌ参上!\r\nHello?わっはっは..\nhoge??")

'変数の初期化
c = ""
max = lstrlen(s)
st = 0
i = 0

'順次シーク処理
While i < max
'DBCSの検証 (全角?半角?)
Select Case IsDBCSLeadByte(s)
Case 0: '<< 半角
Select Case s
Case &h0d: 'キャリッジリターンの検証
c = c + "[改行]"
i = i + 1
st = i + 1
Case &h0a: '改行コードの検証
c = c + "[改行]"
st = i + 1
Case Else:
c = c + Chr$(s)
End Select
Case Else: '<< 全角
c = c + Chr$(s) + Chr$(s[i+1])
i = i + 1
End Select
i = i + 1
Wend

'変換後文字の出力
MessageBox( GetForegroundWindow(), c,"改行判定",MB_OK)

'終了
End
====================================================================

_________________
# まけイヌ (losedog2)
# Home : http://www50.tok2.com/home/losedog2/
# Mail : losedog2@yahoo.co.jp


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 6 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[11人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean