Recommendation on How to build a long string

M

Mo

Hi,

I am trying to write a code to build a string 768 characters long.
This string is going to be written to a file which is then read by
another application. The format of the string is already defined. For
example Firstname starts at position 20, Last Name at position 30,
address at position 40 etc... I am reading these data from sql
datasource and must substitute the values in the exact position
insuring that paramteres end up exactly at position they need to be. I
have this running now but I am looking for a smarter method. I am
trying to build a string with 768 spaces to initalize. Then replace
the spaces with characters one at a time to insure location of all
parameters are preserved. I tried using stringbuilder but it does not
have the functionality I am lookign for. Does Any body has a smart way
of dong this?

character Position
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
FirstName LastName Address
street City st Zip xxx xxxxx xxxx

Thanks,
Mo
 
J

Jon Skeet [C# MVP]

Mo said:
I am trying to write a code to build a string 768 characters long.
This string is going to be written to a file which is then read by
another application. The format of the string is already defined. For
example Firstname starts at position 20, Last Name at position 30,
address at position 40 etc... I am reading these data from sql
datasource and must substitute the values in the exact position
insuring that paramteres end up exactly at position they need to be. I
have this running now but I am looking for a smarter method. I am
trying to build a string with 768 spaces to initalize. Then replace
the spaces with characters one at a time to insure location of all
parameters are preserved. I tried using stringbuilder but it does not
have the functionality I am lookign for. Does Any body has a smart way
of dong this?

Firstly, are you sure you actually need to make this faster? Is your
current code readable, and have you measured its performance? I would
only start going for more complicated options when you've got an issue.

Having said that, you could create a type which stores a char array and
allows you to replace portions of it easily - then create a new string
from that char array appropriately.
 
B

Bruce Wood

Hi,

I am trying to write a code to build a string 768 characters long.
This string is going to be written to a file which is then read by
another application. The format of the string is already defined. For
example Firstname starts at position 20, Last Name at position 30,
address at position 40 etc... I am reading these data from sql
datasource and must substitute the values in the exact position
insuring that paramteres end up exactly at position they need to be. I
have this running now but I am looking for a smarter method. I am
trying to build a string with 768 spaces to initalize. Then replace
the spaces with characters one at a time to insure location of all
parameters are preserved. I tried using stringbuilder but it does not
have the functionality I am lookign for. Does Any body has a smart way
of dong this?

character Position
012345678901234567890123456789012345678901234567890123456789012345678901234­567890123456789
FirstName LastName Address
street City st Zip xxx xxxxx xxxx

I would do something like this:

if (firstName.Length > 10) firstName = firstName.Substring(0, 10);
....etc...
longString = String.Format("{0,10}{1,10}...", firstName,
lastName, ... );

This is the easiest to read. I would tune it for speed only in the
case that I were to benchmark it and find that it really is a
bottleneck in my code.
 
B

bob clegg

hi,
If I read your question correctly you have a series of Database
records which you are going to retrieve and turn into a text file
possibly for some proprietary system input.
My instinct on this one is:
Create a class
It would contain a series of strings.
One for each parameter.
Create an array of strings filled with spaces.
each array entry would contain the number of padding spaces that its
index represents.
ie ar[5] would be " " 5 spaces
In your data retrieval create and fill a series of these classes

Do the maths on the inbound strings and store the padded results.

the filled items into a collection say stack<T>

When writing to the file pop each item off and use its ToString() to
give you the finished line to write to file.

It is probably slower than the other suggestions, but you will find it
easy to maintain in 6 months when they change the file spec on you.

Use a stringbuilder in the ToString() override to easily concat the
whole lot.
or...
maybe I have been drinking too much coffee and this is overkill.
FWIW
Bob
Sort of like:
class stFixedString
{

string[] arSpace;
//Length constants
const int iGivenName = 20;
const int iSurname = 25;




public stFixedString()
{
arSpace = new string[5];
arSpace[0]="";
arSpace[1]=" ";
arSpace[2] = " ";
//etc

}
private string msGivenName;
public string GivenName
{
get { return msGivenName ; }
set
{
msGivenName = value + arSpace[iGivenName -
value.Length];

}

}
private string msSurname;
private int miSurnameLength;

public string Surname
{
get { /*as above*/ }
set {/*as above*/ }
}
public override string ToString()
{
StringBuilder s = new StringBuilder();
s.Append(msGivenName);
s.Append(msSurname);
return s.ToString();
}



}
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Mo said:
Hi,

I am trying to write a code to build a string 768 characters long.
This string is going to be written to a file which is then read by
another application. The format of the string is already defined. For
example Firstname starts at position 20, Last Name at position 30,
address at position 40 etc... I am reading these data from sql
datasource and must substitute the values in the exact position
insuring that paramteres end up exactly at position they need to be. I
have this running now but I am looking for a smarter method. I am
trying to build a string with 768 spaces to initalize. Then replace
the spaces with characters one at a time to insure location of all
parameters are preserved. I tried using stringbuilder but it does not
have the functionality I am lookign for. Does Any body has a smart way
of dong this?

character Position
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
FirstName LastName Address
street City st Zip xxx xxxxx xxxx

Thanks,
Mo

Use the StringBuilder to build the string from left to right, instead of
trying to creating a string and put things into it.

Example:

StringBuilder record = new StringBuilder();
record.Append(firstName);
record.Append(' ', 40 - record.Length);
recoRd.Append(lastName);
record.Append(' ', 80 - recoed.Length);
....
string result = record.ToString();
 
B

Bruce Wood

Use the StringBuilder to build the string from left to right, instead of
trying to creating a string and put things into it.

Example:

StringBuilder record = new StringBuilder();
record.Append(firstName);
record.Append(' ', 40 - record.Length);
recoRd.Append(lastName);
record.Append(' ', 80 - recoed.Length);
...
string result = record.ToString();

This looked promising until I noticed the following.

1. StringBuilder.Append doesn't have an Append signature for (string,
int). It does, however, have (string, int, int), where the first int
is the start location in the string, so, Göran's code is easily
changed:

StringBuilder record = new StringBuilder();
record.Append(firstName);
record.Append(' ', 0, 40 - record.Length);
record.Append(lastName);
record.Append(' ', 0, 80 - record.Length);
....
string result = record.ToString();

However, this still doesn't work, because if firstName or lastName is
longer than the maximum length, then the resulting record will be
misaligned, and the second int argument, the number of characters to
append, will be negative. The latter will cause Append to throw an
ArgumentOutOfRange exception.

So, you need to truncate the strings (if necessary), and _then_ do the
Append:

StringBuilder record = new StringBuilder();
if (firstName.Length > 40) firstName = firstName.Substring(0, 40);
record.Append(firstName);
record.Append(' ', 0, 40 - record.Length);
if (lastName.Length > 80) lastName = lastName.Substring(0, 80);
record.Append(lastName);
record.Append(' ', 0, 80 - record.Length);
....
string result = record.ToString();
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Bruce said:
This looked promising until I noticed the following.

1. StringBuilder.Append doesn't have an Append signature for (string,
int).

Of course not, but it has an overload for Append(char, int), which is
what's used in the code.

Strings are delimited with quotes (").
Chars are delimited with apostrophes (').
It does, however, have (string, int, int), where the first int
is the start location in the string, so, Göran's code is easily
changed:

StringBuilder record = new StringBuilder();
record.Append(firstName);
record.Append(' ', 0, 40 - record.Length);
record.Append(lastName);
record.Append(' ', 0, 80 - record.Length);
...
string result = record.ToString();

Nope. That doesn't even compile.
However, this still doesn't work, because if firstName or lastName is
longer than the maximum length, then the resulting record will be
misaligned, and the second int argument, the number of characters to
append, will be negative. The latter will cause Append to throw an
ArgumentOutOfRange exception.

So, you need to truncate the strings (if necessary), and _then_ do the
Append:

StringBuilder record = new StringBuilder();
if (firstName.Length > 40) firstName = firstName.Substring(0, 40);
record.Append(firstName);
record.Append(' ', 0, 40 - record.Length);
if (lastName.Length > 80) lastName = lastName.Substring(0, 80);
record.Append(lastName);
record.Append(' ', 0, 80 - record.Length);
...
string result = record.ToString();

This is simpler, creates less strings and doesn't change the original
values:

StringBuilder record = new StringBuilder();
record.Append(firstName, 0, Math.Min(firstName.Length, 40));
record.Append(' ', 40 - record.Length);
record.Append(lastName, 0, Math.Min(lastName.Length, 40));
record.Append(' ', 80 - record.Length);

It also has the added benefit of working. ;)
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Bruce said:
Ouch. Need to reduce the resolution of my monitor, obviously. Didn't
notice the difference between ' and " in your code. Sorry.


No, of course it wouldn't: I cut-and-pasted your code, assuming that
the char ' ' was in fact a string " ".


I know it's nit-picky, but your code and my code create the same
number of strings, I believe. The benefit of yours is that, as you
stated, it doesn't alter firstName or lastName.

Nope, my code creates a smaller (or sometimes equal) number of strings. :)

When you use Substring to truncate a string, it creates another string.
Instead I use the overload of the Append method that appends a part of a
string. This does not create an extra truncated string, but reads
directly from the original string.

The difference in performance is of course negligable in this case.
Creating another string hardly ever makes a difference, at least not
when they are as small as here, and as few. :)
 
B

Bruce Wood

Nope, my code creates a smaller (or sometimes equal) number of strings. :)

When you use Substring to truncate a string, it creates another string.
Instead I use the overload of the Append method that appends a part of a
string. This does not create an extra truncated string, but reads
directly from the original string.

Right you are.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top