How to add numbers in a mixed string C# - c#

example = "I-000146.22.43.24"
In the example, I need to validate that the last number after the period isnt over 9. Currently is 24 and thats not valid.
01-08 is valid and anything over that isnt.
How can I add logic to check for this?

One solution would be to use Regex. The regex pattern would be something like this:
^.+\.(0?[0-8])$
Regex demo.
C# example:
string pattern = #"^.+\.(0?[0-8])$";
string[] inputs = new [] { "I-000146.22.43.24", "I-000146.22.43.09",
"I-000146.22.43.08", "xxxxxxx.07" };
foreach (string input in inputs)
{
Match match = Regex.Match(input, pattern);
if (match.Success)
Console.WriteLine($"The input is valid. Last number is '{match.Groups[1].Value}'.");
else
Console.WriteLine("The input is not valid.");
}
Output:
The input is not valid.
The input is not valid.
The input is valid. Last number is '08'.
The input is valid. Last number is '07'.
Try it online.

You could use Linq:
using System;
using System.Linq;
class MainClass {
public static void Main (string[] args) {
String[] tests = new string[3] {"I-000146.22.43.24", "I-000146.22.43.9", "I-000146.22.43.a"};
foreach (string test in tests) {
Console.WriteLine ($"{test} is a valid string: {isValidString (test)}");
}
}
private static bool isValidString (string str) {
var lastNumString = str.Split ('.').Last();
return isSingleDigit (lastNumString);
}
private static bool isSingleDigit (string numString) {
int number;
bool success = Int32.TryParse (numString, out number);
if (success) {
return number >= 0 && number <= 9;
}
return success;
}
}
Output:
I-000146.22.43.24 is a valid string: False
I-000146.22.43.9 is a valid string: True
I-000146.22.43.a is a valid string: False

Related

After instruction still can not make for loop with C# [duplicate]

This question already has answers here:
How do I create a terminable while loop in console application?
(7 answers)
Closed 3 years ago.
I started a C# course now and there is an assignment where I have to create a "palindrome detector" program. Point is that user inputs some word or sentence, then I have to remove chars like ,.;:!? and space from it. I have done that with two different methods, because char method can not remove space so I wrote another method for it.
After "cleaning" operation program reversing input what user gave, and comparing original user input and reversed user input to each other. It they are same it prints "It is palindrome", if they are different it prints "It is not palindrome". That is working fine, BUT THE PROBLEM IS I have to put them in for loop. It have to ask input again and again, until user give empty.
This would be very easy, but somehow I can not do it.
Here is my code:
using System;
namespace Palindromi
{
class Program
{
static void Main()
{
Console.WriteLine("Hei! Tervetuloa palindromin tunnistusohjelmaan. Tämä tunnistaa, onko syöttämäsi sana sama toisinpäin!");
Console.Write("Anna teksti (tyhjä lopettaa): ");
string userinput = Console.ReadLine(); //userinput is user's input, this is what you have to modify. remove some chars and reverse it.
if (userinput == "")
{
Console.ReadLine();//when i have loop this have to be "break". This meant to break for loop when i have it.
}
char[] removechars = { '.', ':', ';', ',', '!', '?' };//this is the list of "have to be removed" chars
string userinput_without_chars = userinput.Trim(removechars); //this method remove chars which are listed
string userinput_without_chars_space = userinput_without_chars.Replace( " ", ""); //replace space with empty
string reverse_string, reversed;
reverse_string = userinput_without_chars_space;
reversed = "";
int len;
len = userinput_without_chars_space.Length - 1;
while (len >= 0)
{
reversed = reversed + reverse_string[len];
len--;
}
Console.WriteLine("Sana käännettynä on {0}", reversed); //tells user input reversed
if (userinput_without_chars_space == reversed)//check is the userinput same than reversed user input
{
Console.Write("On palindromi.");//it is palindrome
}
else
{
Console.Write("Ei ole palindromi.");//it is not palindrome
}
}
}
}
You could potentially do something along these lines:
var running = true;
while(running)
{
var input = Console.ReadLine().ToLower();
var phrase = input.Sanitize(new List<string>() {".", ",", "?", "!", "'", "&", "%", "$", " "});
if(phrase.IsPalindrome())
Console.Writeline("Input was palindrome.");
}
public static string Sanitize(this string input, IList<string> punctuation) =>
String.Join(String.Empty, input.Where(character => punctuation.Contains(character) == false));
public static bool IsPalindrome(this string sentence)
{
for (int l = 0, r = sentence.Length - 1; l < r; l++, r--)
if (sentence[l] != sentence[r])
return false;
return true;
}
public static void Close(string input)
{
// Some logic to see if the application should stop.
}
You could create another method that looks for commands, or keystrokes, then sets the boolean to run as false. Which would break the infinite loop. You could also do an abrupt close with Environment.Exit.
The very simplest approach is replace your Console.ReadLine() where you want to break to return.
Alternatively, you could wrap the logic in another while loop.
while (userinput != "")
{
// Remove chars
// rest of your logic
/* IMPORTANT */
userinput = Console.Readline();
}
To remove the symbols from the input, you can use the Regex.Replace method. In this case, you can be sure, that the specified symbols will be correctly removed from the input string. Note, that you can handle the whitespaces along with other characters you mentioned, like in the code snippet below:
var CharactersToRemove { get; set; } = " ,.;:!?";
var processedInput = Regex.Replace(input.ToLower(), $"[{CharactersToRemove}]", string.Empty);
Note, that here I used input.ToLower() to convert the input to a lowercase string. This will make the palindrome tests case-insensitive. Should you need case-sensitive palindrome tests, just remove the .ToLower() part.
There is no need to reverse the input string to check if it is a palindrome. You can check this within one for loop as follows:
bool CheckForBeingaAPalindrome(string input)
{
var frontIndex = 0;
var tailIndex = input.Length - 1;
for (; frontIndex < tailIndex;)
{
if (input[frontIndex] != input[tailIndex])
return false;
++frontIndex;
--tailIndex;
}
return true;
}
Note, that in this case you only iterate over the elements of the input string once. This approach will give you al least 4 times better performance than the one you used.
Below, you can find a complete minimal working solution to your problem.
using System.Text.RegularExpressions;
using static System.Console;
namespace Assignment
{
public static class PalindromeFinder
{
public static string CharactersToRemove { get; set; } = " ,.;:!?";
public static bool IsPalindrome(string input)
{
var processedInput = RemoveUnnecessaryCharacters(input);
return CheckForBeingAPalindrome(processedInput);
}
private static string RemoveUnnecessaryCharacters(string input)
{
return Regex.Replace(input.ToLower(), $"[{CharactersToRemove}]", string.Empty);
}
private static bool CheckForBeingAPalindrome(string input)
{
var frontIndex = 0;
var tailIndex = input.Length - 1;
for (; frontIndex < tailIndex;)
{
if (input[frontIndex] != input[tailIndex])
return false;
++frontIndex;
--tailIndex;
}
return true;
}
}
public class Program
{
private static void Main(string[] args)
{
ContinuouslyCheckUserInputForBeingAPalindrome();
}
private static void ContinuouslyCheckUserInputForBeingAPalindrome()
{
while (FetchUserInputFromConsole() is string input
&& !string.IsNullOrWhiteSpace(input))
{
var isPalindrome = PalindromeFinder.IsPalindrome(input);
var modifier = isPalindrome ? "a" : "not a";
WriteLine($"It is {modifier} palindrome");
}
}
private static string FetchUserInputFromConsole()
{
Write("Enter a string: ");
return ReadLine();
}
}
}

How to correctly convert letters to numbers?

I have a string which comprise lots of letters. I have used the following code to convert it to numbers, but the new string t still gives me imperfect result.
For example:
tung2003 -> -1-1-1-12003
What I expected: 1161171101032003 (116 is the ASCII code of t, 117 is the ASCII code of u
string t=null;
foreach (char c in Properties.Settings.Default.password)
{
int ascii = (int)Char.GetNumericValue(c);
int counter=0;
counter = ascii;
t = t + Convert.ToString(counter);
}
The problem is the - character. I want my new string only comprises numbers.
It looks like you do not want the ASCII values of the numbers based on your expected output. In that case you can just do something like this:
string input = "tung2003";
string output = string.Empty;
foreach(char c in input)
{
if(char.IsNumber(c))
{
output += c;
}
else
{
output += ((byte)c).ToString();
}
}
//output is now: 1161171101032003
Fiddle here
Also added as a Linq expression for a short hand solution.
// Method 1 Linq
string output = string.Concat(("tung2003".ToCharArray()
.Select(s=> char.IsDigit(s) ? s.ToString() : ((int)s).ToString())));
// Method 2
string input = "tung2003";
string output = string.Empty;
foreach (char c in input)
{
if (Char.IsDigit(c)) output += c.ToString();
else output += ((int)c).ToString();
}
Extrapolating your output it looks like you want two different things. You want to tally each ascii character as long as it is a letter and extract the numeric values to append. The following provides three options, the first is to tally the ascii values from letters and the other two are ways to extract only digits. Because your code example uses a Password I am assuming you are trying to do some sort of custom hashing and if that is the case you should use a Hash implementation from the Cryptography namespace or some other package.
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
var combined = OnlyLettersToAscii("tung2003") + OnlyNumbers("tung2003");
Console.WriteLine($"Input: tung2003 Output: {OnlyNumbers("tung2003")}");
Console.WriteLine($"Input: tung2003 Output Regex: {OnlyNumbersWithRegex("tung2003")}");
Console.ReadKey();
}
private static string OnlyLettersToAscii(string originalString)
{
if (string.IsNullOrWhiteSpace(originalString)) return originalString;
return string.Join(string.Empty, originalString.ToArray()
.Where(w => char.IsLetter(w))
.Select(s => ((int)s).ToString()));
}
private static string OnlyNumbers(string originalString)
{
if (string.IsNullOrWhiteSpace(originalString)) return originalString;
return new string(originalString.Where(w => char.IsDigit(w)).ToArray());
}
public static string OnlyNumbersWithRegex(string originalString)
{
return Regex.Replace(originalString, #"[^\d]", string.Empty);
}
}
}
string t = "";
foreach (char c in Properties.Settings.Default.password)
{
if (IsNumber(x)) t += System.Convert.ToInt32(c).ToString();
else
{
t += c.ToString();
}
}
Moreover, if you just want to get rid off '-' the use this code: t =String.Replace(t, '-');

Checking if string contains numeric value, then display the value doubled

user input:
"I have 3 apples"
output:
"I"
"have"
"6"
"apples"
My C#:
static void Main(string[] args)
{
Console.WriteLine("Enter a string...");
string delimeter = " ";
string input = Console.ReadLine();
string[] output = input.Split(Convert.ToChar(delimeter));
foreach (var substring in output)
{
Console.WriteLine(substring);
}
Console.Read();
}
I need help getting on the right track. My code only breaks the sentence apart using space as a delimiter.
Give it a try
foreach (var substring in output)
{
int value;
if(int.TryParse(substring, out value)){
value = value * 2;
input = input.Replace(substring, value.ToString());
}
}
Console.WriteLine(input);
You first need to check if your spitted string is a number, if it is then multiple by 2 and replace it in your input variable to get the expected output.
Can you try followoing?
static void Main(string[] args)
{
Console.WriteLine("Enter a string...");
string delimeter = " ";
string input = Console.ReadLine();
var result = System.Text.RegularExpression.Regex.Replace(input,"\d+", match=>(int.Parse(match.Value)*2).ToString(CultureInfo.InvariantCul‌​ture));
Console.WriteLine(result);
Console.Read();
}
Here is an algorithm for example.
// an extension method to check if a string is all decimal digits
public static class StringHelper {
public static bool IsNumeric(this string str)
{
if (str.IsNullOrWhiteSpace()) return false;
return str.All(char.IsNumber);
}
}
...
static void Main(string[] args)
{
Console.WriteLine("Enter a string...");
string delimeter = " ";
string input = Console.ReadLine();
string[] output = input.Split(Convert.ToChar(delimeter));
foreach (var substring in output)
{
if (substring.IsNumeric())
{
substring = (int.Parse(substring) * 2).ToString();
}
Console.Write(substring);
}
Console.WriteLine();
Console.Read();
}
Please note that the code is only checking if a substring contains only decimal digits. It's not prepared to handle any number with decimal point for example, and it's also not completely safe. The code is not tested, and is ment only for example purposes.
I intentionally showed a code without using Regular Expressions, but if you're interested, check out the other answers for that alternative.

validate variable contains string value

I have one variable which contains string value like below:
var stringWithSpecialChar = "/Home%";
Sometimes this variable does not contain any value like below:
var stringWithSpecialChar = "/%";
I have to check here whether this variable contains string value or not.
Everytime string value is changing so it is not sure that i will get the same value another time.
I can't understand what is a valid value in your question, so:
Use below code if a valid value is a value of some letters or some digits:
using System.Linq;
if (str.Any(char.IsLetterOrDigit)
{
//Some codes
}
But I recommend you; for checking a valid or invalid string use Regex like this:
using System.Text.RegularExpressions;
var regex = new Regex(#"[A-Za-z]"); // You have many options here
if (regex.IsMatch(str))
{
//Some codes
}
You can do this, do a foreach loop on your variable to check if it will see a string or letter.
var stringWithSpecialChar = "/Home%";
bool blStringInput;
blStringInput = IsThisString(stringWithSpecialChar);
Method to check if it will see a string value:
public static bool IsThisString(string strInput)
{
foreach (char c in strInput)
{
if (char.IsLetter(c))
return true;
}
return false;
}
Below is a simple implementation of your problem. I have considered that anything in between / and % is a string [It might contain numbers, alphabets or special characters]. Also, I have included a check inside the function whether the string is valid or not by checking whether it starts and ends with / and % respectively.
using System;
class MainClass {
public static void Main (string[] args) {
var stringWithSpecialChar = "/Home%";
bool ans = checkIfStringIsPresent(stringWithSpecialChar);
Console.WriteLine(ans);
stringWithSpecialChar = "/%";
ans = checkIfStringIsPresent(stringWithSpecialChar);
Console.WriteLine(ans);
stringWithSpecialChar = "/hi%";
ans = checkIfStringIsPresent(stringWithSpecialChar);
Console.WriteLine(ans);
stringWithSpecialChar = "/12#%";
ans = checkIfStringIsPresent(stringWithSpecialChar);
Console.WriteLine(ans);
}
public static bool checkIfStringIsPresent(string s){
var len = s.Length;
if(s[0]!='/' || s[len-1]!='%')
return false; // if string doesn't start and and with correct symbols, then return false
var i = 0;
for(i=1;i<len-1;i++){
return true; // something is present in between / and %, so return true
}
return false; // else return false
}
}
Output:
True
False
True
True
If you know the special characters and know they are at the begining and end of the string, Trim() could be used:
var stringWithSpecialChar = "/Home%";
var value = stringWithSpecialChar.Trim('/', '%');
if(!string.IsNullOrEmpty(value))
// Use value...
One could also use string.IsNullOrWhiteSpace(value) in the condition depending on your needs.

c# contains word exception number

I need to search a string and see if it contains "<addnum(x)>"
I have used .contains on the other words that i searched for and the easiest way i could think for is you somehow could make exception for numbers or do you need to use another code for that?
My code this far.
public List<string> arguments = new List<string>();
public void Custom_naming(string name_code)
{
arguments.Add("Changing the name to " + name_code); // Sets the new name.
if( name_code.Contains("<addnum>") )
{
Add_number();
}
if (name_code.Contains("<addnum(x)>"))
{// X = any number.
}
}
private void Add_number()
{
arguments.Add("Replaces all <addnum> with a number");
}
private void Add_number(int zeros)
{
arguments.Add("Replaces all <addnumxx> with a number with lentgh of");
}
You probably need to use a regular expression:
var match = Regex.Match(name_code, #"<addnum(?:\((\d+)\))?>");
if (match.Success)
{
int zeros;
if (int.TryParse(match.Groups[1].Value, out zeros))
{
Add_number(zeros);
}
else
{
Add_number();
}
}
This will return invoke the appropriate Add_number method if name_code contains <addnum> or anything like <addnum(123)>.
If there could possibly be more than one such in name_code, e.g. <addnum(1)><addnum(2)>, you'll want to use a loop to analyze each match, like this:
var matches = Regex.Matches(name_code, #"<addnum(?:\((\d+)\))?>");
foreach(var match in matches)
{
int zeros;
if (int.TryParse(match.Groups[1].Value, out zeros))
{
Add_number(zeros);
}
else
{
Add_number();
}
}
Use regular expression:
string s = "Foo <addnum(8)> bar.";
var contains = Regex.IsMatch(s, #"<addnum\(\d+\)>");
If you want also extract number:
string s = "Foo <addnum(42)> bar.";
var match = Regex.Match(s, #"<addnum\((\d+)\)>");
if (match.Success)
{
// assume you have valid integer number
var number = Int32.Parse(match.Groups[1].Value);
}

Categories

Resources