C#: How to use arrays, chars and strings? Clear up needed - c#

I am new to programming and I have a project in my Algorithm class. What we have to do is decide on a problem and solve it. We haven't learnt much more than string, char and WriteLine. We did add a couple of things as you will see soon!
I decided that what I want to solve this: The user inserts a word, no matter how long and the program will automatically make the first letter a capital letter. So far this is what I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
start:
Console.WriteLine("Please enter a word below:");
Console.WriteLine("");
string str = Console.ReadLine();
char char1;
if (str[0] >= 97)
{
char1 = (char)(str[0] - 32);
}
else
{
char1 = (char)(str[0] + 32);
}
char char2 = (char)(str[1]);
char char3 = (char)(str[2]);
char char4 = (char)(str[3]);
char char5 = (char)(str[4]);
Console.WriteLine("");
Console.Write(char1);
Console.Write(char2);
Console.Write(char3);
Console.Write(char4);
Console.WriteLine(char5);
goto start;
}
}
}
The problem with that code is that any word with less than 5 letters will make the program crash. Anything with more than 5 letters will just be cut at the fifth letter... I was told that using arrays should solve this problem. Seeing as I am a total newbie at this, I would need this to be broken down and be as simply told as possible!
Any help getting this to work would be very appreciated.
Thanks :)

Console.WriteLine("Enter a word:");
string str = Console.ReadLine();
Console.WriteLine(str[0].ToString().ToUpper() + str.Substring(1));
This will work.
Or... if you need to go through the entire string and find the first actual alphabetical character, you can do the following:
Console.WriteLine("Please enter a word:");
string s = Console.ReadLine();
bool found = false;
char[] chars = new char[s.Length];
for (int i = 0; i < s.Length; i++)
{
if (Char.IsLetter(s[i]) && !found)
{
chars[i] = s[i].ToString().ToUpper()[0];
found = true;
}
else
{
chars[i] = s[i];
}
}
s = new String(chars);
Console.WriteLine(s);

Use a for loop like this after writing char1 to the Console:
if (str.Length > 1)
{
for (int i = 1; i < str.Length; i++)// Start at 1 to skip char1
{
Console.Write(str[i]);
}
}

There are some methods you can call on string that will be helpful:
Substring
ToUpper
In fact, you don't need to worry about characters; this problem can be solved using only strings.
Also take care to check that your code handles the case where the string is empty (using an if statement), which will happen if the user just presses Enter without typing anything.

You're taking an algorithms class and they make you choose a problem to solve? Sounds dangerous for someone learning.
Console.WriteLine("Please enter a word below:");
Console.WriteLine("");
string inputString = Console.ReadLine(); // try to use meaningful variable names
// shorthand for the if ... else block:
// type variableName = (true/false condition) ? "is true" : "is false";
char firstChar = inputString[0] >= 97 ? (char)(inputString[0] - 32) : (char)(inputString[0] + 32);
Console.WriteLine("");
Console.Write(firstChar);
for (int i = 1; i < inputString.Length; i++) // skip firstChar
{
Console.Write(inputString[i]);
}
As others have mentioned, you need to use a loop for this if you want anything resembling a general solution.
Also, you'll want to avoid using goto statements. There are many reasons, one being that they (in my opinion) make code difficult to read and maintain.
Additionally, if your code had worked as written, it would never end. Your program, as written would execute, then begin again, never stopping. If you want this sort of behavior, then you should wrap your code in an infinite loop which exits upon some condition. This might look something like:
bool keepRunning = true;
while(keepRunning){
//code here
Console.Write("go again? (y/n) ");
keepRunning = (string)(Console.ReadLine()).equals("y") ? false : true;
}
On that last statement, I forget if you need to cast the output of ReadLine to a string before calling the .equals method... I don't have my IDE up. i think you get the idea.
edit: I saw another response that was just posed about using the .ToUpper method. I thought of this but assumed maybe you needed to use the char type.

Related

Comparing a string[index] to another string

I am in the process of learning C# and I'm building a hangman game from scratch as one of my first projects.
Everything works except for the part that replaces the dashes of the hidden word with the correctly guessed letters.
For example: ----- becomes G-EA- after you guess G, E, and A.
I have a for loop that logically seems like it'd do the job except I can't use the == operator for strings or chars.
for (int i = 0; i <= answer.Length; i++) //answer is a string "theword"
{
if (answer[i] == passMe) //passMe is "A" for example
{
hiddenWord = hiddenWord.Remove(i, 1);
hiddenWord = hiddenWord.Insert(i, passMe);
}
}
I've scoured the net trying to find a good solution. Most recommend using Regex or other commands I haven't learned yet and therefore don't fully understand how to implement.
I've tried converting both to char format in the hope that it would fix it, but no luck so far. Thanks in advance for any help.
If passMe is a string of only one char then
if (answer[i] == passMe[0])
In this way you compare the character at i-th position with the character at the first position of your user input
There is also a serious error in your code.
Your loop goes off by one, change it to
for (int i = 0; i < answer.Length; i++)
The arrays in NET start at index zero and, the max index value possible, is always one less than the length of the array.
answer[i] refers to a character and passMe is a single character string. (not a character)
Try this
for (int i = 0; i <= answer.Length; i++) //answer is a string "theword"
{
if (answer[i] == passMe[0]) //passMe is "A" for example
{
hiddenWord = hiddenWord.Remove(i, 1);
hiddenWord = hiddenWord.Insert(i, passMe);
}
}
you need to compare a character with a character.

"System.FormatException" when getting user input from console - visual c#

I am trying to make a command line program that will ask if fast and long you want it to beep. I keep getting System.FormatException on the code below. I get the problem right after Console.WriteLine("how many times should i beep?");. I've found a fix by putting a console.read();//pause right after this line.
My question is what am I doing wrong? or am I suppose to have the pause after that line?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("how fast would you like the sounds to play?");
Console.WriteLine("70 = fast and 300 = slow can pick any number inbetween");
string choice = Console.ReadLine();
int speed = Convert.ToInt32(choice);
Console.Write(speed);
Console.Read();//pause
Console.WriteLine("how many times should i beep?");
string choice2 = Console.ReadLine();
int j = Convert.ToInt32(choice2);
Console.Write(j);
Console.Read();//pause
for (int i = 0 ; i < j; i++)
{
Console.Beep(1000, speed);
}
}
}
My psychic debugging skills tell me that it's this line throwing the exception:
int j = Convert.ToInt32(choice2);
Putting the Console.Read() in like you mentioned before that causes that line not to execute immediately and delaying the throwing of the exception.
If you input something that isn't an integer on this line:
string choice2 = Console.ReadLine();
You will get a FormatException on the following Convert.ToInt32 call.
See the documentation for Convert.ToInt32 where it tells you a FormatException is thrown when the value you pass does not consist of an optional sign followed by a sequence of digits (0 through 9).
To solve your issue, use Int32.TryParse (or just make sure you enter a valid integer). That will return a boolean indicating the success or failure of the parsing rather than throwing an exception.
Also, welcome to StackOverflow! Be sure to upvote answers you find helpful and accept the one that best resolves your question.
why are those extra Console.Read() in there? They are breaking your program, because the user will press return too many times
Console.WriteLine("how fast would you like the sounds to play?");
Console.WriteLine("70 = fast and 300 = slow can pick any number inbetween");
string choice = Console.ReadLine();
int speed = Convert.ToInt32(choice);
Console.WriteLine(speed);
Console.WriteLine("how many times should i beep?");
string choice2 = Console.ReadLine();
int j = Convert.ToInt32(choice2);
Console.Write(j);
for (int i = 0; i < j; i++)
{
Console.Beep(1000, speed);
}
Actually, all you need to do is remove those Read() pauses you threw in. I'd probably also change the Write() calls to WriteLine() calls.
You can also change the Read() calls to ReadLine() calls, if you insist on "pausing" there.
Try this:
Console.Read();
string choice2 = Console.ReadLine();

Replace strings in C#

This might be a very basic question. I need to write a code which works similar as string replace algorithm.
static string stringReplace(string s, string stringOld, string stringNew)
{
string newWord = "";
int oldMax = stringOld.Length;
int index = 0;
for (int i = 0; i < s.Length; i++)
{
if (index != oldMax && s[i] == stringOld[index])
{
if (stringOld[index] < stringNew[index])
{
newWord = newWord + stringNew[index];
index++;
}
else
{
newWord = newWord + stringNew[index];
}
}
else
{
newWord = newWord + s[i];
}
}
return newWord;
}
Since it's 3am the code above is probably bugged. When the new word is shorter than the old one, it goes wrong. Same as when it's longer. When the index variable is equal for both stringOld and stringNew, it will do the swap. I think... Please don't post "use string.Replace(), I have to write that algorithm myself...
I don't know what you're trying to do with your code, but the problem is not a small one.
Think logically about what you are trying to do.
It is a two step process:
Find the starting index of stringOld in s.
If found replace stringOld with stringNew.
Step 1:
There are many rather complex (and elegant) efficient string search algorithms, you can search for them online or look at popular 'Introduction to Algorithms' by Cormen, Leiserson, Rivest & Stein, but the naive approach involves two loops and is pretty simple. It is also described in that book (and online.)
Step 2:
If a match is found at index i; simply copy characters 0 to i-1 of s to newWord, followed by newString and then the rest of the characters in s starting at index i + oldString.Length.

Foreach doubles or triples itself

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace lotto
{
class Program
{
static void Main(string[] args)
{
char k = 'l';
while (!(k == 'k'))
{
Random rnd = new Random();
int[] tablica = new int[6];
for (int i = 0; i < 6; i++)
{
tablica[i] = 0;
}
for (int i = 0, z; i < 6; i++)
{
{
z = rnd.Next(1, 49);
while (tablica.Contains(z))
{
z = rnd.Next(1, 49);
}
tablica[i] = z;
}
}
Array.Sort(tablica);
foreach (int q in tablica)
{
Console.Write(q);
Console.Write(", ");
}
k = Convert.ToChar(Console.Read()) ;
Console.WriteLine("\n\n\n");
}
}
}
}
It works alright. When I use the step by step clickage (F10 in visual studio), it runs fine. But when I run it normally, then after the
k=Convert.ToChar(Console.Read());
when I supply 'k', the program stops, as intended.
when I supply nothing, it does the
foreach (int q in tablica)
{
Console.Write(q);
Console.Write(", ");
}
k = Convert.ToChar(Console.Read()) ;
Console.WriteLine("\n\n\n");
two times, and when I supply anything other than 'k' it does it three times. What.The.Hell.
Console.Read reads a single character at a time from the input stream (doc). When you press enter you are supplying two characters: \r then \n, so there are two characters to read before pausing for further user input.
I'm confused how it ran fine when you used F10 as I did this to see what was looping, I just so happened to use Enter when supplying "nothing" and saw the characters pop through.
Did you try capturing the input from Console.Read() and see what it is giving you? It might be something to do with a control character being read in, and it not being able to convert to char properly.
Also, completely aside, I would recommend reformatting your code (you have superfluous "{}" in there in the second for loop). Also, it is always good practice to give meaningful names to your variables. i, j, k, etc. have no inherent meaning. It will just be easier to refactor/maintaining your code in the future.
I didn't take a real close look at the rest of your code, but I'm guessing there are shorter/simpler ways to do a lot of it. This many for/foreach/while loop in one method has a code smell.
By using Console.Read(), you are actually getting your input plus "\r\n",so when you use ENTER you just get "\r\n"(2 chars), when you input a char"m", your input is "m\r\n"(3 chars), that's the reason why there is a "one" difference.
Besides, why use int i = 0, z;? the , z does not mean anything here for this is C++ usage.

Constantly Incrementing String

So, what I'm trying to do this something like this: (example)
a,b,c,d.. etc. aa,ab,ac.. etc. ba,bb,bc, etc.
So, this can essentially be explained as generally increasing and just printing all possible variations, starting at a. So far, I've been able to do it with one letter, starting out like this:
for (int i = 97; i <= 122; i++)
{
item = (char)i
}
But, I'm unable to eventually add the second letter, third letter, and so forth. Is anyone able to provide input? Thanks.
Since there hasn't been a solution so far that would literally "increment a string", here is one that does:
static string Increment(string s) {
if (s.All(c => c == 'z')) {
return new string('a', s.Length + 1);
}
var res = s.ToCharArray();
var pos = res.Length - 1;
do {
if (res[pos] != 'z') {
res[pos]++;
break;
}
res[pos--] = 'a';
} while (true);
return new string(res);
}
The idea is simple: pretend that letters are your digits, and do an increment the way they teach in an elementary school. Start from the rightmost "digit", and increment it. If you hit a nine (which is 'z' in our system), move on to the prior digit; otherwise, you are done incrementing.
The obvious special case is when the "number" is composed entirely of nines. This is when your "counter" needs to roll to the next size up, and add a "digit". This special condition is checked at the beginning of the method: if the string is composed of N letters 'z', a string of N+1 letter 'a's is returned.
Here is a link to a quick demonstration of this code on ideone.
Each iteration of Your for loop is completely
overwriting what is in "item" - the for loop is just assigning one character "i" at a time
If item is a String, Use something like this:
item = "";
for (int i = 97; i <= 122; i++)
{
item += (char)i;
}
something to the affect of
public string IncrementString(string value)
{
if (string.IsNullOrEmpty(value)) return "a";
var chars = value.ToArray();
var last = chars.Last();
if(char.ToByte() == 122)
return value + "a";
return value.SubString(0, value.Length) + (char)(char.ToByte()+1);
}
you'll probably need to convert the char to a byte. That can be encapsulated in an extension method like static int ToByte(this char);
StringBuilder is a better choice when building large amounts of strings. so you may want to consider using that instead of string concatenation.
Another way to look at this is that you want to count in base 26. The computer is very good at counting and since it always has to convert from base 2 (binary), which is the way it stores values, to base 10 (decimal--the number system you and I generally think in), converting to different number bases is also very easy.
There's a general base converter here https://stackoverflow.com/a/3265796/351385 which converts an array of bytes to an arbitrary base. Once you have a good understanding of number bases and can understand that code, it's a simple matter to create a base 26 counter that counts in binary, but converts to base 26 for display.

Categories