2010-06-10 78 views
1

我正在嘗試將VB6程序轉換爲C#。有大量的字符串拆分成結構。例如,將字符串解析爲多個可變長度字符串(C#)

Dim Sample AS String 
Sample = "John Doe  New York Test Comment" 

Public Type Struct1 
    Name As String * 15 
    Address As String * 10 
    Comment As String * 20 
End Type 

Dim dataStruct As Struct1 

Set dataStruct = Sample 

當dataStruct設置後,它會自動將值分割爲3個結構成員。是否有一個特殊的功能在C#中執行此操作。我知道如何做到這一點的唯一方法是通過描述字符串長度和起始位置的Attributes/Annotation。任何其他建議?

回答

3

你可以看看FileHelpers這個庫有methods這樣做。

+0

謝謝。這段代碼正是我所需要的。 – Nap 2010-06-11 00:50:53

2

我不知道任何內置的方法來做到這一點,但使用屬性聽起來像是一個很好的方法來做到這一點。然後你可以編寫一個代碼來通過反射來設置相關的屬性。除非字符串中有空白,否則我會將其表示爲相對順序和長度,而不是開始位置 - 然後您可以找到所有屬性,按照它們的順序進行排序(不應要求它們是連續的) - 排序0,10,20,30,40更容易在需要時添加額外的屬性),並以這種方式進行分割。

+0

我可能需要放置開始和結束,因爲我跳過一些值 – Nap 2010-06-11 00:52:05

1

您可以使用運算符重載來模擬賦值行爲。這樣目標類也定義了部件的大小,因此每個類必須知道輸入的外觀。這是比VB示例更多的代碼。

示例(語法可能是不正確的,我用運算符重載很少):

class DataItem 
{ 
    public String Name {get;set;} 
    public String Address {get;set;} 
    public String Comment {get;set;} 

    public static implicit operator DataItem(string value) 
    { 
    DataItem item = new DataItem(); 
    item.Name = string.Substring(0, 10).Trim(); 
    item.Address = string.Substring(10, 25).Trim(); 
    item.Comment = string.Substring(25, 45).Trim(); 
    return item; 
    } 
} 

[...] 
DataItem item = sampleString; 
[...] 

更具可讀性的選擇將是一個隱含的創造者模式:

class DataItem 
{ 
    public String Name {get;set;} 
    public String Address {get;set;} 
    public String Comment {get;set;} 

    public static DataItem FromString(String string) 
    { 
    DataItem item = new DataItem(); 
    item.Name = string.Substring(0, 10).Trim(); 
    item.Address = string.Substring(10, 25).Trim(); 
    item.Comment = string.Substring(25, 45).Trim(); 
    return item; 
    } 
} 

[...] 
DataItem item = DataItem.FromString(sampleString); 
[...] 
+0

您可能意指'公共靜態隱式運算符DataItem(字符串值)',因此您可以說'DataItem item =「...」';您無法在C#中更改賦值運算符。 – Ruben 2010-06-10 11:24:27

+0

謝謝,糾正它(我認爲) – dbemerlin 2010-06-10 11:30:02

3

你可以嘗試使用隱式運算符:

class Program 
{ 
    static void Main(string[] args) 
    { 
     string sample = "John Doe  New York Test Comment"; 
     MyClass c = sample; 
    } 
} 

public class MyClass 
{ 
    public string Name; 
    public string Address; 
    public string Comment; 

    public MyClass(string value) 
    { 
     //parsing of value and assigning to Name, Adress, Comment comes here 
    } 

    public static implicit operator MyClass(string value) 
    { 
     return new MyClass(value); 
    } 
} 

爲了解析字符串值,你可以使用正則表達式。

1

像這樣的結構映射技巧如果沒有P/Invoke編組器就無法工作。一個結構的內部組織是不可發現的。 JIT編譯器很容易利用這一點,如果它爲結構產生較小的內存大小,則會交換成員。只有[StructLayout]可以指定它。

在Microsoft.VisualBasic命名空間中還有另外一個好處,它使得這件事變得容易。 TextFieldParser類可以通過一次調用輕鬆地轉換這樣的字符串。例如:

using System; 
using System.IO; 
using Microsoft.VisualBasic.FileIO; // NOTE: add reference to Microsoft.VisualBasic 

class Program { 
    static void Main(string[] args) { 
     var strm = new StringReader("John Doe  New York Test Comment"); 
     var parse = new TextFieldParser(strm); 
     parse.TextFieldType = FieldType.FixedWidth; 
     parse.SetFieldWidths(16, 10, 12); 
     foreach (var field in parse.ReadFields()) 
      Console.WriteLine(field.Trim()); 
     Console.ReadLine(); 
    } 
} 

請注意,您發佈的原始字符串與結構聲明不匹配,我不得不修改字段寬度。另請注意,TextFieldParser接受任何流,它不一定是存儲在StringReader中的字符串。讀取文件的StreamReader將是更典型的用法。

+0

這很好,但我需要將每個字段放在指定的記錄。但它是一個有趣的visualbasic功能。給予upvote – Nap 2010-06-11 00:55:02