static string RemoveDuplicateChars(string key)
{
// --- Removes duplicate chars using string concats. ---
// Store encountered letters in this string.
string table = "";
// Store the result in this string.
string result = "";
// Loop over each character.
foreach (char value in key)
{
// See if character is in the table.
if (table.IndexOf(value) == -1)
{
// Append to the table and the result.
table += value;
result += value;
}
}
return result;
}
The above code-snippet is from http://www.dotnetperls.com/duplicate-chars. The question I have is why do you need the extra result variable when you can just use table? Is there a reason for both variables? Below is code I wrote that accomplishes the same purpose, I believe. Am I missing anything? Thanks again and look forward to contributing here!
Code re-written:
static string RemoveDuplicateChars(string key)
{
// --- Removes duplicate chars using string concats. ---
// Store encountered letters in this string.
string table = "";
// Loop over each character.
foreach (char value in key)
{
// See if character is in the table.
if (table.IndexOf(value) == -1)
{
// Append to the table and the result.
table += value;
}
}
return table;
}
There is nothing wrong with what you did. That should work just fine. That being said, in C# we also have linq. You could just take a char[] and do:
char[] result = inputCharArray.Distinct().ToArray();
Your code is correct and functions perfectly, you could also use LINQ in C# using
stringName.Distinct()
The reason that dotnetperls uses two variables is because it is an introduction, and tries to the logic as straightforward as possible to follow to facilitate learning. Good catch!
It is not really necessary as both ways work fine. The choice is purely up to the developer.
Related
I have an application which generates CSV data. This application "helpfully" includes the Excel fix of using = as a preamble to quoted 0-filled numeric data, to prevent the Excel interpreter from eating the leading 0.
I want to use CSVHelper to read these records. However, when mapping to a number, CSVhelper reports an error for these values with the = prefix.
Other than search/replace to pull the "=" out, is there a way to tell CSVhelper to ignore the leading equals and process successfully? I see options for including = in the written output but not to allow them in the parse.
Here is an example record:
"XYZ INC","R1G202113","R2G",="202113","D-SRS PRO FLD SM/2",157.49,122.53,True,50,50,0.00,1,False,"N",4.00,6.00,8.00,6.00,""
Any hep with this is appreciated.
This is a guess, and there may be a much better way, but perhaps you could do something like this with your mapping:
public class MyData
{
//map the raw input to this field as a string
public string MappedIntField {get;set;}=null;
// use an integer property not mapped to any column to shadow the string, and lazy-convert to an integer the first time you read it.
public int ActualIntField
{
get {
if (MappingReady || string.IsNullOrEmpty(MappedIntField)) return _ActualIntField;
//clean up the extra = character.
if (MappedIntField[0] == '=') MappedIntField = MappedIntField.Substring(1);
int result;
if (int.TryParse(MappedIntField, out result))
{
_ActualIntField = result;
MappingReady = true;
return result;
}
return _ActualIntField;
}
set {
_ActualIntField = value;
MappingReady = true;
}
}
private int _AcutalIntField;
// We don't want to re-parse the string on every read, so also flag when this work is done. You could also use a nullable int? to do this.
private bool MappingReady = false;
}
How do I check a string to make sure it contains numbers, letters, or space only?
In C# this is simple:
private bool HasSpecialChars(string yourString)
{
return yourString.Any(ch => ! char.IsLetterOrDigit(ch));
}
The easiest way it to use a regular expression:
Regular Expression for alphanumeric and underscores
Using regular expressions in .net:
http://www.regular-expressions.info/dotnet.html
MSDN Regular Expression
Regex.IsMatch
var regexItem = new Regex("^[a-zA-Z0-9 ]*$");
if(regexItem.IsMatch(YOUR_STRING)){..}
string s = #"$KUH% I*$)OFNlkfn$";
var withoutSpecial = new string(s.Where(c => Char.IsLetterOrDigit(c)
|| Char.IsWhiteSpace(c)).ToArray());
if (s != withoutSpecial)
{
Console.WriteLine("String contains special chars");
}
Try this way.
public static bool hasSpecialChar(string input)
{
string specialChar = #"\|!#$%&/()=?»«#£§€{}.-;'<>_,";
foreach (var item in specialChar)
{
if (input.Contains(item)) return true;
}
return false;
}
String test_string = "tesintg#$234524##";
if (System.Text.RegularExpressions.Regex.IsMatch(test_string, "^[a-zA-Z0-9\x20]+$"))
{
// Good-to-go
}
An example can be found here: http://ideone.com/B1HxA
If the list of acceptable characters is pretty small, you can use a regular expression like this:
Regex.IsMatch(items, "[a-z0-9 ]+", RegexOptions.IgnoreCase);
The regular expression used here looks for any character from a-z and 0-9 including a space (what's inside the square brackets []), that there is one or more of these characters (the + sign--you can use a * for 0 or more). The final option tells the regex parser to ignore case.
This will fail on anything that is not a letter, number, or space. To add more characters to the blessed list, add it inside the square brackets.
Use the regular Expression below in to validate a string to make sure it contains numbers, letters, or space only:
[a-zA-Z0-9 ]
You could do it with a bool. I've been learning recently and found I could do it this way. In this example, I'm checking a user's input to the console:
using System;
using System.Linq;
namespace CheckStringContent
{
class Program
{
static void Main(string[] args)
{
//Get a password to check
Console.WriteLine("Please input a Password: ");
string userPassword = Console.ReadLine();
//Check the string
bool symbolCheck = userPassword.Any(p => !char.IsLetterOrDigit(p));
//Write results to console
Console.WriteLine($"Symbols are present: {symbolCheck}");
}
}
}
This returns 'True' if special chars (symbolCheck) are present in the string, and 'False' if not present.
A great way using C# and Linq here:
public static bool HasSpecialCharacter(this string s)
{
foreach (var c in s)
{
if(!char.IsLetterOrDigit(c))
{
return true;
}
}
return false;
}
And access it like this:
myString.HasSpecialCharacter();
private bool isMatch(string strValue,string specialChars)
{
return specialChars.Where(x => strValue.Contains(x)).Any();
}
Create a method and call it hasSpecialChar with one parameter
and use foreach to check every single character in the textbox, add as many characters as you want in the array, in my case i just used ) and ( to prevent sql injection .
public void hasSpecialChar(string input)
{
char[] specialChar = {'(',')'};
foreach (char item in specialChar)
{
if (input.Contains(item)) MessageBox.Show("it contains");
}
}
in your button click evenement or you click btn double time like that :
private void button1_Click(object sender, EventArgs e)
{
hasSpecialChar(textbox1.Text);
}
While there are many ways to skin this cat, I prefer to wrap such code into reusable extension methods that make it trivial to do going forward. When using extension methods, you can also avoid RegEx as it is slower than a direct character check. I like using the extensions in the Extensions.cs NuGet package. It makes this check as simple as:
Add the [https://www.nuget.org/packages/Extensions.cs][1] package to your project.
Add "using Extensions;" to the top of your code.
"smith23#".IsAlphaNumeric() will return False whereas "smith23".IsAlphaNumeric() will return True. By default the .IsAlphaNumeric() method ignores spaces, but it can also be overridden such that "smith 23".IsAlphaNumeric(false) will return False since the space is not considered part of the alphabet.
Every other check in the rest of the code is simply MyString.IsAlphaNumeric().
Based on #prmph's answer, it can be even more simplified (omitting the variable, using overload resolution):
yourString.Any(char.IsLetterOrDigit);
No special characters or empty string except hyphen
^[a-zA-Z0-9-]+$
Why doesn't my code work?? I am writing a cypher program in C# and would like to know why this isn't working. The error that I keep on getting is 'not all code paths return a value'
this is my code:
If passed string will be empty then the return will never be hit, so the method will not return anything.
public static string cypher(string word)
{
// If word is null, we just return null.
if(string.IsNullOrEmpty(word))
return null;
// Process string. This will return after first char...
foreach (char d in word)
{
char charCypher = System.Convert.ToChar((int)d+2);
return Convert.ToString(charCypher);
}
}
Not exactly what the question is about, but you iterate through each char of a word, but you return after first char. You probably want to cypher every char and return cyphered word. In this case you need to modify your code:
public static string cypher(string word)
{
// If word is null, we just return null.
if(string.IsNullOrEmpty(word))
return null;
StringBuilder builder = new StringBuilder();
foreach (char d in word)
{
char charCypher = System.Convert.ToChar((int)d+2);
builder.Append(Convert.ToString(charCypher));
}
return builder.ToString();
}
The foreach loop in cypher can contain an empty string, so the loop won't be executed if that's the case. Therefore it won't hit your return statement.
A workaround for this problem could be adding return String.Empty before the last closing brace or your method.
It seems, that you want to implement Caesar cipher:
using System.Linq;
...
public static string cypher(string word) {
//DONE: do not forget to validate public method's arguments
if (string.IsNullOrEmpty(word))
return word;
//TODO: you may want to make some amendments
// 1. Filter out which characters to encode (e.g. skip new lines)
// 2. Add modulo operator (e.g. to encode letters as letters)
return string.Concat(word.Select(d => (char)(d + 2)));
}
Please, do not forget to cast integer back to char when concatenating the string
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);
I connect to a webservice that gives me a response something like this(This is not the whole string, but you get the idea):
sResponse = "{\"Name\":\" Bod\u00f8\",\"homePage\":\"http:\/\/www.example.com\"}";
As you can see, the "Bod\u00f8" is not as it should be.
Therefor i tried to convert the unicode (\u00f8) to char by doing this with the string:
public string unicodeToChar(string sString)
{
StringBuilder sb = new StringBuilder();
foreach (char chars in sString)
{
if (chars >= 32 && chars <= 255)
{
sb.Append(chars);
}
else
{
// Replacement character
sb.Append((char)chars);
}
}
sString = sb.ToString();
return sString;
}
But it won't work, probably because the string is shown as \u00f8, and not \u00f8.
Now it would not be a problem if \u00f8 was the only unicode i had to convert, but i got many more of the unicodes.
That means that i can't just use the replace function :(
Hope someone can help.
You're basically talking about converting from JSON (JavaScript Object Notation). Try this link--near the bottom you'll see a list of publicly available libraries, including some in C#, that might do what you need.
The excellent Json.NET library has no problems decoding unicode escape sequences:
var sResponse = "{\"Name\":\"Bod\u00f8\",\"homePage\":\"http://www.ex.com\"}";
var obj = (JObject)JsonConvert.DeserializeObject(sResponse);
var name = ((JValue)obj["Name"]).Value;
var homePage = ((JValue)obj["homePage"]).Value;
Debug.Assert(Equals(name, "Bodø"));
Debug.Assert(Equals(homePage, "http://www.ex.com"));
This also allows you to deserialize to real POCO objects, making the code even cleaner (although less dynamic).
var obj = JsonConvert.DeserializeObject<Response>(sResponse);
Debug.Assert(obj2.Name == "Bodø");
Debug.Assert(obj2.HomePage == "http://www.ex.com");
public class Response
{
public string Name { get; set; }
public string HomePage { get; set; }
}
Perhaps you want to try:
string character = Encoding.UTF8.GetString(chars);
sb.Append(character);
I know this question is getting quite old, but I crashed into this problem as of today, while trying to access the Facebook Graph API. I was getting these strange \u00f8 and other variations back.
First I tried a simple replace as the OP also said (with the help from an online table). But I thought "no way!" after adding 2 replaces.
So after looking a little more at the "codes" it suddenly hit me...
The "\u" is a prefix, and the 4 characters after that is a hexadecimal encoded char code! So writing a simple regex to find all \u with 4 alphanumerical characters after, and afterwards converting the last 4 characters to integer and then to a character made the deal.
My source is in VB.NET
Private Function DecodeJsonString(ByVal Input As String) As String
For Each m As System.Text.RegularExpressions.Match In New System.Text.RegularExpressions.Regex("\\u(\w{4})").Matches(Input)
Input = Input.Replace(m.Value, Chr(CInt("&H" & m.Value.Substring(2))))
Next
Return Input
End Function
I also have a C# version here
private string DecodeJsonString(string Input)
{
foreach (System.Text.RegularExpressions.Match m in new System.Text.RegularExpressions.Regex(#"\\u(\w{4})").Matches(Input))
{
Input = Input.Replace(m.Value, ((char)(System.Int32.Parse(m.Value.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier))).ToString());
}
return Input;
}
I hope it can help someone out... I hate to add libraries when I really only need a few functions from them!