How to format a string with fixed width fields - c#

I'm was wondering if there is a way to format a string to format a string, what I mean is, I have a foreach loop that get a information from some files and how many records has each file, as the length of each file is different the format is change.
My example is, I have 3 files:
1.- MyFile1.txt RecordCount: 5
2.- anotherfile.txt RecordCount: 8
3.- MyTestFile.doc RecordCount: 17
As you can see are not formated, I want something like this:
1.- MyFile1.txt RecordCount: 5
2.- anotherfile.txt RecordCount: 8
3.- MyTestFile.doc RecordCount: 17
does not matter the length of the file, RecordCount will be in the same place.
What I have is this:
foreach (RemoteFileInfo file in MySession.EnumerateRemoteFiles(directory.RemoteDirectory, directory.RemoteFiles, EnumerationOptions.None))
{
BodyMessage.Append((index + 1) + ". " + file.Name + " Record Count: " + File.ReadAllLines(Path.Combine(directory.LocalDirectory, file.Name)).Length.ToString() + "\n");
index++;
}
Any idea?

You can try using \t in your strings which will insert a tab or you can try padding each portion so they always take up the same amount space.
For example:
string fileName = file.Name.PadRight(50);
will ensure that the string fileName is at least 50 characters long. I say at least because you could always have a file name that is larger than 50 characters.

foreach (RemoteFileInfo file in MySession.EnumerateRemoteFiles(directory.RemoteDirectory, directory.RemoteFiles, EnumerationOptions.None))
{
int lines= File.ReadAllLines(Path.Combine(directory.LocalDirectory, file.Name)).Length.ToString();
string appending = String.Format("{0,2}.- {1,-18} RecordCount: {3}", file.Name, lines);
BodyMessage.Append(appending);
index++;
}
See MSDN: String.Format Method.

Firstly, use string.Format, rather than concatenation:
int lineCount = File.ReadAllLines(Path.Combine(directory.LocalDirectory, file.Name)).Length.ToString();
string message = string.Format("{0}. {1}\t Record Count: " {2}\n", (index + 1), file.Name, lineCount);
To answer your question, you can align text within a formatted string using the following syntax:
string message = string.Format("{0}. {1,-10}\t Record Count: " {2}\n", (index + 1), file.Name, lineCount);
The additional -10 will ensure that the inserted text is left-padded to 10 characters.

I think you can use PadRight or PadLeft function for this.
string _line = item.FirstName.PadRight(20) + item.Number.PadRight(20) + item.State.PadRight(20) + item.Zip.PadRight(20);
file.WriteLine(_line);

Related

Appending file name giving back incorrect string

I'm currently trying to add a DateTime stamp, a prefix and a unique number to a file name. My desired output is:
\ParentDirectory\Sub Directory\Another Sub Directory\Prefix- Unique Number - 11 29 2016 2 07 30 PM.xlsx
Prefix and Unique Number above will be passed into the function. I'm using the following method to achieve this:
public static string AppendDateTimeToFileName(this string fileName, string prefix, string uniqueNumber)
{
return string.Concat(
Path.GetFullPath(fileName),
Path.Combine(prefix + " - " + uniqueNumber + " - "),
Path.GetFileNameWithoutExtension(fileName),
DateTime.Now.ToString()
.Replace("/", " ")
.Replace(":", " ")
.Trim(),
Path.GetExtension(fileName)
);
}
I call the above method as:
string fileName = #"\\ParentDirectory\Sub Directory\Another Sub Directory\MyFile.xlsx";
string adjustedFileName = fileName.AppendDateTimeToFileName("Shipping Note", "0254900");
The output I receive is as follows:
\ParentDirectory\Sub Directory\Another Sub Directory\Shipping Note -\0254900 - 11 29 2016 2 08 10 PM
As you can see in the above output the string is incorrect, firstly I get an extra -\ and the file extension isn't coming through either. Can someone tell me where I'm going wrong please.
Here's how I'd do it
public static string AppendDateTimeToFileName(this string fileName, string prefix, string uniqueNumber)
{
return Path.Combine(
Path.GetDirectoryName(fileName),
string.Concat(
prefix,
" - ",
uniqueNumber,
" - ",
Path.GetFileNameWithoutExtension(fileName),
DateTime.Now.ToString("MM dd yyyy h mm ss tt"),
Path.GetExtension(fileName)));
}
This correctly uses Path.Combine to combine the directory from Path.GetDirectoryName and you're new concatenated file name. Note I also used a date format string instead of the replacements. You might want to consider changing that format and putting a separator between the file name and the date.
The posted version of your code give the following output:
\ParentDirectory\Sub Directory\Another Sub Directory\MyFile.xlsxShipping Note - 0254900 - MyFile29 11 2016 15 46 48.xlsx
and NOT as you posted:
\ParentDirectory\Sub Directory\Another Sub Directory\Shipping Note -\0254900 - 11 29 2016 2 08 10 PM
if your desired output is:
\ParentDirectory\Sub Directory\Another Sub Directory\Prefix- Unique Number - 11 29 2016 2 07 30 PM.xlsx
You need to move the directory into the Path.Combine and use GetDirectoryName. Also remove the line:
Path.GetFileNameWithoutExtension(fileName)
since in your desired output I don't see the old file name "MyFile".
This code:
public static string AppendDateTimeToFileName(this string fileName, string prefix, string uniqueNumber)
{
return string.Concat(
Path.Combine(Path.GetDirectoryName(fileName), prefix + " - " + uniqueNumber + " - "),
DateTime.Now.ToString()
.Replace(".", " ")
.Replace(":", " ")
.Trim(),
Path.GetExtension(fileName)
);
}
will yield the following output:
\ParentDirectory\Sub Directory\Another Sub Directory\Shipping Note - 0254900 - 29 11 2016 15 39 37.xlsx

How do I align text like columns in a treeview?

I have a TreeView where I want to arrange my data nicely.
I format my string like this:
string name = ItemName;
string current = ("Current: " + info.Current.ToString() + " " + identifier);
string maximum = ("Maximum: " + info.Max.ToString() + " " + identifier);
string minimum = ("Minimum: " + info.Min.ToString() + " " + identifier);
string output = string.Format("{0,-20}{1,-30}{2,-30}{3,-30}{4,-30}", name, current, maximum, minimum, average);
dataNode.Text = output;
When I write output to the console it prints it the way I want it, like this (values are off, but that's irrelevant):
Load Current: 9,23 % Maximum: 33,33 % Minimum: 6,06 % Average: 0 %
Temperature Current: 40 °C Maximum: 49 °C Minimum: 38 °C Average: 0 °C
Clock Current: 1200 Mhz Maximum: 2800,09 Mhz Minimum: 1200 Mhz Average: 0 Mhz
etc..
But when I print the exact same strings to my TreeView it shows it like this:
I followed the example on this page but that didn't work for me.
I guess it has something to do with the different nodes I use in my TreeView but I don't know how to properly align my data.
seems like you need to set monospaced font for TreeView.
here is a similar question with example of monospaced font (FontFamily.GenericMonospace):
C# .NET multiline TextBox with same-width characters
This is a perfect situation for .PadRight() or .PadLeft().
string output =
string.Format("{0}{1}{2}{3}{4}",
name.PadRight(20),
current.PadRight(30),
maximum.PadRight(30),
minimum.PadRight(30),
average.PadRight(30));
This code will ensure that the space taken up by each parameter is the same every time.
You can use other controls how alow to create columns like :
There are a number of sample controls to be found around the web:
TreeViewAdv for .Net
TreeView with Columns
ContainerListView and TreeListView
Try just to change font of treeView to use a
non-proportional font like "Courier" , "Consolas"

Line up Characters

I have a combobox made up of two numbers; inches and millimetres. At the moment it is looking hideous. I am wondering if some of the gurus here have anyway of lining the character '|' or at least make it nicer?
A bit of background info, the number inches and millimetres are separate strings which I append together like so:
Size(in) + " (In) | " + Size(mm) + " (mm)"
Possibly the cleanest way would be to format every number to have 3 decimal places for at least inches. This still won't be perfect however since the letter font width won't be perfect, to fix that you'd need to use a monospaced font.
To format to 3dp you can use the following
String.Format("{0:f3}", Size(in)) + " (In) | " + Size(mm) + " (mm)"
Since you have some values that are 2 digits before the decimal you can always use PadLeft to align these, but again this doesn't always work well without a monospaced font..
String.Format("{0:f3}", Size(in)).PadLeft(5, ' ') // or (5, '0')
Use String.PadRight(i); and String.PadLeft(i); where i is a nr. of spaces to "fill":
Example:
// Just to simplify a little, create vars:
var inches = Size(in) + " (In) ";
var mm = " + Size(mm) + " (mm)";
var formatted = inches.PadRight(15) + "|" + mm.PadLeft(15);
Example of output using 15 for the padding value (obviously, you can adjust this as needed):
43 inches | 123 cm
445554 inches | 12345 cm

Format custom numeric string with fixed character count

I need to convert any number in a fixed format with a fixed amount of characters. Means 1500 and -1.5 or 0.025 need to have the same length. I also have to give the format in this form: Format = "{???}";
When i type Format = "{0000}"; i can limit 1500 to "1500", but -1.5 -> "-0001.5" means i have too much numbers after the point.
Negative sign place can be done with Format = "{ 0.0;-0.0; 0.0}".
How can i fix the count of the numbers for different numbers?
The length of the string doesn't matter, the most important is the equal length.
Examples:
1500 -> " 1500.000" or " 1500"
-1500 -> "-1500.000" or "- 1500" or " -1500"
1.5 -> " 1.500" or " 1.5"
-0.25-> " -0.250" or "- 0.25"
0.00005 -> " 0.000" or " 0"
150000-> " 150000.0" or " 150000"
15000000 " 15000000"
Edit:
I want to Format an y-Axis of a Chart. I can't use something like value.ToString("???") i need to use chartArea.AxisY.LabelStyle.Format = "{???}";
Why don't use formatting? "F3" forces 3 digits after decimal point and PadLeft ensures the overall length
Double value = 1500.0;
// 3 digits after decimal point, 9 characters length
String result = value.ToString("F3").PadLeft(9, ' ');
0 -> 0.000
1500.0 -> 1500.000
-1500.0 -> -1500.000
-0.25 -> -0.250
Another (similar) possibility is String.Format:
Double value = 1500.0;
// Put value at place {0} with format "F4" aligned to right up to 9 symbols
String result = String.Format("{0:9,F4}", value);
Try it > result = Math.Round(yourValue, 3);
Check full reference here !
you cannot achieve this by a simple format function
string result = string.Empty;
var array = dec.ToString().Split('.');
if (dec > 0)
{
result = array[0].PadLeft(9).Remove(0, 9);
if (array.Count() > 1)
{
result += '.' + array[1].PadRight(3).Remove(3);
}
}
else
{
result = "-"+array[0].PadLeft(9).Remove(0, 9);
if (array.Count() > 1)
{
result += '.' + array[1].PadRight(3).Remove(3);
}
}

Format a string into columns

Is there a cool way to take something like this:
Customer Name - City, State - ID
Bob Whiley - Howesville, TN - 322
Marley Winchester - Old Towne, CA - 5653
and format it to something like this:
Customer Name - City, State - ID
Bob Whiley - Howesville, TN - 322
Marley Winchester - Old Towne, CA - 5653
Using string format commands?
I am not too hung up on what to do if one is very long. For example this would be ok by me:
Customer Name - City, State - ID
Bob Whiley - Howesville, TN - 322
Marley Winchester - Old Towne, CA - 5653
Super Town person - Long Town Name, WA- 45648
To provide some context. I have a drop down box that shows info very similar to this. Right now my code to create the item in the drop down looks like this:
public partial class CustomerDataContract
{
public string DropDownDisplay
{
get
{
return Name + " - " + City + ", " + State + " - " + ID;
}
}
}
I am looking for a way to format this better. Any ideas?
This is what I ended up with:
HttpContext.Current.Server.HtmlDecode(
String.Format("{0,-27} - {1,-15}, {2, 2} - {3,5}",
Name, City, State, ID)
.Replace(" ", " "));
The HtmlDecode changes the to a space that can withstand the space removing formatting of the dropdown list.
You can specify the number of columns occupied by the text as well as alignment using Console.WriteLine or using String.Format:
// Prints "--123 --"
Console.WriteLine("--{0,-10}--", 123);
// Prints "-- 123--"
Console.WriteLine("--{0,10}--", 123);
The number specifies the number of columns you want to use and the sign specifies alignment (- for left alignment, + for right alignment). So, if you know the number of columns available, you could write for example something like this:
public string DropDownDisplay {
get {
return String.Format("{0,-10} - {1,-10}, {2, 10} - {3,5}"),
Name, City, State, ID);
}
}
If you'd like to calculate the number of columns based on the entire list (e.g. the longest name), then you'll need to get that number in advance and pass it as a parameter to your DropDownDisplay - there is no way to do this automatically.
In addition to Tomas's answer I just want to point out that string interpolation can be used in C# 6 or newer.
// with string format
var columnHeaders1 = string.Format($"|{0,-30}|{1,-4}|{2,-15}|{3,-30}|{4,-30}|{5,-30}|{6,-30}", "ColumnA", "ColumnB", "ColumnC", "ColumnD", "ColumnE", "ColumnF", "ColumnG");
// with string interpolation
var columnHeaders2 = $"|{"ColumnA",-30}|{"ColumnB",-4}|{"ColumnC",-15}|{"ColumnD",-30}|{"ColumnE",-30}|{"ColumnF",-30}|{"ColumnG",-30}";
I am unable to add a comment above, but in the accepted answer it was stated:
If you'd like to calculate the number of columns based on the entire list (e.g. the longest name), then you'll need to get that number in advance and pass it as a parameter to your DropDownDisplay - there is no way to do this automatically.
This can in fact be done programmatically at runtime by creating the format string 'on the fly':
string p0 = "first";
string p1 = "separated by alignment value x";
int x = n * 10; // calculate the alignment x as needed
// now use x to give something like: {0,-20}, {1}
string fmt = "{0,-" + x + "},{1}"; // or whatever formatting expression you want
// then use the fmt string
string str = string.Format(fmt, p0, p1)
// with n = 2 this would give us
"first ,separated by alignment value x"

Categories

Resources