C# for case in string(easy) - c#

so I have this code. I need to generate a for loop that checks all the characters in the string and checks if they are all valid(So numbers from 0->7). But I don't know how to write it, I tried something but it didn't work. Here are the examples:user enters: 77, code works, user enters 99, code doesn't work, user enters 5., code doesn't work, etc..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NALOGA1
{
class Program
{
static string decToOct(int stevilo)//v mojon primere 7
{
string izhod = "";
//7>0 DRŽI
while (stevilo > 0)
{
//izhodi se dodeli ostanek deljenja z 8 keri se spremeni v string
izhod = (stevilo % 8) + izhod;
//7/8;
stevilo /= 8;
}
return izhod;
}
static int Octtodesetisko(string stevilo)
{
double vsota = 0;
for (int i = stevilo.Length - 1; i >= 0; i--)
{
int stevka = stevilo[i] - '0';
vsota += (stevka * Math.Pow(8, i));
}
return (int)vsota;
}
static void Main(string[] args)
{
//3 podprogram-in progress
string prvastevilka = Console.ReadLine();
int prvasprememba = Int32.Parse(prvastevilka);
if (prvasprememba > 0)
{
Console.WriteLine(decToOct(prvasprememba));
}
else
{
Console.WriteLine("Napaka");
}
string drugastevilka = Console.ReadLine();
int drugasprememba = Octtodesetisko(drugastevilka);
foreach (char znak in drugastevilka)
{
if(znak!=1 || znak!=2 || znak!=3 || znak!=4 || znak!=5 || znak!=6 || znak!=7)
{
Console.WriteLine("Napaka");
}
else
{
Console.WriteLine("dela :D");
}
}
Console.ReadKey();
}
}
}

Personally, I would take advantage of the LINQ Enumerable.All method to express this in a very concise and readable way:
if (str.Any() && str.All(c => c >= '0' && c <= '7'))
{
Console.WriteLine("good");
}
else
{
Console.WriteLine("bad");
}
EDIT: No LINQ
It's not hard to translate what the LINQ Enumerable.All method does to a normal loop. It's just more verbose:
bool isValid = true;
foreach (char c in str)
{
if (c < '0' || c > '7')
{
isValid = false;
break;
}
}
if (str.Length != 0 && isValid)
{
Console.WriteLine("good");
}
else
{
Console.WriteLine("bad");
}

Firstly, there seems to be a mistake in the line
if(znak!=1 || znak!=2 || znak!=3 || znak!=4 || znak!=5 || znak!=6 || znak!=7)
I guess it should read
if(znak!='1' || znak!='2' || znak!='3' || znak!='4' || znak!='5' || znak!='6' || znak!='7')
which should be compressed to
if (znak >= '0' && znak <= '7')
You can use linq instead of the for loop here like this:
if (drugastevilka.All(c => c >= '0' && c <= '7')
Console.WriteLine("dela :D");
else
Console.WriteLine("Napaka");
But the best solution is probably to use a regular expression:
Regex regex = new Regex("^[0-7]+$");
if (regex.IsMatch(drugastevilka))
Console.WriteLine("dela :D");
else
Console.WriteLine("Napaka");
Edit: the linq solution shown accepts empty strings, the regex (as shown) needs at least 1 character. Exchange the + with a * and it will accept empty strings, too. But I don't think you want to accept empty strings.

You are messing up with the datatype
Can you try with below code
static string decToOct(int stevilo)//v mojon primere 7
{
int izhod = 0;
//7>0 DRŽI
while (stevilo > 0)
{
//izhodi se dodeli ostanek deljenja z 8 keri se spremeni v string
izhod = (stevilo % 8) + izhod;
//7/8;
stevilo /= 8;
}
return (izhod.ToString());
}

What about something like this?
class Program
{
static void Main(string[] args)
{
string someString = "1234567";
string someOtherString = "1287631";
string anotherString = "123A6F2";
Console.WriteLine(IsValidString(someString));
Console.WriteLine(IsValidString(someOtherString));
Console.WriteLine(IsValidString(anotherString));
Console.ReadLine();
}
public static bool IsValidString(string str)
{
bool isValid = true;
char[] splitString = str.ToCharArray(); //get an array of each character
for (int i = 0; i < splitString.Length; i++)
{
try
{
double number = Char.GetNumericValue(splitString[i]); //try to convert the character to a double (GetNumericValue returns a double)
if (number < 0 || number > 7) //we get here if the character is an int, then we check for 0-7
{
isValid = false; //if the character is invalid, we're done.
break;
}
}
catch (Exception) //this will hit if we try to convert a non-integer character.
{
isValid = false;
break;
}
}
return isValid;
}
}
IsValidString() takes a string, converts it to a Char array, then checks each value as such:
Get the numeric value
Check if the value is between 0-7
GetNumericValue will fail on a non-integer character, so we wrap it in a try/catch - if we hit an exception we know that isValid = false, so we break.
If we get a valid number, and it's not between 0-7 we also know that isValid = false, so we break.
If we make it all the way through the list, the string is valid.
The sample given above returns:
IsValidString(someString) == true
IsValidString(someOtherString) == false
IsValidString(anotherString) == false

Related

Can I compare a value from a method and another from a variable?

I need to identify if password is equal to Pin(), I don't know if the problem is comparing a method inside a method
public static string Pin(int size = 4) {
StringBuilder sb = new StringBuilder(size);
while (sb.Length < size) {
var key = Console.ReadKey(true);
if (key.KeyChar >= '0' && key.KeyChar <= '9') {
sb.Append(key.KeyChar);
Console.WriteLine('*');
}
}
return sb.ToString();
}
static void Card() {
Console.WriteLine("Enter the 4 Digits Password");
int password = int.Parse(Console.ReadLine());
if (password == Pin()) {
// Is going to do something
}
}
You cannot compare string (Pin() result) and int (password) directly. Either convert password to string string password = Console.ReadLine();, either add int.Parse to the Pin() function result.
if (password == int.Parse(Pin()))
{
// Is going to do something
}
I suggest implementation like this. For reading Pin we can put
// Since Pin is integer, let's return int, not string
public static int Pin(int size = 4) {
if (size <= 0 || size >= 9)
throw new ArgumentOutOfRangeException(nameof(size));
StringBuilder sb = new StringBuilder(size);
while (sb.Length != size) {
var position = Console.GetCursorPosition();
char letter = Console.ReadKey().KeyChar;
Console.SetCursorPosition(position.Left, position.Top);
if (letter >= '0' && letter <= '9') {
Console.Write('*');
sb.Append(letter);
}
else {
Console.Write(' ');
Console.SetCursorPosition(position.Left, position.Top);
}
}
return int.Parse(sb.ToString());
}
Let's extract ReadInteger as well:
public static int ReadInteger(string title) {
while (true) {
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
if (int.TryParse(Console.ReadLine(), out int result))
return result;
Console.WriteLine("Syntax error, incorrect integer value. Please, try again.");
}
}
Then you can use the routine as simple as
static void Card() {
int password = ReadInteger("Enter the 4 Digits Password");
if (password == Pin()){
// Is going to do something
}
}

Logic to determine a postal carrier based on the tracking number C#

working on some simple logic to determine a postal carrier based on the tracking number. I am trying to put the tracking number into an array called "trackingNumberArray" then have a few if statements that compare various items of that array to determine the carrier. This is the code I have but still cannot seem to make it work. Any tips/guideance would be greatly appreciated!
static void Main(string[] args)
{
string trackingNumber = "1Z204E380338943508";
string[] trackingNumberArray = new string[] {trackingNumber};
if (trackingNumberArray.Contains("1Z"))
{
string carrierName = "UPS";
Console.WriteLine($"Carrier Name" + carrierName);
}
else if (trackingNumberArray.Length >= 12 && trackingNumberArray.Length < 14 && !!trackingNumberArray.Contains("1Z"))
{
string carrierName = "Fedex";
Console.WriteLine($"Carrier Name" + carrierName);
}
else if (trackingNumberArray.Length >= 20 && trackingNumberArray.Length < 22 && !trackingNumberArray.Contains("1Z"))
{
string carrierName = "USPS";
Console.WriteLine($"Carrier Name" + carrierName);
}
else
{
string carrierName = null;
Console.WriteLine($"did not work" + carrierName);
}
}
Instead of putting the tracking number into an array, you can just leave it as a string. The rest of your code should then work with that string. You also don't need the redundant checks for "1Z", since that was in the first conditon:
static void Main()
{
string trackingNumber = "1Z204E380338943508";
string carrierName = null;
if (trackingNumber.Contains("1Z"))
{
carrierName = "UPS";
}
else if (trackingNumber.Length >= 12 && trackingNumber.Length < 14)
{
carrierName = "FedEx";
}
else if (trackingNumber.Length >= 20 && trackingNumber.Length < 22)
{
carrierName = "USPS";
}
if (carrierName == null)
{
Console.WriteLine("Did not work.");
}
else
{
Console.WriteLine($"Carrier name: {carrierName}");
}
GetKeyFromUser("\nPress any key to exit...");
}
You could then create a static method out of the code:
public static string GetCarrierName(string trackingNumber)
{
if (trackingNumber == null) return null;
if (trackingNumber.Contains("1Z")) return "UPS";
if (trackingNumber.Length >= 12 && trackingNumber.Length < 14) return "FedEx";
if (trackingNumber.Length >= 20 && trackingNumber.Length < 22) return "USPS";
return null;
}
And use it like:
static void Main()
{
string carrierName = GetCarrierName("1Z204E380338943508");
if (carrierName == null)
{
Console.WriteLine("Unknown tracking id format.");
}
else
{
Console.WriteLine($"Carrier name: {carrierName}");
}
GetKeyFromUser("\nPress any key to exit...");
}
trackingNumberArray.Contains("1Z")
This won't work because your array is made up of individual letters. If you want to look for a string, use the original string.
trackingNumber.Contains("1Z")
Also, there's no need for this bit, because it's in an 'else' that can only be reached when it's true.
&& !trackingNumberArray.Contains("1Z")

C# - Check if entered string is a Integer or not

i want to check if entered string is a Integer or not for example
12 = True
+12 = True
-5 = True
4.4 = False
4as = False
I make it using int.TryParse but what I want is to using ASCII without using int.TryParse
string str;
int strint;
int strintoA;
bool flag = false;
while (flag == false)
{
Console.Write("Enter a Number : ");
str = Console.ReadLine();
flag = int.TryParse(str, out strint);
if (flag == false)
{
Console.WriteLine("Please Enter Numbers Only.");
}
else
{
strintoA = strint;
Console.WriteLine("Entered String: " + str + " is a Number!" );
break;
}
}
Console.ReadKey();
You could also use regular expressions:
var regex = new Regex(#"^[-+]?\d+$");
var str = Console.ReadLine();
if (regex.IsMatch(str))
{
Console.WriteLine($"{str} is a number!");
}
check the first char for -|+|digit, check rest isDigit
for (int i = 0; i < str.Length; i++)
{
var c = str[i];
if (i == 0)
{
if (!(c == '+' || c == '-' || char.IsDigit(c)) {
return false;
}
}
if (!char.IsDigit(c)) return false;
}
return true;
why dont use:
if(intString[0] == '+' || intString[0] == '-') intString = intString.Substring(1, intString.Length - 1);
bool isNumber = intString.All(char.IsDigit);
Not sure why you don't want to use int.TryParse but the following code should do:
static bool IsValidInteger(string s)
{
var leadingSignSeen = false;
var digitSeen = false;
var toParse = s.Trim();
foreach (var c in toParse)
{
if (c == ' ')
{
if (digitSeen)
return false;
}
else if (c == '+' || c == '-')
{
if (leadingSignSeen || digitSeen)
return false;
leadingSignSeen = true;
}
else if (!char.IsDigit(c))
return false;
else
{
digitSeen = true;
}
}
return true;
}
This will accept any integer with leading sign and leading and trailing spaces. Whitespaces between leading sign and digits are also accepted.
FYI: You can refactor your code to simplify it for exactly the same functional output:
void Main()
{
int result;
Console.Write("Enter a Number : ");
while (!int.TryParse(Console.ReadLine(), out result))
{
Console.WriteLine("Please Enter Numbers Only.");
Console.Write("Enter a Number : ");
}
Console.WriteLine($"Entered String: {result} is a Number!");
Console.ReadKey();
}
If you have a good reason to not use int.TryParse (e.g. it's lacking some functionality, or this is an exercise where you've been asked to write your own) you could use the above replacing int.TryParse with a call to IsNumericCustom, assuming the below signature (or change type int to whatever data type you need to handle).
public bool IsNumericCustom(string input, out int output)
{
//...
}
Or if you only care about whether the value's numeric and not the parsed value:
void Main()
{
string result;
Console.Write("Enter a Number : ");
//while (!int.TryParse((result = Console.ReadLine()), out _))
while (!IsNumericCustom((result = Console.ReadLine()))
{
Console.WriteLine("Please Enter Numbers Only.");
Console.Write("Enter a Number : ");
}
Console.WriteLine($"Entered String: {result} is a Number!");
Console.ReadKey();
}
public bool IsNumericCustom(string input)
{
//...
}
As for the logic in the IsNumericCustom, it really depends on what you're hoping to achieve / why int.TryParse / decimal.TryParse etc aren't appropriate. Here's a couple of implementations (using different function names).
using System.Text.RegularExpressions; //https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex?view=netframework-4.7.2
//...
readonly Regex isNumeric = new Regex("^[+-]?\d*\.?\d*$", RegexOptions.Compiled); //treat "." as "0.0", ".9" as "0.9", etc
readonly Regex isInteger = new Regex("^[+-]?\d+$", RegexOptions.Compiled); //requires at least 1 digit; i.e. "" is not "0"
readonly Regex isIntegerLike = new Regex("^[+-]?\d*\.?\0*$", RegexOptions.Compiled); //same as integer, only 12.0 is treated as 12, whilst 12.1 is invalid; i.e. only an integer if we can remove digits after the decimal point without truncating the value.
//...
public bool IsNumeric(string input)
{
return isNumeric.IsMatch(input); //if you'd wanted 4.4 to be true, use this
}
public bool IsInteger(string input)
{
return isInteger.IsMatch(input); //as you want 4.4 to be false, use this
}
public bool IsIntegerLike(string input)
{
return isIntegerLike.IsMatch(input); //4.4 is false, but both 4 and 4.0 are true
}
From your requirements it appears that you want to use ASCII code in order to assert whether the string entered is numeric or not.
This is the code I have come up with:
string str;
var index = 1;
int strintoA = 0;
bool isNegative = false;
//ASCII list of numbers and signs
List<int> allowedValues = new List<int> { 43, 45, 48, 49, 50, 51, 52, 53, 54, 55, 56,
57 };
bool flag = false;
while (!flag)
{
Console.WriteLine("Enter a Number : ");
str = Console.ReadLine();
if (str.Count(item => allowedValues.Contains((int)item)) == str.Count())
{
foreach (var item in str.Reverse())
{
if (item != 43 && item != 45)
{
strintoA += index * (item - 48);
index = index * 10;
}
else if(item == 45)
{
isNegative = true;
}
}
if(isNegative)
{
strintoA *= -1;
}
Console.WriteLine("Entered String: " + str + " is a Number!");
flag = true;
}
else
{
Console.WriteLine("Please Enter Numbers Only.");
}
}
Console.ReadKey();
}
The allowedValues list contains the ASCII representation of numeric values and allowed signs(+ and -). The foreach loop will regenerates the int value inserted.
Hope it helps.

If statement not working C#

I'm not sure if I'm just really tired and missing something obvious or there is something wrong with my program. Basically my if statement condition is not working.
public bool check(string nextvaluebinary)
{
bool test = true;
for (int i = -1; i < 8; ++i)
{
i++;
System.Console.WriteLine(nextvaluebinary[i] + " " + nextvaluebinary[i + 1]);
if (nextvaluebinary[i] == 1)
{
System.Console.WriteLine("Activated");
if (nextvaluebinary[i + 1] == 0)
{
test = false;
System.Console.WriteLine("false");
}
}
else
{
test = true;
}
if (test == false)
{
break;
}
}
return test;
}
I'm passing in the string 0001010110 and im getting an output of:
0 0
0 1
0 1
0 1
1 0
but no "activated" or "false" even though the last one is "1 0". Again sorry if this is a dumb question and any insight or help would be greatly appreciated.
You're comparing a char against an int. The check you're attempting carries a completely different meaning than what you're trying to accomplish. You need to either check if its equal to '1' or cast the char to an int first so you can do a numeric comparison.
if (nextvaluebinary[i] == '1')
Since nextvaluebinary is a String, this comparison will succeed only if that string has a null character, i.e. '\0':
if (nextvaluebinary[i + 1] == 0)
It looks like you are looking for a zero digit character, instead, so you should write
if (nextvaluebinary[i + 1] == '0')
Equals is used with char to int. So that will use char code.
Use this
public static bool check(string nextvaluebinary)
{
bool test = true;
for (int i = -1; i < 8; ++i)
{
i++;
System.Console.WriteLine(nextvaluebinary[i] + " " + nextvaluebinary[i + 1]);
if (nextvaluebinary[i] == '1')
{
System.Console.WriteLine("Activated");
if (nextvaluebinary[i + 1] == '0')
{
test = false;
System.Console.WriteLine("false");
}
}
else
{
test = true;
}
if (test == false)
{
break;
}
}
return test;
}

Reliably checking if a string is base64 encoded in .Net

Before I start: Yes, I have checked the other questions and answers on this topic both here and elsewhere.
I have found an example string that the .Net will base64 decode even though it isn't actually base64 encoded. Here is the example:
Rhinocort Aqueous 64mcg/dose Nasal Spray
The .Net method Convert.FromBase64String does not throw an exception when decoding this string so my IsBase64Encoded method happily returns true for this string.
Interestingly, if I use the cygwin base64 -d command using this string as input, it fails with the message invalid input.
Even more interestingly, the source that I thought that belongs to this executable (http://libb64.sourceforge.net/) "decodes" this same string with the same result as I am getting from the .Net Convert.FromBase64String. I will keep looking hoping to find a clue elsewhere but right now I'm stumped.
Any ideas?
There's a slightly better solution which also checks the input string length.
I recommend you do a check at the beginning. If the input is null or empty then return false.
http://www.codeproject.com/Questions/177808/How-to-determine-if-a-string-is-Base-decoded-or
When strings do pass Base64 decoding and the decoded data has special characters, then perhaps we can conclude that it was not valid Base64 (this depends on the encoding). Also, sometimes we're expecting the data being passed to be Base64, but sometimes it may not be properly padded with '='. Therefore, one method uses "strict" rules for Base64 and the other is "forgiving".
[TestMethod]
public void CheckForBase64()
{
Assert.IsFalse(IsBase64DataStrict("eyJhIjoiMSIsImIiOiI2N2NiZjA5MC00ZGRiLTQ3OTktOTlmZi1hMjhhYmUyNzQwYjEiLCJmIjoiMSIsImciOiIxIn0"));
Assert.IsTrue(IsBase64DataForgiving("eyJhIjoiMSIsImIiOiI2N2NiZjA5MC00ZGRiLTQ3OTktOTlmZi1hMjhhYmUyNzQwYjEiLCJmIjoiMSIsImciOiIxIn0"));
Assert.IsFalse(IsBase64DataForgiving("testing123"));
Assert.IsFalse(IsBase64DataStrict("ABBA"));
Assert.IsFalse(IsBase64DataForgiving("6AC648C9-C08F-4F9D-A0A5-3904CF15ED3E"));
}
public bool IsBase64DataStrict(string data)
{
if (string.IsNullOrWhiteSpace(data)) return false;
if ((new Regex(#"[^A-Z0-9+\/=]", RegexOptions.IgnoreCase)).IsMatch(data)) return false;
if (data.Length % 4 != 0) return false;
var e = data.IndexOf('=');
var l = data.Length;
if (!(e == -1 || e == l - 1 || (e == l - 2 && data[l - 1] == '='))) return false;
var decoded = string.Empty;
try
{
byte[] decodedData = Convert.FromBase64String(data);
decoded = Encoding.UTF8.GetString(decodedData);
}
catch(Exception)
{
return false;
}
//check for special chars that you know should not be there
char current;
for (int i = 0; i < decoded.Length; i++)
{
current = decoded[i];
if (current == 65533) return false;
if (!((current == 0x9 || current == 0xA || current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)) ||
((current >= 0x10000) && (current <= 0x10FFFF))))
{
return false;
}
}
return true;
}
public bool IsBase64DataForgiving(string data)
{
if (string.IsNullOrWhiteSpace(data)) return false;
//it could be made more forgiving by replacing any spaces with '+' here
if ((new Regex(#"[^A-Z0-9+\/=]", RegexOptions.IgnoreCase)).IsMatch(data)) return false;
//this is the forgiving part
if (data.Length % 4 > 0)
data = data.PadRight(data.Length + 4 - data.Length % 4, '=');
var e = data.IndexOf('=');
var l = data.Length;
if (!(e == -1 || e == l - 1 || (e == l - 2 && data[l - 1] == '='))) return false;
var decoded = string.Empty;
try
{
byte[] decodedData = Convert.FromBase64String(data);
decoded = Encoding.UTF8.GetString(decodedData);
}
catch (Exception)
{
return false;
}
//check for special chars that you know should not be there
char current;
for (int i = 0; i < decoded.Length; i++)
{
current = decoded[i];
if (current == 65533) return false;
if (!((current == 0x9 || current == 0xA || current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)) ||
((current >= 0x10000) && (current <= 0x10FFFF))))
{
return false;
}
}
return true;
}

Categories

Resources