2011-08-07 3 views
2

빈 채워진 고정 폭 레코드를 작성하려면 주어진 위치에서 시작하여 StringBuilder 객체에 문자열 필드를 복사하고 싶습니다. 이것에 대한 좋은 구문은C#에서는 StringBuilder 객체의 부분 문자열에 "정적"복사를 수행합니다.

을했을 것이다
StringBuilder sb = new StringBuilder(' ', 100); 
string fieldValue = "12345"; 
int startPos = 16; 
int endPos = startPos + fieldValue.Length - 1; 
sb[startPos..endPos] = fieldValue; // no such syntax 
나는 분명히 한 번에이 C 스타일, 하나 개의 문자를 할 수

:

for (int ii = 0; ii++; ii < fieldValue.Length) 
    sb[startPos + ii] = fieldValue[ii]; 

그러나이 방법은 C#을 너무 성가신 것, 플러스는 루프를 사용 그 결과로 생성 된 기계 코드는 대량 복사를보다 효율적으로 사용할 수 있었고 관련 문자열이 길면 차이를 만들 수있었습니다. 더 좋은 방법에 대한 아이디어가 있습니까?

답변

1

다음과 같은 방법으로 지원 될 수 있습니다 후드, 특히 String.CopyTo :

public class FixedStringBuilder 
{ 
    char[] buffer; 

    public FixedStringBuilder(int length) 
    { 
     buffer = new string(' ', length).ToCharArray(); 
    } 

    public FixedStringBuilder Replace(int index, string value) 
    { 
     value.CopyTo(0, buffer, index, value.Length); 
     return this; 
    } 

    public override string ToString() 
    { 
     return new string(buffer); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     FixedStringBuilder sb = new FixedStringBuilder(100); 
     string fieldValue = "12345"; 
     int startPos = 16; 
     sb.Replace(startPos, fieldValue); 
     string buffer = sb.ToString(); 
    } 
} 
+0

고마워요.이게 내가 찾고있는 정확한 것입니다. 불변의 System.String의 메소드로서 그것을 찾기 위해 절대로 나에게 일어나지 않을 것이다 :) Thanks! –

0

목표에 가장 가까운 솔루션은 문자 배열의 소스 문자열을 변환 한 다음 셀을 대체하는 것입니다. 모든 char 배열은 다시 문자열로 변환 될 수 있습니다.

0

문자열 빌더에서 메모리를 사전 할당하는 이유는 성능 만 지원하는 것입니다.

나는 알려진 접두사를 추가 한 다음 실제 값과 문자열 뒤에 접미사를 붙입니다.

뭔가 같은 :

StringBuilder sb = new StringBuilder(); 
sb.Append(prefix).Append(value).Append(postfix); 
+0

알려진 고정 길이의 정적 문자 시퀀스가 ​​있고 주어진 "주소"에서 작은 영역을 덮어 쓰려는 "찾기"시나리오는 다루지 않습니다. –

2

는 원래 알고리즘은 아래 char[]string의 효율적인 기계를 사용하여 당신은 당신의 자신의 전문 스트링 빌더 클래스를 작성할 수

var builder = new StringBuilder(new string(' ', 100)); 
string toInsert = "HELLO WORLD"; 
int atIndex = 10; 
builder.Remove(atIndex, toInsert.Length); 
builder.Insert(atIndex, toInsert); 

Debug.Assert(builder.Length == 100); 
Debug.Assert(builder.ToString().IndexOf(toInsert) == 10); 
+3

꼬리를 앞뒤로 움직이기 때문에 char-by-char 바꾸기보다 느릴 수도 있습니다. 나는 단순한 루프 대신에 그것을 권하고 싶지 않다. –

+0

이와 같은 단일 알고리즘 연산의 경우, 문자열을 사용하고 빌더를 모두 잊어 버릴 것입니다. 과도합니다. 루프에서 여러 번 수행해야 할 작업에 대해서는 효율성을 원하지만 확실한 이유가 있습니다. 배열에서'char' 치환 연산은 합리성 측정기에서 더 낮은 순위를 가지므로 추정 된 성능 이득은 그만한 가치가 있어야합니다. –

+0

시나리오에 따라 크게 달라집니다. 예를 들어 큰 파일을 읽고 처음 몇 군데를 교체하면 성능이 크게 떨어집니다. 그리고 가독성을 위해'for'와'Remote' /'Insert' 변종은 거의 동일합니다. 그래서 기본적으로 OP까지입니다 :) –