I am currently writing a Caesar Cipher program in C# for my assignment and I am having a problem.
I am approaching this task using an array where I store the whole alphabet and I declare a shift variable which is defined by character index in the array - the iteration of a for loop. The shift calculation is done in a foreach loop, that fetches a character from a string that is read from a text file. Foreach loop is contained within a for loop that iterates to output every possible shift.
However, the problem is that when I try to access the character in an array by a value of my shift variable, the program doesn't seem to access the character I want, it just outputs the same character as in the original string.
This is the code for the program:
using System;
using System.IO;
public class caesar_shift
{
public static void Main()
{
string file = #"C:\Users\terasss2\Desktop\Programming and Data Structures\caesarShiftEncodedText.txt"; //String variable that stores a file location
string encrypted_text = File.ReadAllText(file); //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
string decoded_text = " ";
int shift = 0;
char character = '0';
char[] alphabet = new char[26]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
Console.WriteLine("The encrypted text is \n{0}", encrypted_text); //Display the encrypted text
for(int i = 0; i < alphabet.Length; i++) //Start a loop which will display 25 different candidates of decipher
{
foreach(char c in encrypted_text)
{
character = c;
if(character == '\'' || character == ' ')
continue;
shift = Array.IndexOf(alphabet, character) - i; //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable
if(shift <= 0)
shift = shift + 26;
if(shift >= 26)
shift = shift - 26;
character = alphabet[shift]; //Set the character to a shifted letter by accessing the array element of a value shift
Console.WriteLine(character);
decoded_text = decoded_text + character;
}
Console.WriteLine("\nShift {0} \n {1}",i + 1, decoded_text);
}
}
}
I played a bit with your code. The following gives you the solution, but you have to take care: you couldonly use capital letters, because theres a difference in upper and lower charts. I used the ToUpper() method. Works fine for me. I think that's what your problem was.
public static void Main()
{
string encrypted_text = "BCD"; //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
string decoded_text = " ";
int shift = 0;
char character = '0';
encrypted_text = encrypted_text.ToUpper();
char[] alphabet = new char[26] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
Console.WriteLine("The encrypted text is \n{0}", encrypted_text); //Display the encrypted text
for (int i = 0; i < alphabet.Length; i++) //Start a loop which will display 25 different candidates of decipher
{
decoded_text = "";
foreach (char c in encrypted_text)
{
character = c;
if (character == '\'' || character == ' ')
continue;
shift = Array.IndexOf(alphabet, character) - i; //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable
if (shift <= 0)
shift = shift + 26;
if (shift >= 26)
shift = shift - 26;
decoded_text += alphabet[shift];
}
Console.WriteLine("\nShift {0} \n {1}", i + 1, decoded_text);
}
}
I took a look at your code and made a slight adjustment. First of all, I converted it to a method that lets you pass in the string and the amount you want to shift, so that you can either call it in a loop from 0 to 25 to see all the permutations, or you can just get a single value. I also check to see if each character is actually in the array, and if it isn't, then don't change it (in your code you were only checking for '\' and ' ' characters:
public static string ShiftText(string input, int shiftAmount)
{
if (input == null) return null;
char[] alphabet =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
shiftAmount %= 26; // Ensure shift is between 0 and 25
var shiftedText = string.Empty;
foreach (var character in input)
{
var index = Array.IndexOf(alphabet, character);
if (index < 0)
{
// This character isn't in the array, so don't change it
shiftedText += character;
}
else
{
var newIndex = index - shiftAmount;
// If it's negative, wrap around to end of array
if (newIndex < 0) newIndex += 26;
shiftedText += alphabet[newIndex];
}
}
return shiftedText;
}
But another way to do this that works for upper AND lower case, and which is less code, is to simply test if char.IsLetter(character), and then shift the ASCII value of the character within the same 0-25 range.
For example, this does the same as the code above, only it works for lower case letters as well. The difference here is that before we compare the character to our lowest valued character ('a' or 'A'), we test if char.IsLower() first. This way we stay within the ASCII range for this character set:
/// <summary>
/// This method takes the input string and shifts all letter characters
/// to the left (subtracts) by the amount specified in shiftAmount, so
/// if shiftAmount = 1, then 'M' becomes 'L', and 'a' becomes 'z'.
/// </summary>
/// <param name="input">The input string to apply changes to</param>
/// <param name="shiftAmount">A value from 0 to 25, used to shift the characters</param>
/// <returns>The modified (shifted) string</returns>
public static string ShiftText(string input, int shiftAmount)
{
if (input == null) return null;
// Ensure shift is between 0 and 25
shiftAmount %= 26;
var result = string.Empty;
// Loop through input and update result with shifted letters
foreach (var character in input)
{
if (!char.IsLetter(character))
{
// If the character isn't a letter, don't change it
result += character;
}
else
{
var newChar = (char) (character - shiftAmount);
// Adjust newChar to stay within this character range
if (newChar < (char.IsLower(character) ? 'a' : 'A')) newChar += (char) 26;
result += newChar;
}
}
return result;
}
Why don't you just use character's ASCII values. I would convert ciphertext to lower case first. For example a's asci value is 97. I would write a method to extract 97 every characters so a=0,b=1..... z=25. Then for every character in your ciphertext get -3 shifted value of that char.For example input char d should return value 0 which corresponds a.
Related
I am currently writing a Caesar Cipher program in C# for my assignment and I am having a problem.
I am approaching this task using an array where I store the whole alphabet and I declare a shift variable which is defined by character index in the array - the iteration of a for loop. The shift calculation is done in a foreach loop, that fetches a character from a string that is read from a text file. Foreach loop is contained within a for loop that iterates to output every possible shift.
However, the problem is that when I try to access the character in an array by a value of my shift variable, the program doesn't seem to access the character I want, it just outputs the same character as in the original string.
This is the code for the program:
using System;
using System.IO;
public class caesar_shift
{
public static void Main()
{
string file = #"C:\Users\terasss2\Desktop\Programming and Data Structures\caesarShiftEncodedText.txt"; //String variable that stores a file location
string encrypted_text = File.ReadAllText(file); //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
string decoded_text = " ";
int shift = 0;
char character = '0';
char[] alphabet = new char[26]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
Console.WriteLine("The encrypted text is \n{0}", encrypted_text); //Display the encrypted text
for(int i = 0; i < alphabet.Length; i++) //Start a loop which will display 25 different candidates of decipher
{
foreach(char c in encrypted_text)
{
character = c;
if(character == '\'' || character == ' ')
continue;
shift = Array.IndexOf(alphabet, character) - i; //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable
if(shift <= 0)
shift = shift + 26;
if(shift >= 26)
shift = shift - 26;
character = alphabet[shift]; //Set the character to a shifted letter by accessing the array element of a value shift
Console.WriteLine(character);
decoded_text = decoded_text + character;
}
Console.WriteLine("\nShift {0} \n {1}",i + 1, decoded_text);
}
}
}
I played a bit with your code. The following gives you the solution, but you have to take care: you couldonly use capital letters, because theres a difference in upper and lower charts. I used the ToUpper() method. Works fine for me. I think that's what your problem was.
public static void Main()
{
string encrypted_text = "BCD"; //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
string decoded_text = " ";
int shift = 0;
char character = '0';
encrypted_text = encrypted_text.ToUpper();
char[] alphabet = new char[26] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
Console.WriteLine("The encrypted text is \n{0}", encrypted_text); //Display the encrypted text
for (int i = 0; i < alphabet.Length; i++) //Start a loop which will display 25 different candidates of decipher
{
decoded_text = "";
foreach (char c in encrypted_text)
{
character = c;
if (character == '\'' || character == ' ')
continue;
shift = Array.IndexOf(alphabet, character) - i; //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable
if (shift <= 0)
shift = shift + 26;
if (shift >= 26)
shift = shift - 26;
decoded_text += alphabet[shift];
}
Console.WriteLine("\nShift {0} \n {1}", i + 1, decoded_text);
}
}
I took a look at your code and made a slight adjustment. First of all, I converted it to a method that lets you pass in the string and the amount you want to shift, so that you can either call it in a loop from 0 to 25 to see all the permutations, or you can just get a single value. I also check to see if each character is actually in the array, and if it isn't, then don't change it (in your code you were only checking for '\' and ' ' characters:
public static string ShiftText(string input, int shiftAmount)
{
if (input == null) return null;
char[] alphabet =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
shiftAmount %= 26; // Ensure shift is between 0 and 25
var shiftedText = string.Empty;
foreach (var character in input)
{
var index = Array.IndexOf(alphabet, character);
if (index < 0)
{
// This character isn't in the array, so don't change it
shiftedText += character;
}
else
{
var newIndex = index - shiftAmount;
// If it's negative, wrap around to end of array
if (newIndex < 0) newIndex += 26;
shiftedText += alphabet[newIndex];
}
}
return shiftedText;
}
But another way to do this that works for upper AND lower case, and which is less code, is to simply test if char.IsLetter(character), and then shift the ASCII value of the character within the same 0-25 range.
For example, this does the same as the code above, only it works for lower case letters as well. The difference here is that before we compare the character to our lowest valued character ('a' or 'A'), we test if char.IsLower() first. This way we stay within the ASCII range for this character set:
/// <summary>
/// This method takes the input string and shifts all letter characters
/// to the left (subtracts) by the amount specified in shiftAmount, so
/// if shiftAmount = 1, then 'M' becomes 'L', and 'a' becomes 'z'.
/// </summary>
/// <param name="input">The input string to apply changes to</param>
/// <param name="shiftAmount">A value from 0 to 25, used to shift the characters</param>
/// <returns>The modified (shifted) string</returns>
public static string ShiftText(string input, int shiftAmount)
{
if (input == null) return null;
// Ensure shift is between 0 and 25
shiftAmount %= 26;
var result = string.Empty;
// Loop through input and update result with shifted letters
foreach (var character in input)
{
if (!char.IsLetter(character))
{
// If the character isn't a letter, don't change it
result += character;
}
else
{
var newChar = (char) (character - shiftAmount);
// Adjust newChar to stay within this character range
if (newChar < (char.IsLower(character) ? 'a' : 'A')) newChar += (char) 26;
result += newChar;
}
}
return result;
}
Why don't you just use character's ASCII values. I would convert ciphertext to lower case first. For example a's asci value is 97. I would write a method to extract 97 every characters so a=0,b=1..... z=25. Then for every character in your ciphertext get -3 shifted value of that char.For example input char d should return value 0 which corresponds a.
I am trying to write to a new file (create a new file), and I want everything that is shown in the command console (the 26 shifts) when the program runs to all be shown in the new file. However, when I use file.WriteAllText() it overwrites each shift and then only shows the 26th shift in the new file I create.
using System;
using System.IO;
namespace ceasarAssignment
{
public class caesarShift
{
public static void Main()
{
string file = #"text.txt", // Name of the file that is being read from
encrypted = File.ReadAllText(file), // Reading the file
decrypted = " ";
char character = '0';
int shift = 0;
encrypted = encrypted.ToUpper(); // Puts the string into uppercase
char[] alph = new char[26] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
// The array above is the alphabet (26 characters)
Console.WriteLine("Encrypted text: \n{0}", encrypted);
//Shows the encrypted text before it is decrypted
for (int i = 0; i < alph.Length; i++) //adds a counter so that this for loop will repeat until it has happened 26 times
{
decrypted = "";
foreach (char c in encrypted)
{
character = c;// each letter in the file is now defined as a 'character'
if (!char.IsLetter(c)) {
decrypted += c;
continue;
}
shift = Array.IndexOf(alph, character) - i; //searchs the array for the character then minuses the counter to add the correct shift
if (shift <= 0)
shift = shift + 26;// if the character is at the beginning of the array go to the end
if (shift >= 26)
shift = shift - 26;// if the character is at the end of the array go to the beginning
decrypted += alph[shift];
}
Console.WriteLine("\n Shift {0} \n {1}", i+1, decrypted); //Shows the decrypted code for each 26 shifts
}
}
}
}
You need to use File.AppendAllText(path, appendText)
File.WriteAllText() will overwrite the file each time the loop is run
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm creating a basic caesar cipher encryption/decryption. I'm having an issue where a random "u" is appearing instead of a space.. Any not sure how to correct this, any advice would be very much appreciated.
// Decryption Method //
static void decryption() {
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.WriteLine("\n*********************************** Decryption *********************************");
Console.ResetColor();
//pulls getPath from varables class
string path = globalVars.getPath();
string fileContent = "";
string encrypted_text = System.IO.File.ReadAllText(path); //String variable that contains the text from a file. To get the text, the method in a class SystemIO is ran to read the text. It expects a parameter, which is a file directory.
string decoded_text = " ";
int shift = 0;
char character = '0';
encrypted_text = encrypted_text.ToUpper();
char[] alphabet = new char[26] {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
Console.WriteLine("The encrypted text is \n{0}", encrypted_text); //Display the encrypted text
for (int i = 0; i < alphabet.Length; i++) //Start a loop which will display 25 different candidates of decipher
{
decoded_text = "";
foreach(char c in encrypted_text) {
character = c;
if (character == '\'' || character == ' ') continue;
shift = Array.IndexOf(alphabet, character) - i; //Define a shift which is the index of a character in an alphabet array, take away the itteration of this loop. Store the result in a variable
if (shift <= 0) shift = shift + 26;
if (shift >= 26) shift = shift - 26;
decoded_text += alphabet[shift];
}
Console.WriteLine("\n\nShift {0} \n\n {1}", i + 1, decoded_text);
fileContent += "Shift " + (i + 1).ToString() + "\r\n" + decoded_text + "\r\n";
}
// Save Decrypted Output to .TXT file - allows user to choose save path within filesystem.
string filename;
string savePath;
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.WriteLine("\nWhat do you want to name your file??");
Console.ResetColor();
filename = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.WriteLine("Where would you like to save your file??");
Console.ResetColor();
savePath = Console.ReadLine();
File.WriteAllText(savePath + filename + ".txt", fileContent);
Console.ForegroundColor = ConsoleColor.DarkBlue;
Console.WriteLine("File Saved");
Console.WriteLine(Console.Read());
}
Please see below for images of both input and output text
Your bug originates from the fact that Array.IndexOf returns -1 (ie, equivalent to z) if the character is not present in the array, so giving a shift of -1 - i. In particular, the new line characters every 20 characters are causing problems.
I would suggest your check of
if (character == '\'' || character == ' ')
continue;
be replaced with a check
if (!alphabet.Contains(character))
{
decoded_text += character;
continue;
}
Which is much more robust, and in particular works for characters such as \n, or \r followed by \n (\r\n is a line break on windows). Adding the character to the output is optional, but maybe helpful.
Your problem is in the new line characters, which this line:
if (character == '\'' || character == ' ') continue;
does not check.
In that case, Array.IndexOf will return -1. Since your text is correctly decrypted when i == 5 (i.e. "Shift 6"), this will, for unknown characters, give you alphabet[20], which is U. The lines in your input file are 20 characters long and, indeed, the first wrong U appears after 20 characters in the output as well: THEINCREDIBLELEGACYOUFTHE...
You should instead check if Array.IndexOf(...) >= 0.
I don't have a direct answer to your question, suffice to say that it is likely something to do with the way you shift bytes. I do, however, want to share a byte cipher that I found some time ago on the internet, which does exactly what you're trying to do, but in very few lines of code: Original Source Here
Despite the biased downvotes, the snippet of code is actually very good, and works well for simple obfuscation tactics. Here is the code just in case the link were to die:
public static class SimpleByteCipher
{
public static byte[] EncryptStringToByteArray( string data , string password , uint seed)
{
byte[] bytes = Encoding.ASCII.GetBytes( data );
byte[] passwordBytes = Encoding.ASCII.GetBytes( password );
int passwordShiftIndex = 0;
for( int i = 0; i < bytes.Length; i++ )
{
bytes[ i ] = ( byte )( bytes[ i ] + passwordBytes[ passwordShiftIndex ] + seed );
passwordShiftIndex = ( passwordShiftIndex + 1 ) % passwordBytes.Length;
}
return bytes;
}
public static string DecryptByteArrayToString( byte[] data , string password , uint seed)
{
byte[] bytes = data;
byte[] passwordBytes = Encoding.ASCII.GetBytes( password );
int passwordShiftIndex = 0;
for( int i = 0; i < bytes.Length; i++ )
{
bytes[ i ] = ( byte )( bytes[ i ] - passwordBytes[ passwordShiftIndex ] - seed );
passwordShiftIndex = ( passwordShiftIndex + 1 ) % passwordBytes.Length;
}
return Encoding.ASCII.GetString( bytes );
}
}
Again, I know this is not a direct answer, but perhaps you can learn something from the way that user did it.
Question
Take input of 1 character from user. It can be the vowel or consonant.
After the user gives input so it will ask do you want to input the character again for Yes press Y and for No press N.
When the user says No, you have to show how much vowel and how much consonant use has input.
Please do this question using For loop. I think array must be use. I did this code it counting vowel and consonant and spacing. But I cant take the input multiple times.
My code doesnn't run multiple times. I can only write sentence or a character in a line so it will only count that. But I want to ask the user to enter a character again.
I want my code to run multiple times so the user can give input multiple times as I explain my question.
using System;
public class vowelConsonant
{
public static void Main()
{
int vowels = 0;
int consonant = 0;
int space = 0;
Console.WriteLine("Enter a Sentence or a Character");
string v = Console.ReadLine().ToLower();
for (int i = 0; i < v.Length; i++)
{
if (v[i] == 'a' || v[i] == 'e' || v[i] == 'i' || v[i] == 'o' || v[i] == 'u')
{
vowels++;
}
else if (char.IsWhiteSpace(v[i]))
{
space++;
}
else
{
consonant++;
}
}
Console.WriteLine("Your total number of vowels is: {0}", vowels);
Console.WriteLine("Your total number of constant is: {0}", consonant);
Console.WriteLine("Your total number of space is: {0}", space);
Console.ReadLine();
}
}
Thanks
Just put an infinite loop around the whole thing.
using System;
public class vowelConsonant
{
public static void Main()
{
// Infinite loop.
while (true)
{
int vowels = 0;
int consonant = 0;
int space = 0;
Console.WriteLine("Enter a Sentence or a Character");
string v = Console.ReadLine().ToLower();
for (int i = 0; i < v.Length; i++)
{
if (v[i] == 'a' || v[i] == 'e' || v[i] == 'i' || v[i] == 'o' || v[i] == 'u')
{
vowels++;
}
else if (char.IsWhiteSpace(v[i]))
{
space++;
}
else
{
consonant++;
}
}
Console.WriteLine("Your total number of vowels is: {0}", vowels);
Console.WriteLine("Your total number of constant is: {0}", consonant);
Console.WriteLine("Your total number of space is: {0}", space);
}
}
}
This application to count vowels and consonants letters in a sentence.
This is another solution with less line of codes with understanding idea of using loop and nested loop with char arrays.
Application interface with controls names
namespace Program8_4
{
public partial class Form1 : Form
{
// declare the counter variables in field
int iNumberOfVowels = 0;
int iNumberOfConsonants = 0;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// call the methods in this event
GetVowels(txtStringInput.Text);
GetConsonants(txtStringInput.Text);
// show the result in a label
lblOutput.Text = "The number of vowels : " + iNumberOfVowels.ToString() + Environment.NewLine+
"The number of consonants : " + iNumberOfConsonants.ToString();
// assign zero the counters to not add the previous number to new number, and start counting from zero again
iNumberOfVowels = 0;
iNumberOfConsonants = 0;
}
private int GetConsonants(string strFindConsonants)
{
// Declare char array to contain consonants letters
char[] chrConsonants = { 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'X',
'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'x' };
// loop to get each letter from sentence
foreach (char Consonants in strFindConsonants)
{
// another nested loop to compare each letter with all letters contains in chrConsonants array
for (int index = 0; index < chrConsonants.Length; index++)
{
// compare each letter with each element in charConsonants array
if (Consonants == chrConsonants[index])
{
// If it is true add one to the counter iNumberOfConsonants
iNumberOfConsonants++;
}
}
}
// return the value of iNumberOfConsonants
return iNumberOfConsonants;
}
private int GetVowels(string strFindVowels)
{
// Declare char array to contain vowels letters
char[] chrVowels = { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O','U' };
// loop to get each letter from sentence
foreach (char Vowels in strFindVowels)
{
// another nested loop to compare each letter with all letters contains in chrVowels array
for (int index = 0; index < chrVowels.Length; index++)
{
// compare each letter with each element in chrVowels array
if (Vowels == chrVowels[index])
{
// If it is true add one to the counter iNumberOfVowels
iNumberOfVowels = iNumberOfVowels+1;
}
}
}
// return the value of iNumberOfVowels
return iNumberOfVowels;
}
}
}
We can simply find the required vowels and consonant counts using Regex.Matches() function.
Below is the working code snippet:
public static void Main()
{
Console.WriteLine("Enter a Sentence or a Character");
string input = Console.ReadLine().ToLower();
string vowels = #"[aeiouAEIOU]+"; //regular expression to match vowels
string consonants = #"[^aeiouAEIOU]+"; //regular expression to match consonants
string space = #"[\S]+";
int vowLength = new Regex(vowels).Matches(input).Count;
int conLength = new Regex(consonants).Matches(input).Count;;
int spLength = new Regex(space).Matches(input).Count;;
Console.WriteLine("Your total number of vowels is: {0}", vowLength);
Console.WriteLine("Your total number of constant is: {0}", conLength);
Console.WriteLine("Your total number of space is: {0}", spLength);
}
I have created a program that randomly generates a letter from a given word which is stored in a character data type array.
For example:
strong and r is generated and also displayed.
How can I get the position of r and also display it?
s - 1, t - 2, r -3, o - 4, n - 5, g -6. The letter r is the 3rd letter.
Since I have stored the word in character array, array by default has its index value starting from 0 and I can't reset it.
I have got r generated, how can I get and display its position without tampering with my character array?
Is there anyway where I can compare the randomly generated r and its position?
Array.IndexOf Method (Array, Object) is your friend:
int index = Array.IndexOf(characters, randomChar) + 1;
//+1 at the end because indexes are zero-based
You can use Array.IndexOf as follows:
var word = new[] { 's', 't', 'r', 'o', 'n', 'g' };
var character = 'r';
var position = Array.IndexOf(word, character);
Note: Since arrays are zero indexed, you will need to add 1 to position to get 3 as IndexOf will return 2 in this example.
If you want to show ALL positions of a given character then you will need to create a method to find them (something like this although it could probably be improved):
public static IEnumerable<int> AllIndexesOf<T>(this T[] source, T value)
where T : IComparable<T>
{
if (Array.IndexOf(source, value) == -1)
{
yield return -1;
yield break;
}
var position = Array.IndexOf(source, value);
while (position > 0)
{
yield return position;
position = Array.IndexOf(source, value, position + 1);
}
yield break;
}
Which you can then use as follows:
var word = new[] { 's', 't', 'r', 'o', 'n', 'g', 'e', 'r' };
var character = 'r';
foreach (var position in word.AllIndexesOf(character))
{
Console.WriteLine(position.ToString());
}
Since you don't supply any code, let me just show how I would implement it:
public static string RandomChar(string s) {
Random r = new Random();
int i = r.Next(s.Length);
return s[i] + " - " + (i+1);
}
This picks an index at random and returns the character at that index as well as the 1-based index of the character, e.g. "r - 3".
Call it with:
string result = RandomChar("strong");
// Do something with the result, e.g. Console.WriteLine(result).
Is it imperative that you do this is C#? Because you can do this using php:
<?php
$mystring = 'strong';
$findme = 'r';
$pos = strpos($mystring, $findme);
$posadj = $pos +1; //this will offset because the array starts at 0.
// must use ===
if ($pos === false) {
echo "The string '$findme' was not found in the string '$mystring'";
} else {
echo "The string '$findme' was found in the string '$mystring'";
echo " and exists at position $pos which when offset is really $pos1.";
}
?>
The results of this snippet are $pos = 2 and $pos1 = 3.