2010-06-10 2 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

methods이있는 FileHelpers 라이브러리를 살펴보십시오.

+0

감사합니다. 이 코드는 내가 필요한 것입니다. – Nap

2

기본 제공 방법은 모르지만 속성을 사용하면 좋은 방법이라고 생각됩니다. 그런 다음 리플렉션을 통해 관련 속성을 설정하는 코드를 작성할 수 있습니다. 문자열에 간격이 없다면 시작 위치가 아닌 상대적인 순서 및 길이로 표현할 것입니다. 그러면 모든 속성을 찾고 순서에 따라 정렬 할 수 있습니다 (연속적 일 필요는 없습니다). 0, 10, 20, 30, 40을 사용하면 필요한 경우 추가 속성을 더 쉽게 추가 할 수 있습니다).

+0

일부 값을 건너 뛰기 때문에 시작과 끝을 배치해야 할 수도 있습니다. – Nap

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

아마도'public static implicit operator DataItem (string value)'을 의미 할 것이므로'DataItem item = "..."';이라고 말할 수 있습니다. C#에서 할당 연산자를 변경할 수있는 방법이 없습니다. – Ruben

+0

고마워, 그것을 고쳤다 (나는 생각한다) – dbemerlin

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

이것은 괜찮지 만, 각 필드를 지정된 레코드에 배치해야합니다. 그러나 흥미로운 시각적 기본 기능입니다. upvote 포기 – Nap

관련 문제