Convert a string to an array of strings in c# - c#

Can I get an array of string with CRLF or LF or CR included, only with linq ?
I don't want to use a loop .
I have a string like this "Hello \r\n Stackverflow\n How are you doing \r", and i have to convert it to be like this
mystring[0] = "Hello \r\n"
mystring[1] = "Stackverflow\n"
mystring[2] = "How are you doing \r"
Any ideas ?

This is slightly complicated by the fact that we have to handle "\r", "\n" AND "\r\n". I'm assuming you don't need to handle "\n\r" - if you do, you'll have to add a case for it in the code below.
Obviously there are many ways to solve this; here's a low-level approach that doesn't use anything other than a basic loop:
public static IEnumerable<string> SplitByAndKeepLineSeparators(string input)
{
if (input.Length == 0)
yield break;
int i = 0, j = 0;
while (true)
{
if (i == input.Length - 1) // Last char?
{
yield return input.Substring(j, i - j + 1);
break;
}
switch (input[i])
{
case '\r' when input[i+1] == '\n':
yield return input.Substring(j, i - j + 2);
i += 2;
j = i;
break;
case '\r':
yield return input.Substring(j, i - j + 1);
j = ++i;
break;
case '\n':
yield return input.Substring(j, i - j + 1);
j = ++i;
break;
default:
++i;
break;
}
}
}
Note: If using an older version of C# you won't be able to use that kind of switch, so your code would have to be:
public static IEnumerable<string> SplitByAndKeepLineSeparators(string input)
{
if (input.Length == 0)
yield break;
int i = 0, j = 0;
while (true)
{
if (i == input.Length - 1) // Last char?
{
yield return input.Substring(j, i - j + 1);
break;
}
if (input[i] == '\r' && input[i + 1] == '\n')
{
yield return input.Substring(j, i - j + 2);
i += 2;
j = i;
}
else if (input[i] == '\r')
{
yield return input.Substring(j, i - j + 1);
j = ++i;
}
else if (input[i] == '\n')
{
yield return input.Substring(j, i - j + 1);
j = ++i;
}
else
{
++i;
}
}
}

Try the below line please:-
var arr = mystring.Split('\n');

Related

Adding exponentials

I made an expression evaluator but I only included: addition and substraction and multiply and division and a brackets resolver and I want to add exponential "^" and after that trigonometric functions: sine, cosine and tangent but I don't know where to start... this is what I did for now:
public static string RemoveBrackets(string text)
{
while (text.Contains('(') && text.Contains(')'))
{
int openIndex = 0;
int closeIndex = 0;
for(int i = 0; i < text.Length; ++i)
{
if(text[i] == '(')
{
openIndex = i;
}
if(text[i] == ')')
{
closeIndex = i;
text = text.Remove(openIndex, closeIndex - openIndex + 1).Insert(openIndex, ResolveBrackets(openIndex, closeIndex, text));
break;
}
}
}
for(int i = 1; i < text.Length; ++i)
{
if(text[i] == '-' && (text[i - 1] == '*' || text[i - 1] == '/'))
{
for(int j = i - 1; j >= 0; --j)
{
if(text[j] == '+')
{
StringBuilder text1 = new StringBuilder(text);
text1[j] = '-';
text = text1.ToString();
text = text.Remove(i, 1);
break;
}
else if(text[j] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[j] = '+';
text = text1.ToString();
text = text.Remove(i, 1);
break;
}
}
}
}
for (int i = 0; i < text.Length; ++i)
{
if (text[i] == '-' && (text[i - 1] == '-' || text[i - 1] == '+'))
{
if(text[i - 1] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '+';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
else
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '-';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
}
else if (text[i] == '+' && (text[i - 1] == '-' || text[i - 1] == '+'))
{
if (text[i - 1] == '-')
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '-';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
else
{
StringBuilder text1 = new StringBuilder(text);
text1[i] = '+';
text = text1.ToString();
text = text.Remove(i - 1, 1);
}
}
}
if (text[0] == '-')
{
text = '0' + text;
}
return Calculate(text);
}
public static string ResolveBrackets(int openindex, int closeindex, string text)
{
string BracketAnswer = evaluate(text.Substring(openindex + 1, closeindex - openindex - 1));
return BracketAnswer;
}
public static double DivideAndMultiply(string text)
{
string[] expr = text.Split('*');
List<string> textList = new List<string>();
for (int i = 0; i < expr.Length; ++i)
{
textList.Add(expr[i]);
if (i != expr.Length - 1)
{
textList.Add("*");
}
}
for (int i = 0; i < textList.Count; ++i)
{
if (textList[i].Contains('/') && textList[i].Length > 1)
{
string[] textPart = textList[i].Split('/');
textList.RemoveAt(i);
for (int j = textPart.Length - 1; j >= 0; --j)
{
textList.Insert(i, textPart[j]);
if (j != 0)
{
textList.Insert(i, "/");
}
}
}
}
double total;
if (textList[0].Contains('*') || textList[0].Contains('/'))
{
total = textList[0] == "" ? 0 : DivideAndMultiply(textList[0]);
}
else
{
total = Convert.ToDouble(textList[0]);
}
/// 7:30 min tutorial
for (int i = 2; i < textList.Count; i += 2)
{
if (textList[i - 1] == "/")
{
total /= Convert.ToDouble(textList[i]);
}
else if (textList[i - 1] == "*")
{
total *= Convert.ToDouble(textList[i]);
}
}
return total;
}
public static double AddAndSubstract(string text)
{
string[] expr = text.Split('-');
List<string> textList = new List<string>();
for(int i = 0; i < expr.Length; ++i)
{
textList.Add(expr[i]);
if(i != expr.Length - 1)
{
textList.Add("-");
}
}
for(int i = 0; i < textList.Count; ++i)
{
if (textList[i].Contains('+') && textList[i].Length > 1)
{
string[] textPart = textList[i].Split('+');
textList.RemoveAt(i);
for (int j = textPart.Length - 1; j >= 0; --j)
{
textList.Insert(i, textPart[j]);
if (j != 0)
{
textList.Insert(i, "+");
}
}
}
}
//double total = Add(expr[0]);
double total = expr[0] == "" ? 0 : DivideAndMultiply(textList[0]);
for (int i = 2; i < textList.Count; i += 2)
{
if(textList[i - 1] == "-")
{
total -= DivideAndMultiply(textList[i]);
}
else if(textList[i - 1] == "+")
{
total += DivideAndMultiply(textList[i]);
}
}
return total;
}
Any suggestions on what should I read?
Use system.math to do this, it is easier
read about programmatic part - of math class
https://msdn.microsoft.com/en-us/library/system.math(v=vs.110).aspx
And find some tuturial about scientific calculator. That should give a insights.

Cursor overwrites text in console application

I am building an ascii version of TicTacToe as a class asigment and I ran into a problem.The cursor doverwrites the board and the signs.
while (pressed == false)
{
ConsoleKeyInfo cki;
cki = Console.ReadKey();
switch (cki.Key)
{
case ConsoleKey.RightArrow:
if(sides+1>Console.WindowWidth)
break;
if(sides+1==17||sides+1==8)
sides+=2;
else
sides += 1;
Console.SetCursorPosition(sides, ver);
break;
case ConsoleKey.LeftArrow:
if (sides - 1 < 0)
break;
if (sides -1 == 17 || sides -1 == 8)
sides -= 2;
else
sides -= 1;
Console.SetCursorPosition(sides, ver);
break;
case ConsoleKey.DownArrow:
if (ver + 1 > Console.WindowHeight)
break;
if (ver+1==8||ver+1==17)
ver += 2;
else
ver += 1;
Console.SetCursorPosition(sides, ver);
break;
case ConsoleKey.UpArrow:
if (ver - 1 < 0 )
break;
if (ver - 1 == 8 || ver - 1 == 17)
ver-=2;
else
ver -= 1;
Console.SetCursorPosition(sides, ver);
break;
case ConsoleKey.X:
case ConsoleKey.O:
br.PutSign(ver,sides,ch);
pressed = true;
break;
default:
break;
}
}
}
I fixed the problme that the cursor overwrites the board But I still cant find a way to protect the sings(the X and the O)
Thats the board class for refernce:
public char[,] board = new char[27, 27];
public Board()
{
for (int i = 0; i < board.GetLength(0); i++)
{
for (int j = 0; j < board.GetLength(1); j++)
{
if (i==8||i==17)
board[i, j] = '_';
if (j==8||j==17)
board[i, j] = '|';
}
}
}
public void PrintB()
{
for (int i = 0; i < board.GetLength(0); i++)
{
for (int j = 0; j < board.GetLength(1); j++)
{
Console.Write(board[i, j]);
}
Console.WriteLine("");
}
}
public void PutSign(int row, int col, char ch)
{
board[row, col] = ch;
}

Increment character in string

I have the following code:
string str="A";
I want to get the next alphabetical character programmatically (so B, C, D, E etc.)
Can anyone suggest a way of doing this?
Instead of whole strings, use Char.
char aChar = 'A';
aChar++; // After this line executes, `aChar` is `B`
If you are looking for something like "A".. "Z"..."AA", "AB"..."ZZ"..."AAA"...
, here is the code,
public static string IncrementString(this string input)
{
string rtn = "A";
if (!string.IsNullOrWhiteSpace(input))
{
bool prependNew = false;
var sb = new StringBuilder(input.ToUpper());
for (int i = (sb.Length - 1); i >= 0; i--)
{
if (i == sb.Length - 1)
{
var nextChar = Convert.ToUInt16(sb[i]) + 1;
if (nextChar > 90)
{
sb[i] = 'A';
if ((i - 1) >= 0)
{
sb[i - 1] = (char)(Convert.ToUInt16(sb[i - 1]) + 1);
}
else
{
prependNew = true;
}
}
else
{
sb[i] = (char)(nextChar);
break;
}
}
else
{
if (Convert.ToUInt16(sb[i]) > 90)
{
sb[i] = 'A';
if ((i - 1) >= 0)
{
sb[i - 1] = (char)(Convert.ToUInt16(sb[i - 1]) + 1);
}
else
{
prependNew = true;
}
}
else
{
break;
}
}
}
rtn = sb.ToString();
if (prependNew)
{
rtn = "A" + rtn;
}
}
return rtn.ToUpper();
}
var str = "A";
char firstChar = str[0];
char nextChar = (char)((int)firstChar + 1);
var newStr = nextChar.ToString();
I am looking for the same thing, and I am using string so I need to cast it.
You can do this if your variable is string:
string foo = "b";
char result = Convert.ToChar(foo[0] + 1); //Will result to 'c'

Search longest pattern in byte array in C#

I need to write effective and quick method to search byte array for given pattern.
I write it this way, what do you think , how to improve? And it has one bug, it cannot return match with length 1.
public static bool SearchByteByByte(byte[] bytes, byte[] pattern)
{
bool found = false;
int matchedBytes = 0;
for (int i = 0; i < bytes.Length; i++)
{
if (pattern[0] == bytes[i] && bytes.Length - i >= pattern.Length)
{
for (int j = 1; j < pattern.Length; j++)
{
if (bytes[i + j] == pattern[j])
{
matchedBytes++;
if (matchedBytes == pattern.Length - 1)
{
return true;
}
continue;
}
else
{
matchedBytes = 0;
break;
}
}
}
}
return found;
}
Any suggestions ?
The Boyer-Moore algorithm that is used in grep is pretty efficient, and gets more efficient for longer pattern sizes. I'm pretty sure you could make it work for a byte array without too much difficulty, and its wikipedia page has an implementation in Java that should be fairly easy to port to C#.
UPDATE:
Here's an implementation of a simplified version of the Boyer-Moore algorithm for byte arrays in C#. It only uses the second jump table of the full algorithm. Based on the array sizes that you said (haystack: 2000000 bytes, needle: 10 bytes), it's about 5-8 times faster than a simple byte by byte algorithm.
static int SimpleBoyerMooreSearch(byte[] haystack, byte[] needle)
{
int[] lookup = new int[256];
for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Length; }
for (int i = 0; i < needle.Length; i++)
{
lookup[needle[i]] = needle.Length - i - 1;
}
int index = needle.Length - 1;
var lastByte = needle.Last();
while (index < haystack.Length)
{
var checkByte = haystack[index];
if (haystack[index] == lastByte)
{
bool found = true;
for (int j = needle.Length - 2; j >= 0; j--)
{
if (haystack[index - needle.Length + j + 1] != needle[j])
{
found = false;
break;
}
}
if (found)
return index - needle.Length + 1;
else
index++;
}
else
{
index += lookup[checkByte];
}
}
return -1;
}
And it has one bug, it cannot return match with length 1
To fix this, start inner loop from zero:
public static bool SearchByteByByte(byte[] bytes, byte[] pattern)
{
bool found = false;
int matchedBytes = 0;
for (int i = 0; i < bytes.Length; i++)
{
if (pattern[0] == bytes[i] && bytes.Length - i >= pattern.Length)
{
for (int j = 0; j < pattern.Length; j++) // start from 0
{
if (bytes[i + j] == pattern[j])
{
matchedBytes++;
if (matchedBytes == pattern.Length) // remove - 1
return true;
continue;
}
else
{
matchedBytes = 0;
break;
}
}
}
}
return found;
}
UPDATE: Here is your searching algorithm after flattering and removing local variables (they are not needed)
public static bool SearchByteByByte(byte[] bytes, byte[] pattern)
{
for (int i = 0; i < bytes.Length; i++)
{
if (bytes.Length - i < pattern.Length)
return false;
if (pattern[0] != bytes[i])
continue;
for (int j = 0; j < pattern.Length; j++)
{
if (bytes[i + j] != pattern[j])
break;
if (j == pattern.Length - 1)
return true;
}
}
return false;
}
So you're looking, effectively, for the longest common substring, so see the Wikipedia article on that: http://en.wikipedia.org/wiki/Longest_common_substring_problem
... or even a reference implementation: http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring#C.23 -- you will, of course, have to substitute byte[] for string there, etc.

How to escape JSON string?

Are there any classes/functions available to be used for easy JSON escaping? I'd rather not have to write my own.
I use System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
For those using the very popular Json.Net project from Newtonsoft the task is trivial:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(#"a\b");
Console.WriteLine(s);
....
This code prints:
"a\\b"
That is, the resulting string value contains the quotes as well as the escaped backslash.
Building on the answer by Dejan, what you can do is import System.Web.Helpers .NET Framework assembly, then use the following function:
static string EscapeForJson(string s) {
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
}
The Substring call is required, since Encode automatically surrounds strings with double quotes.
Yep, just add the following function to your Utils class or something:
public static string cleanForJSON(string s)
{
if (s == null || s.Length == 0) {
return "";
}
char c = '\0';
int i;
int len = s.Length;
StringBuilder sb = new StringBuilder(len + 4);
String t;
for (i = 0; i < len; i += 1) {
c = s[i];
switch (c) {
case '\\':
case '"':
sb.Append('\\');
sb.Append(c);
break;
case '/':
sb.Append('\\');
sb.Append(c);
break;
case '\b':
sb.Append("\\b");
break;
case '\t':
sb.Append("\\t");
break;
case '\n':
sb.Append("\\n");
break;
case '\f':
sb.Append("\\f");
break;
case '\r':
sb.Append("\\r");
break;
default:
if (c < ' ') {
t = "000" + String.Format("X", c);
sb.Append("\\u" + t.Substring(t.Length - 4));
} else {
sb.Append(c);
}
break;
}
}
return sb.ToString();
}
I have used following code to escape the string value for json.
You need to add your '"' to the output of the following code:
public static string EscapeStringValue(string value)
{
const char BACK_SLASH = '\\';
const char SLASH = '/';
const char DBL_QUOTE = '"';
var output = new StringBuilder(value.Length);
foreach (char c in value)
{
switch (c)
{
case SLASH:
output.AppendFormat("{0}{1}", BACK_SLASH, SLASH);
break;
case BACK_SLASH:
output.AppendFormat("{0}{0}", BACK_SLASH);
break;
case DBL_QUOTE:
output.AppendFormat("{0}{1}",BACK_SLASH,DBL_QUOTE);
break;
default:
output.Append(c);
break;
}
}
return output.ToString();
}
In .Net Core 3+ and .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
The methods offered here are faulty.
Why venture that far when you could just use System.Web.HttpUtility.JavaScriptEncode ?
If you're on a lower framework, you can just copy paste it from mono
Courtesy of the mono-project #
https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, bool addDoubleQuotes)
{
if (string.IsNullOrEmpty(value))
return addDoubleQuotes ? "\"\"" : string.Empty;
int len = value.Length;
bool needEncode = false;
char c;
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
{
needEncode = true;
break;
}
}
if (!needEncode)
return addDoubleQuotes ? "\"" + value + "\"" : value;
var sb = new System.Text.StringBuilder();
if (addDoubleQuotes)
sb.Append('"');
for (int i = 0; i < len; i++)
{
c = value[i];
if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
sb.AppendFormat("\\u{0:x4}", (int)c);
else switch ((int)c)
{
case 8:
sb.Append("\\b");
break;
case 9:
sb.Append("\\t");
break;
case 10:
sb.Append("\\n");
break;
case 12:
sb.Append("\\f");
break;
case 13:
sb.Append("\\r");
break;
case 34:
sb.Append("\\\"");
break;
case 92:
sb.Append("\\\\");
break;
default:
sb.Append(c);
break;
}
}
if (addDoubleQuotes)
sb.Append('"');
return sb.ToString();
}
This can be compacted into
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
public class SimpleJSON
{
private static bool NeedEscape(string src, int i)
{
char c = src[i];
return c < 32 || c == '"' || c == '\\'
// Broken lead surrogate
|| (c >= '\uD800' && c <= '\uDBFF' &&
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF'))
// Broken tail surrogate
|| (c >= '\uDC00' && c <= '\uDFFF' &&
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF'))
// To produce valid JavaScript
|| c == '\u2028' || c == '\u2029'
// Escape "</" for <script> tags
|| (c == '/' && i > 0 && src[i - 1] == '<');
}
public static string EscapeString(string src)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int start = 0;
for (int i = 0; i < src.Length; i++)
if (NeedEscape(src, i))
{
sb.Append(src, start, i - start);
switch (src[i])
{
case '\b': sb.Append("\\b"); break;
case '\f': sb.Append("\\f"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case '\t': sb.Append("\\t"); break;
case '\"': sb.Append("\\\""); break;
case '\\': sb.Append("\\\\"); break;
case '/': sb.Append("\\/"); break;
default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));
break;
}
start = i + 1;
}
sb.Append(src, start, src.Length - start);
return sb.ToString();
}
}
I ran speed tests on some of these answers for a long string and a short string. Clive Paterson's code won by a good bit, presumably because the others are taking into account serialization options. Here are my results:
Apple Banana
System.Web.HttpUtility.JavaScriptStringEncode: 140ms
System.Web.Helpers.Json.Encode: 326ms
Newtonsoft.Json.JsonConvert.ToString: 230ms
Clive Paterson: 108ms
\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\"things\to\escape\some\long\path\with\lots"\of\things\to\escape
System.Web.HttpUtility.JavaScriptStringEncode: 2849ms
System.Web.Helpers.Json.Encode: 3300ms
Newtonsoft.Json.JsonConvert.ToString: 2827ms
Clive Paterson: 1173ms
And here is the test code:
public static void Main(string[] args)
{
var testStr1 = "Apple Banana";
var testStr2 = #"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";
foreach (var testStr in new[] { testStr1, testStr2 })
{
var results = new Dictionary<string,List<long>>();
for (var n = 0; n < 10; n++)
{
var count = 1000 * 1000;
var sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.HttpUtility.JavaScriptStringEncode(testStr);
}
var t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = System.Web.Helpers.Json.Encode(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = Newtonsoft.Json.JsonConvert.ToString(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);
sw = Stopwatch.StartNew();
for (var i = 0; i < count; i++)
{
var s = cleanForJSON(testStr);
}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Clive Paterson").Add(t);
}
Console.WriteLine(testStr);
foreach (var result in results)
{
Console.WriteLine(result.Key + ": " + Math.Round(result.Value.Skip(1).Average()) + "ms");
}
Console.WriteLine();
}
Console.ReadLine();
}
I would also recommend using the JSON.NET library mentioned, but if you have to escape unicode characters (e.g. \uXXXX format) in the resulting JSON string, you may have to do it yourself. Take a look at Converting Unicode strings to escaped ascii string for an example.
I nice one-liner, used JsonConvert as others have but added substring to remove the added quotes and backslash.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
What about System.Web.Helpers.Json.Encode(...) (see http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111).aspx)?
String.Format("X", c);
That just outputs: X
Try this instead:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
There's a Json library at Codeplex
I chose to use System.Web.Script.Serialization.JavaScriptSerializer.
I have a small static helper class defined as follows:
internal static partial class Serialization
{
static JavaScriptSerializer serializer;
static Serialization()
{
serializer = new JavaScriptSerializer();
serializer.MaxJsonLength = Int32.MaxValue;
}
public static string ToJSON<T>(T obj)
{
return serializer.Serialize(obj);
}
public static T FromJSON<T>(string data)
{
if (Common.IsEmpty(data))
return default(T);
else
return serializer.Deserialize<T>(data);
}
}
To serialize anything I just call Serialization.ToJSON(itemToSerialize)
To deserialize I just call Serialization.FromJSON<T>(jsonValueOfTypeT)

Categories