4

いくつかのアドレスをテキストファイルに保存してから、グループメンバーシップに基づいてファイルの特定の部分を読み取りたい。私はグループメンバーシップのすべての作業を行ったので、そのための助けは必要ありません。

しかし、プレーンテキストファイルとINIファイルのどちらを使用すべきかわかりませんか?
問題は、投稿アドレスが2行または3行であり、改行が必要なことです。
プレーンテキストファイルを使用してみましたが、改行を正しく取得できませんでした。

では、INIファイルが望ましいでしょうか?

INIファイルは次のようになります。

【ロンドン】
住所(1
ポストボックス3245
58348ロンドン

【コペンハーゲン】
アドレス2
郵便ポスト2455
5478347コペンハーゲン

INIファイルでこれが可能かどうかはよくわかりませんが、おそらく各行にも名前を付ける必要があります。または、プレーンテキストファイルを使用して[london]という単語を検索し、改行がなくなるまで各行を読み取ることもできます。次に、これらのすべての行を、渡す変数に格納しますか?

どうやってこれを解決しますか?

4

4 に答える 4

2

このような形式で書かれた「実際の」ini ファイルを処理する小さな VBScript クラスを作成しました。

[セクション名]
キー 1 = 値 1
キー 2 = 値 2

クラスのコードは次のとおりです。

Class IniFileObject
    Private m_Data

    Private Sub Class_Initialize
        Set m_Data = Server.CreateObject("Scripting.Dictionary")
    End Sub

    Private Sub Class_Terminate
        Dim key
        If IsObject(m_Data) Then
            For Each key In m_Data
                m_Data(key).RemoveAll
                Set m_Data(key) = Nothing
            Next
            m_Data.RemoveAll
            Set m_Data = Nothing
        End If
    End Sub

    Public Function Init(sFilePath)
        Dim arrLines, sLine, x
        Dim sCurSection, oSectionDict
        Set Init = Me
        arrLines = GetFileLines(sFilePath)
        If Not(IsArray(arrLines)) Then Exit Function
        sCurSection = ""
        For x = 0 To UBound(arrLines)
            sLine = Trim(arrLines(x))
            If Len(sLine)>0 Then
                If Left(sLine, 1)="[" Then
                    If Not(HandleSectionLine(sLine, sCurSection)) Then Exit Function
                Else  
                    If Len(sCurSection)=0 Then
                        Err.Raise 1005, "IniFileObject init", "Found value outside any section (" & Server.HTMLEncode(sLine) & ")"
                        Exit Function
                    End If

                    Set oSectionDict = m_Data(sCurSection)
                    If Not(ParseOneLine(sLine, oSectionDict)) Then Exit Function
                    Set m_Data(sCurSection) = oSectionDict
                End If
            End If
        Next
    End Function

    Public Property Get ReadValue(section, key)
        Dim oSectionDict
        ReadValue = ""
        If m_Data.Exists(section) Then
            Set oSectionDict = m_Data(section)
            If oSectionDict.Exists(key) Then ReadValue = oSectionDict(key)
        End If
    End Property

    Private Function ParseOneLine(ByVal sLine, ByRef oSectionDict)
        Dim arrTemp, sErrorMsg, sKey
        sErrorMsg = ""
        ParseOneLine = True
        If Left(sLine, 2)="//" Or Left(sLine, 1)="'" Or Left(sLine, 1)="{" Then Exit Function
        arrTemp = Split(sLine, "=")
        If UBound(arrTemp)=1 Then
            sKey = Trim(arrTemp(0))
            If (Len(sKey)>0) And (Len(arrTemp(1))>0) Then
                If Not(oSectionDict.Exists(sKey)) Then
                    oSectionDict.Add sKey, Trim(arrTemp(1))
                Else  
                    sErrorMsg = "Key already exists"
                End If
            Else  
                sErrorMsg = "Empty key or value"
            End If
        Else  
            sErrorMsg = "Missing or too much '=' characters"
        End If
        Erase arrTemp
        If Len(sErrorMsg)>0 Then
            ParseOneLine = False
            Err.Raise 1006, "IniFileObject Init", "Failed to parse single line (" & Server.HTMLEncode(sLine) & "): " & sErrorMsg
        End If
    End Function

    Private Function HandleSectionLine(ByVal sLine, ByRef sCurSection)
        HandleSectionLine = False
        If (Len(sLine)<3) Or (Right(sLine, 1)<>"]") Then
            Err.Raise 1002, "IniFileObject init", "Invalid line found: " & Server.HTMLEncode(sLine)
            Exit Function
        End If

        sCurSection = Mid(sLine, 2, Len(sLine) - 2)
        If m_Data.Exists(sCurSection) Then
            Err.Raise 1003, "IniFileObject init", "Section exists more than once: " & Server.HTMLEncode(sCurSection)
            Exit Function
        End If

        m_Data.Add sCurSection, Server.CreateObject("Scripting.Dictionary")
        HandleSectionLine = True
    End Function

    Private Function GetFileLines(sFilePath)
        Dim objFSO, oFile
        Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
        If Not(objFSO.FileExists(sFilePath)) Then
            Set objFSO = Nothing
            Err.Raise 1001, "IniFileObject init", "file path '" & Server.HTMLEncode(sFilePath) & "' does not exist, check permissions"
            Exit Function
        End If
        Set oFile = objFSO.OpenTextFile(sFilePath)
        GetFileLines = Split(oFile.ReadAll, VBCrLf)
        oFile.Close
        Set oFile = Nothing
        Set objFSO = Nothing
    End Function
End Class

使用例:

Dim filePath, ini
filePath = Server.MapPath("config.ini")
Set ini = New IniFileObject.Init(filePath)
Response.Write("Value for 'Key001': " & ini.ReadValue("MySection", "Key001") & "<br />")
Set ini = Nothing

ファイルが存在しないか無効な行が含まれている場合、コードはさまざまなエラーをスローします。エラーはかなり明確です。消費時にそのようなコードを使用することで、エラーを「抑制」し、エラーページを表示しないことが可能です:

On Error Resume Next
    Set ini = New IniFileObject.Init(filePath)
    If Err.Number<>0 Then
        Response.Write("Error reading ini file")
    End If
On Error Goto 0
If IsObject(ini) Then
    Response.Write("Value for 'IP001': " & ini.ReadValue("IPaddress", "IP001") & "<br />")
    Set ini = Nothing
End If
于 2011-09-19T10:49:26.360 に答える
1

各行が国を表す代わりに、おそらくCSVファイルを使用するでしょう。

Country,Address1,Address2,Address3,Address4
London,Address 1,Postbox 3245,58348 London
Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen

データを簡単に識別できる場合は、おそらくよりわかりやすい列名 (Street1、Street2、Town、Postcode など) を使用できます。

このファイル形式は、一度に入力ファイルの 1 行のみを読み取り、次のようなものを使用して分割するため、読み取りも簡単です。

aAddress = split(sLine, ",")

作業をさらに簡単にするために、辞書オブジェクトを使用し、国をキーとして、配列を値として使用できます

'sLine should be read from input file'
sLine = "Copenhagen,Address 2,Postbox 2455,5478347,Copenhagen"

'Create dictionary for addresses'
Set dic = CreateObject("Scripting.Dictionary")

'Split line into array'
aAddressParts = Split(sLine, ",") 

'Remove the first element of the array'
sValues = Mid(sLine, InStr(sLine, ",")+1)
aValues = Split(sValues, ",")

'Add new entry into dictionary'
dic.Add aAddressParts(0), aValues

'Usage'
MsgBox "Address for Copenhagen: " & vbNewLine & _
    Join(dic("Copenhagen"), "," & vbNewLine)

ありがとう、マチェイ

于 2010-08-19T18:19:42.273 に答える
1

アドレスを 1 行に格納し、アンダースコアなどの特殊文字を使用して改行を示すことができます。アドレスを読み取るときは、特殊文字を改行に置き換えるだけです。

[ロンドン]
アドレス = "Postbox 3245_58348 London"

[コペンハーゲン]
住所 = 「Postbox 2455_5478347 コペンハーゲン」

これにより、より多くの行を含む住所や、郵便ポストの行がない住所も保存できます。私の経験では、「私たちの住所は常に正確に 2 行あり、最初の行は常に郵便ポストです」などの情報は、非常に多くの場合間違っています...

于 2010-08-16T10:33:31.597 に答える
0

そのためにネイティブ API を起動する小さな実行可能ファイルを使用します: GetPrivateProfileStringおよびWritePrivateProfileString

実行可能ファイルは次のように呼び出されます。

Set sh = CreateObject("WScript.Shell")
Set exec = sh.Exec("ini.exe get %APPDATA%\sth\file.ini ""Section name"" key")
sFirma1 = exec.StdOut.ReadLine
Call sh.Run("ini.exe set %APPDATA%\sth\file.ini ""Section name"" key set_value", 0)

VbScript を使用してコマンド ラインをサイレント モードで実行し、出力を取得するも参照してください。.

これは実行可能ファイルのコードです:

#include <stdio.h>
#include <windows.h>

void usage()
{
  puts("ini <get>/<set> <file> <section> <key> <value>");
  exit(1);
}

int main(int cArg, char **aszArg)
{
  int iFile = 2;
  int iSection = 3;
  int iKey = 4;
  int iValue = 5;
  if (cArg < 5) usage();
  if (strcmp(aszArg[1], "get") != 0 && strcmp(aszArg[1], "set") != 0) usage();
  if (strcmp(aszArg[1], "set") == 0 && cArg < iValue + 1) usage();
  if (strcmp(aszArg[1], "set") == 0) {
    if (!WritePrivateProfileString(aszArg[iSection], aszArg[iKey],
                                   aszArg[iValue], aszArg[iFile]))
      puts("Failure in WriteProfileString.");
  } else {
    char buf[1000];
    buf[0] = 0;
    GetPrivateProfileString(
      aszArg[iSection], aszArg[iKey], "", buf, 999, aszArg[iFile]);
    puts(buf);
  }
  return 0;
}

Windows 用の ac コンパイラを使用してコンパイルする必要があります。私は gcc でそれを行いましたが、ms の無料のコンパイラも動作するはずです。32 ビットの実行可能ファイルを含むこのページがまだ利用可能な場合は、試してみることができますが、自己責任で行ってください。ハッカーはすでに私のサイトを 1 回訪れました。

于 2013-06-05T14:42:41.350 に答える