C# string.format add a "-" value? - c#

I have a string.format issue ...
I'm trying to pass my invoice ID as an arguments to my program ... and the 6th argument always end up with "-" no matter what I do ( we must use the ¿ because of an old program ) ...
public static void OpenIdInvoice(string wdlName, string IdInvoice, Form sender){
MessageBox.Show(string.Format("¿{0}",IdInvoice));
proc.Arguments = string.Format("{0}¿{1}¿{2}¿{3}¿{4}¿­{5}",
session.SessionId.ToString(),
Session.GetCurrentDatabaseName(),
session.Librairie,
wdlName,
"",
IdInvoice
);
System.Windows.Forms.MessageBox.Show(proc.Arguments);
In the end, "-" is always added to my formatted result, but only before my IdInvoice ... (so Id 10 ends up -10 in my Arguments )
now the fun part ... I hardcode some string and ...
if I pass -1 instead of an Id, I have --1 as a result and If I write "banana" ... i get "-banana" ...
I know I could just build the string otherwise ... but I'm getting curious as to why it happens.
Here's the screenshot ...
EDIT :
thats the copy/paste of my code
var proc = new System.Diagnostics.ProcessStartInfo("Achat.exe");
System.Windows.Forms.MessageBox.Show(string.Format("¿{0}",args));
proc.Arguments = string.Format(#"{0}¿{1}¿{2}¿{3}¿{4}¿­{5}¿{6}",
"12346", //session.SessionId.ToString(),
"fake DB",//Session.GetCurrentDatabaseName().ToString(),
"false", //session.Librairie.ToString(),
"myScreenName", //wdl.ToString(),
"123456",
"Banana",
"123456"
//args.ToString(),
);
System.Windows.Forms.MessageBox.Show(proc.Arguments);
System.Windows.Forms.MessageBox.Show(args);
and thats the copy/paste of my text visualiser result :
12346¿fake DB¿false¿myScreenName¿123456¿­Banana¿123456

You literally have an extra character before "{5}" that's called a soft hyphen. It's one of those weird characters that isn't always displayed. If you place your cursor after the "{" in "{5}" and press the left arrow and then press backspace it will actually delete it. That or you can try to use an editor like Notepad++ that will display it. I was able to find it by running the following code
var t = #"{0}¿{1}¿{2}¿{3}¿{4}¿­{5}";
foreach (var c in t)
{
Console.WriteLine((int)c + " " + c);
}
which printed out
123 {
48 0
125 }
191 ¿
123 {
49 1
125 }
191 ¿
123 {
50 2
125 }
191 ¿
123 {
51 3
125 }
191 ¿
123 {
52 4
125 }
191 ¿
173 -
123 {
53 5
125 }

Related

How to split complex text file in C#? [duplicate]

This question already has answers here:
Reading CSV files using C#
(12 answers)
Closed last month.
I have a text file as below and I want to get only the numbers below column rank:
SKYRain LND(4) VA(x) ZZ(x) NUM(n) Rank ll ListOfNames
------- ------ ----- ----- ------ ---- -- -----------
1002 75 283680 185836 1,111.50 19268 1 Jack
4308 1100 175896 195404 751.70 6384 1 Sara
3070 252 1044788 884160 682.94 18924 1 Robert
3187 206 852280 97932 535.83 16472 1 Harry
I just want the numbers below the rank below:
19268
6384
18924
16472
Is there a way?
You have a fixed width text file. Just can simply use SubString():
public class Program{
public static void Main(){
string aLineOfYourTextFile = " 1002 75 283680 185836 1,111.50 19268 1 Jack ";
Console.WriteLine(aLineOfYourTextFile.Substring(48,5));
}
}
You can also use Split():
public class Program{
public static void Main(){
string aLineOfYourTextFile = " 1002 75 283680 185836 1,111.50 19268 1 Jack ";
var columns = aLineOfYourTextFile.Split(new[]{" "}, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(columns[5]);
}
}
read and skip 2 lines
read next line, split on " ", select 5th entry, convert to int
repeat above till EOF

Unable to Remove \\u0000 From String [duplicate]

This question already has answers here:
Help with \0 terminated strings in C#
(7 answers)
Closed 2 years ago.
I am calling an API that returns a string with the following information: "abc \\u0000\\u0000 fjkdshf". I have tried removing this using the following code but it doesn't seem to work.
string res = str.Replace("\\", string.Empty)
.Replace("u0000", string.Empty)
.Trim();
I have read in a couple of articles that this string doesn't actually display when you are not debugging using Visual Studio so I don't know how to fix this problem. Please help!
you mistake the double backslash as actual characters. They are displayed in the debugger because the second backslash is escaped and the first is used as an escape charachter. if you want to replace it simply use "\u0000".
Here is an examplary programm that prints the UTF code of each character
void Main()
{
string s = "abc \u0000\u0000 fjkdshf";
Console.WriteLine(string.Join(" ", s.Select(x => Convert.ToInt32(x))));
string res = s.Replace("\u0000", string.Empty);
Console.WriteLine(string.Join(" ", res.Select(x => Convert.ToInt32(x))));
}
Output:
97 98 99 32 0 0 32 102 106 107 100 115 104 102
97 98 99 32 32 102 106 107 100 115 104 102
as you can see in the output, after the replacement the zeros are gone!
More information about literal string escaping

Find multiple values and strings within another string in C#

So I have this string with 4 lines:
id score ping guid name lastmsg address qport rate
--- ----- ---- ---------- --------------- ------- --------------------- ------ -----
1 11 45 176387877 Player 1 3250 101.102.103.104:555 3647 25000
2 23 61 425716719 Player 2 3250 105.106.107.108:555 5978 25000
How can I 'extract' all of these values? Like, I want to save "id", "score", "ping", "guid", "name", etc.
I have played around with a "GetBetween" function I found here. I also tried to learn the string.Split function. But I don't think I'm getting close to what I want to archive, also I don't really understand splitting a string quite yet.
I basically need to remove all of the " " empty spaces between the values, problem is, the value length may change, e.g "name".
Can someone give me an example how I could extract the values?
Thanks in advance!
RegEx.Split is your friend, and this works well enough.
void Main()
{
// fun fact, the # in front of the string means it's literal, so you
// literally get the new lines
var input =
#"id score ping guid name lastmsg address qport rate
-- - -------------------------------------------------------------------------
1 11 45 176387877 Player 1 3250 101.102.103.104:555 3647 25000
2 23 61 425716719 Player 2 3250 105.106.107.108:555 5978 25000";
//Gets you each line
var lines = input.Split('\n');
// Skip 2 because I doubt you care about the column title
// or the row with the dashes
foreach (var line in lines.Skip(2))
{
// For each line, Regex split will return an array with each entry
// Set a breakpoint with the debugger and inspect to see what I mean.
// Splits using regex - assumes at least 2 spaces between items
// so space in 'Player 1' is handled it's a fickle solution though
// Trim the line before RegEx split to avoid extra data in the split
var r = Regex.Split(line.Trim(), #"\s{2,}");
}
}
You can do this with Regex and named groups.
Sample Input
var str = #"id score ping guid name lastmsg address qport rate
--- ----- ---- ---------- --------------- ------- --------------------- ------ -----
1 11 45 176387877 Player 1 3250 101.102.103.104:555 3647 25000
2 23 61 425716719 Player 2 3250 105.106.107.108:555 5978 25000";
Regex Definition
var regex = new Regex(#"^(?<id>[\d]+)(\s{2,})(?<score>[\d]+)(\s{2,})(?<ping>[\d]+)(\s{1,})(?<guid>[\d]+)(\s{2,})(?<name>([\w]+\s[\w]+))(\s{2,})(?<lastmsg>[\d]+)(\s{2,})(?<ip>[\d.:]+)(\s{2,})(?<port>[\d]+)(\s{2,})(?<rate>[\d]+)$",RegexOptions.Compiled);
Parsing Code
var lines = str.Split(new []{Environment.NewLine},StringSplitOptions.RemoveEmptyEntries);
foreach(var line in lines)
{
var match = regex.Match(line.Trim());
if(!match.Success) continue;
Console.WriteLine($"ID = {match.Groups["id"].Value}");
Console.WriteLine($"Score = {match.Groups["score"].Value}");
Console.WriteLine($"Ping = {match.Groups["ping"].Value}");
Console.WriteLine($"Guid = {match.Groups["guid"].Value}");
Console.WriteLine($"Name = {match.Groups["name"].Value}");
Console.WriteLine($"Last Msg = {match.Groups["lastmsg"].Value}");
Console.WriteLine($"Port = {match.Groups["port"].Value}");
Console.WriteLine($"Rate = {match.Groups["rate"].Value}");
}
Output
ID = 1
Score = 11
Ping = 45
Guid = 176387877
Name = Player 1
Last Msg = 3250
Port = 3647
Rate = 25000
ID = 2
Score = 23
Ping = 61
Guid = 425716719
Name = Player 2
Last Msg = 3250
Port = 5978
Rate = 25000

How to filter hidden characters in a String using C#

I am new to C# and trying to lean how to filter data that I read from a file. I have a file that I read from that has data similer to the follwoing:
3 286 858 95.333 0.406 0.427 87.00 348 366 4 b
9 23 207 2.556 0.300 1.00 1.51 62 207 41 a
9 37 333 4.111 0.390 0.811 2.03 130 270 64 a
10 21 210 2.100 0.348 0.757 3.17 73 159 23 a
9 79 711 8.778 0.343 0.899 2.20 244 639 111 a
10 66 660 6.600 0.324 0.780 2.25 214 515 95 a
When I read these data, some of them have Carriage return Or Line Feed characters hidden in them. Can you please tell me if there is a way to remove them. For example, one of my variable may hold the the following value due to a newline character in them:
mystringval = "9
"
I want this mystringval variable to be converted back to
mystringval = "9"
If you want to get rid of all special characters, you can learn regular expressions and use Regex.Replace.
var value = "&*^)#abcd.";
var filtered = System.Text.RegularExpressions.Regex.Replace(value, #"[^\w]", "");
REGEXPLANATION
the # before the string means that you're using a literal string and c# escape sequences don't work, leaving only the regex escape sequences
[^abc] matches all characters that are not a, b, or c(to replace them with empty space)
\w is a special regex code that means a letter, number, or underscore
you can also use #"[^A-Za-z0-9\.]" which will filter letters, numbers and decimal. See http://rubular.com/ for more details.
As well as using RegEx, you can use LINQ to do something like
var goodCharacters = input
.Replace("\r", " ")
.Replace("\n", " ")
.Where(c => char.IsLetterOrDigit(c) || c == ' ' || c == '.')
.ToArray();
var result = new string(goodCharacters).Trim();
The first two Replace calls will guard against having a number at the end of one line and a number at the start of the next, e.g. "123\r\n987" would otherwise be "123987", whereas I assume you want "123 987".
Try my sample here on ideone.com.

Best way to Find which cell of string array contins text

I have a block of text that im taking from a Gedcom (Here and Here) File
The text is flat and basically broken into "nodes"
I am splitting each node on the \r char and thus subdividing it into each of its parts( amount of "lines" can vary)
I know the 0 address will always be the ID but after that everything can be anywhere so i want to test each Cell of the array to see if it contains the correct tag for me to proccess
an example of what two nodes would look like
0 #ind23815# INDI <<<<<<<<<<<<<<<<<<< Start of node 1
1 NAME Lawrence /Hucstepe/
2 DISPLAY Lawrence Hucstepe
2 GIVN Lawrence
2 SURN Hucstepe
1 POSITION -850,-210
2 BOUNDARY_RECT (-887,-177),(-813,-257)
1 SEX M
1 BIRT
2 DATE 1521
1 DEAT Y
2 DATE 1559
1 NOTE * Born: Abt 1521, Kent, England
2 CONT * Marriage: Jane Pope 17 Aug 1546, Kent, England
2 CONT * Died: Bef 1559, Kent, England
2 CONT
1 FAMS #fam08318#
0 #ind23816# INDI <<<<<<<<<<<<<<<<<<<<<<< Start of Node 2
1 NAME Jane /Pope/
2 DISPLAY Jane Pope
2 GIVN Jane
2 SURN Pope
1 POSITION -750,-210
2 BOUNDARY_RECT (-787,-177),(-713,-257)
1 SEX F
1 BIRT
2 DATE 1525
1 DEAT Y
2 DATE 1609
1 NOTE * Born: Abt 1525, Tenterden, Kent, England
2 CONT * Marriage: Lawrence Hucstepe 17 Aug 1546, Kent, England
2 CONT * Died: 23 Oct 1609
2 CONT
1 FAMS #fam08318#
0 #ind23817# INDI <<<<<<<<<<< start of Node 3
So a when im done i have an array that looks like
address , string
0 = "1 NAME Lawrence /Hucstepe/"
1 = "2 DISPLAY Lawrence Hucstepe"
2 = "2 GIVN Lawrence"
3 = "2 SURN Hucstepe"
4 = "1 POSITION -850,-210"
5 = "2 BOUNDARY_RECT (-887,-177),(-813,-257)"
6 = "1 SEX M"
7 = "1 BIRT "
8 = "1 FAMS #fam08318#"
So my question is what is the best way to search the above array to see which Cell has the SEX tag or the NAME Tag or the FAMS Tag
this is the code i have
private int FindIndexinArray(string[] Arr, string search)
{
int Val = -1;
for (int i = 0; i < Arr.Length; i++)
{
if (Arr[i].Contains(search))
{
Val = i;
}
}
return Val;
}
But it seems inefficient because i end up calling it twice to make sure it doesnt return a -1
Like so
if (FindIndexinArray(SubNode, "1 BIRT ") != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[FindIndexinArray(SubNode, "1 BIRT ") + 1].Replace("2 DATE ", "").Trim();
}
sorry this is a longer post but hopefully you guys will have some expert advice
Can use the static method FindAll of the Array class:
It will return the string itself though, if that works..
string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, item => item.Contains("Sex") || item.Contains("Drugs") || item.Contains("Computer"));
The => indicates a lamda expression. Basically a method without a concrete implementation.
You can also do this if the lamda gives you the creeps.
//Declare a method
private bool HasTag(string s)
{
return s.Contains("Sex") || s.Contains("Drugs") || s.Contains("Computer");
}
string[] test = { "Sex", "Love", "Rock and Roll", "Drugs", "Computer"};
Array.FindAll(test, HasTag);
What about a simple regular expression?
^(\d)\s=\s\"\d\s(SEX|BIRT|FAMS){1}.*$
First group captures the address, second group the tag.
Also, it might be quicker to dump all array items into a string and do your regex on the whole lot at once.
"But it seems inefficient because i end up calling it twice to make sure it doesnt return a -1"
Copy the returned value to a variable before you test to prevent multiple calls.
IndexResults = FindIndexinArray(SubNode, "1 BIRT ")
if (IndexResults != -1)
{
// add birthday to Struct
I.BirthDay = SubNode[IndexResults].Replace("2 DATE ", "").Trim();
}
The for loop in method FindIndexinArray shd break once you find a match if you are interested in only the first match.

Categories

Resources