Trying to understand strange string concatenation behavior - c#

I have a very simple method that takes a string, breaks it into a char array, then creates a new string from the pieces. However it is performing unexpectedly and I don't understand why? Here is a picture of breakpoint. The input string in this case is "20160622".
Edit: Sorry for the pic. Here is the question in text.
internal class Program
{
private static void Main()
{
string test = "20160622";
Console.WriteLine(ConvertDateField(test));
Console.ReadKey();
}
private static string ConvertDateField(string date)
{
var temp = date.ToCharArray();
var output = temp[0] + temp[1] + temp[2] + temp[3] + "-" + temp[4] + temp[5] + "-" + temp[6] + temp[7] + " 00:00:00";
return output;
}
}
The output is "201-06-22 00:00:00".
Edit 2: I understand there are probably better ways to do this. What I am trying to understand is why this code is functioning the way it is. ie. why is the 6 the only char not being concatenated?
As you can see, the fourth char, temp[3] which is a '6', is not being concatenated into the output string. Why?
Edit 3: I solved the problem this way
private static string ConvertDateField(string date)
{
return DateTime.ParseExact(date, "yyyyMMdd", CultureInfo.InvariantCulture).ToString("yyyy-MM-dd 00:00:00");
}
Thank you Steve for your advice.

For your question. The char concat is not a string concat. What happened is that c# is doing Math operation for the chars by casting them to int with ASCII.
The corresponding ascii for temp 1, 2, 3, 4 are 50, 48, 49, 54 which the sum is 201. (what a coincidence)
and then int + string concat resulted in string so the rest of the string worked as expected.
There is an easier way to perform the convert if it was a DateTime object. You can simply call dateTime.ToString("yyyy-MM-dd 00:00:00") and you will get the result you want.

Related

Substring issues - input string was not in a correct format

I'm randomly generating simple math equations and need to get the numbers from the string and convert them into integers so I can add them. However, when I run the program I receive the "input string was not in the correct format" error on the "int N1Q1" line.
Is there something I'm missing? Would there be a better way to extract and convert a number from a string?
Question1.Text = Convert.ToString(random.Next(1, 9) + " + " + random.Next(1, 9) + " = ");
string FirstQuestion = Convert.ToString(Question1.Text);
int N1Q1 = Convert.ToInt32(FirstQuestion.Substring(0,1));
int N2Q1 = Convert.ToInt32(FirstQuestion.Substring(5,1));
Here's a different way to go about it, you could make each random.Next() call into its own variable, then you wont have to do the conversions. Something like this:
int random1 = random.Next(1,9);
int random2 = random.Next(1,9);
Question1.Text = $"{random1} + {random2} = ";
You also don't need to convert Question1.Text to a string, because it is already a string. Also, using this method, you already have the random numbers captured as variables, then you wont have to convert them back into integers
Looks like you are off by one in your substring in N2Q1:
int N2Q1 = Convert.ToInt32(FirstQuestion.Substring(4, 1));
do not forget to declare at the first place the random as the following
Random random = new Random();
second, in N2Q1 you calculated wrong, it should be as the following:
int N2Q1 = Convert.ToInt32(FirstQuestion.Substring(4, 1));

Concatenating a char with an int and a string does odd things

I was coding and needed to build up a file name. I wanted to separate the parts of the file names by an _.
I figured that since I only wanted to add on char in I could use '_'.
int id = 125;
string testWithChar = id + '_' + "Something";
Console.WriteLine(testWithChar);
But when I do I get this:
220Something
Kind of odd.
But if I do it right:
int id = 125;
string testWithString = id + "_" + "Something";
Console.WriteLine(testWithString);
I get the expected output:
125_Something
But I am curious. What is really happening in the first one to give me a different number?
The reason is, C# is considering the char as it's unicode value, and thus the addition between them does not add strings, but integers.
_ in ascii is 95, and thus
int id = 125;
string testWithChar = id + '_' + "Something";
is the equivallent of:
string testWithChar = 125 + 95 + "Something";
In contrast, when you add "_", the addition is done between a string and an integer - and the operator just appends the string to it.
The int value of a char is its place in the ASCII table. '_' is at place 95
When you add an integer to another numeric type, you end up with the result of the addition, rather than the concatenation. In this case, char is a numeric value, so 125 + 95 (value of '_') concatenated with your string gives you 220_Something.
I'd create the string as string.Format("{0}_{1}", id, "Something") instead, particularly as your final string gets more complicated.
The int value is replaced with its ASCII value of 95.
Using string formatting is the most safe way:
Console.WriteLine("{0}_Something", id);

ulong.Parse(string, NumberStyles) Exception C#

i been working on this "string to Binary" method for longer than usual and i have no idea where i m going wrong.
i have already searched the internet for solution but nothing seem to be working the way it supposed to do.
public static string hexToBin(string strValue)
{
byte[] hexThis = ASCIIEncoding.ASCII.GetBytes(strValue.ToString());
string thiI = ToHex(strValue);
ulong number = UInt64.Parse(*string*, System.Globalization.NumberStyles.HexNumber);
byte[] bytes = BitConverter.GetBytes(number);
string binaryString = string.Empty;
foreach (byte singleByte in bytes)
{
binaryString += Convert.ToString(singleByte, 2);
}
return binaryString;
}
ToHex(string) takes string and returns its hex representation.
but all i keep getting is "Input string was not in a correct format." at the ulong.Parse(string, NumberStyle); and no matter what are my inputs i keep getting the "FormatException" "Input string was not in a correct format." Error.
the inputs and its outputs
string: format exception - "Hello"
hex: format exception - "48 65 6C 6C 6F"
byte[]: format exception - { 72, 101, 108, 108, 111 }
i have also tried using the "Hello" string, but it threw me the same error.
would you please let me know what i m doing wrong in here?
i also have tried "Clean/build/rebuild" restart visual studio, but i keep getting the same format exception.
EDIT,, used UInt64.Parse() not ulong.Parse() and the used string is "Hello" w/o quotation.
EDIT #2,,
so i did this based on knittl suggestion and used the Convert.ToUInt64 instead of the parse, but still getting same error
ulong binary;
string binThis;
byte[] ByteThis;
binThis = "Hello";
ByteThis = ASCIIEncoding.ASCII.GetBytes(binThis);
binary = Convert.ToUInt64(ByteThis);
Console.WriteLine(binary);
the CurrentCulture is set to en-US and i m also using en-US keyboard
EDIT #3 - Solved
thanks to knittl
the solution is as follow:
string thestring = "example";
string[] finale = new string[thestring.Length];
foreach (var c in ByteThis)
{
for (int i = 0; i < ByteThis.Length; i++)
{
thestring = Convert.ToString(c, 2);
thestring = "0" + thestring;
if (thestring.Length == 9)
thestring.Remove(0, 1);
finale[i] = thestring;
Console.WriteLine(finale[i]);
}
}
the final for is to check on the solution.
this question aimed to get the binary representation of a given string.
Not totally clear, what your method should do (i.e. what format the input string is. Is it a bas10 number, or already a hexadecimal number?)
If it's a hexadecimal number, use ulong.Parse(inputStr, NumberStyles.HexNumber). If not, simply use ulong.Parse(inputStr). Note that NumberStyles.HexNumber does not allow the 0x prefix (Convert.ToUInt64(inputStr) does however).
Then, once you have your input string parsed to a number, simply use Convert.ToString(number, 2) to convert to base2. You will notice that there is no overload which takes an ulong and an int, but you can simply cast your number to a (signed) long, since the binary representation will be identical between the two (cf. two's complement). So, in effect Convert.ToString((long)number, 2).
No need for complicated loops and conversions to byte arrays.
Bonus answer.
If you are not too concerned with performance, you can even use a LINQ one-liner:
Encoding.ASCII.GetBytes(inputStr).Aggregate(
new StringBuilder(),
(sb, ch) => sb.Append(Convert.ToString(ch, 2).PadLeft(8, '0')),
sb => sb.ToString());

C# - Input string was not in a correct format

I am working on a simple windows forms application that the user enters a string with delimiters and I parse the string and only get the variables out of the string.
So for example if the user enters:
2X + 5Y + z^3
I extract the values 2,5 and 3 from the "equation" and simply add them together.
This is how I get the integer values from a string.
int thirdValue
string temp;
temp = Regex.Match(variables[3], #"\d+").Value
thirdValue = int.Parse(temp);
variables is just an array of strings I use to store strings after parsing.
However, I get the following error when I run the application:
Input string was not in a correct format
Why i everyone moaning about this question and marking it down? it's incredibly easy to explain what is happening and the questioner was right to say it as he did. There is nothing wrong whatsoever.
Regex.Match(variables[3], #"\d+").Value
throws a Input string was not in a correct format.. FormatException if the string (here it's variables[3]) doesn't contain any numbers. It also does it if it can't access variables[3] within the memory stack of an Array when running as a service. I SUSPECT THIS IS A BUG The error is that the .Value is empty and the .Match failed.
Now quite honestly this is a feature masquerading as a bug if you ask me, but it's meant to be a design feature. The right way (IMHO) to have done this method would be to return a blank string. But they don't they throw a FormatException. Go figure. It is for this reason you were advised by astef to not even bother with Regex because it throws exceptions and is confusing. But he got marked down too!
The way round it is to use this simple additional method they also made
if (Regex.IsMatch(variables[3], #"\d+")){
temp = Regex.Match(variables[3], #"\d+").Value
}
If this still doesn't work for you you cannot use Regex for this. I have seen in a c# service that this doesn't work and throws incorrect errors. So I had to stop using Regex
I prefer simple and lightweight solutions without Regex:
static class Program
{
static void Main()
{
Console.WriteLine("2X + 65Y + z^3".GetNumbersFromString().Sum());
Console.ReadLine();
}
static IEnumerable<int> GetNumbersFromString(this string input)
{
StringBuilder number = new StringBuilder();
foreach (char ch in input)
{
if (char.IsDigit(ch))
number.Append(ch);
else if (number.Length > 0)
{
yield return int.Parse(number.ToString());
number.Clear();
}
}
yield return int.Parse(number.ToString());
}
}
you can change the string to char array and check if its a digit and count them up.
string temp = textBox1.Text;
char[] arra = temp.ToCharArray();
int total = 0;
foreach (char t in arra)
{
if (char.IsDigit(t))
{
total += int.Parse(t + "");
}
}
textBox1.Text = total.ToString();
This should solve your problem:
string temp;
temp = Regex.Matches(textBox1.Text, #"\d+", RegexOptions.IgnoreCase)[2].Value;
int thirdValue = int.Parse(temp);

hex to bin converter

I have a textbox which takes as input hex values and a messagebox which shows the output in binary. For example:
input : F710(string)
output : 1111011100010000
I will use that value in another work. How could I do this?
I am not really sure if I understand your question, but the easiest thing that comes to mind is to just calculate the values on the fly. For example:
public static string BitStringFromHexString(string hex)
{
int i;
if (!Int32.TryParse(hex, System.Globalization.NumberStyles.HexNumber, null, out i))
{
throw new ArgumentException(String.Format("Input not recognized '{0}'. ", hex), "hex");
}
return Convert.ToString(i,2);
}
string binV = "";
binV = Convert.ToString(Convert.ToInt32(textBox1.Text, 16), 2);
textBox2.Text=binV;
Should do the job for ya.

Categories