Im making a hangman game, at the start of the game the word that the player must guess is printed as stars. I have just started making it again after attempting to write it once and just having messy code that i couldn't bug fix. So I decided it best to write it again. The only problem is, when i try to get my array to print out by using array.ToString(); it just returns System.char[]. See below.
code:
class Program
{
static void Main(string[] args)
{
string PlayerOneWord;
string PlayerTwoGuess;
int lives = 5;
Console.WriteLine("Welcome to hangman!\n PLayer one, Please enter the word which player Two needs to guess!");
PlayerOneWord = Console.ReadLine().ToLower();
var stars = new char[PlayerOneWord.Length];
for (int i = 0; i < stars.Length ; i++)
{
stars[i] = '*';
}
string StarString = stars.ToString();
Console.Write("Word to Guess: {0}" , StarString);
Console.ReadLine();
}
}
output:
The output should say Word to guess: Hello.
Please will someone explain why this is happening as its not the first time I have run into this problem.
Calling ToString on a simple array only returns "T[]" regardless what the type T is. It doesn't have any special handling for char[].
To convert a char[] to string you can use:
string s = new string(charArray);
But for your concrete problem there is an even simpler solution:
string stars = new string('*', PlayerOneWord.Length);
The constructor public String(char c, int count) repeats c count times.
The variable stars is an array of chars. This is the reason you get this error. As it is stated in MSDN
Returns a string that represents the current object.
In order you get a string from the characters in this array, you could use this:
Console.Write("Word to Guess: {0}" , new String(stars));
The correct way to do this would be:
string StarString = new string(stars);
ToString() calls the standard implementation of the Array-class's ToString-method which is the same for all Arrays and similarily to object only returns the fully qualified class name.
Try this code:
static string ConvertCharArr2Str(char[] chs)
{
var s = "";
foreach (var c in chs)
{
s += c;
}
return s;
}
Related
I need help for this exercise:
Inside the Test class, you must create a public method called copyText that takes a text as input and answer with a text.
It must answer with the same text put together as many time as there is characters in the input text.
Ex: in("car") out "carcarcar";
Ex: in("it") out "itit";
Ex: in("love") out "lovelovelovelove";
Ex: in("coffe") out "coffecoffecoffecoffecoffe";
I have tried to make a solution, where I find the Length of the word,
but I can't figure out to do this part:
Answer with the same text put together as many time as there are characters:
class Program
{
static void Main(string[] args)
{
Test k = new Test();
string carText = k.copyText("car");
Console.WriteLine(carText.Length);
}
}
class Test
{
public string copyText(string text)
{
return text;
}
}
You can loop through each character in the word, and append the text each time to a variable.
public string copyText(string text)
{
string output = String.Empty;
for(int i = 0; i < text.Length; i++) {
output += text;
}
return output;
}
It is good to point out that the String class is immutable and for every iteration new object will be created, which can cause high memory consumption. For concatenating strings see the StringBuilder class. I think this article will help you with your exercise.
PS: I also think you should not just copy the snippet, but really research and try to understand how it works. Then when you have more questions than answers, it will cause more and more research and actually learning.
Good luck with the coding :)
so I'm having trouble with the program recognizing the values of my array elements (The name 'a' does not exist in the current context) , plus i can't get line.split to work(I need it to read the next element after the ',' and it needs to loop for all books (it's a library program). Lastly i can't figure out how to change the "10" (i put the number at random, so it doesn't show me an error) in my for loop, so that the program stops after it read all the info from .txt. Here's the code:
EDIT : It doesn't show any more errors, it just crashes now. :(
using System;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
foreach (string line in File.ReadAllLines(#"Duomenys.txt"))
{
string[] a = line.Split(',');
int ISBN = int.Parse(a[0]);
string BookName = a[1];
string Author = a[2];
string Genre = a[3];
string Publisher = a[4];
int PublishYear = int.Parse(a[5]);
int PageNumber = int.Parse(a[6]);
Console.WriteLine(PublishYear);
Console.WriteLine();
Console.ReadKey();
}
}
public void BookWithTheMostPages(int[] a)
{
int maxPages = 0;
string[] lines = File.ReadAllText(#"Duomenys.txt").Split('\n');
foreach (string line in lines)
{
{
Console.ReadLine();
if (a[6] > maxPages)
{
maxPages = a[6];
Console.WriteLine("Storiausios knygos pavadinimas: {0} , jos autorius(-ė): {1}", a[1], a[2]);
}
}
}
}
public void Publish(string[] a)
{
if (!File.Exists(#"Technologija.csv"))
File.Create(#"Technologija.csv").Dispose();
using (StreamWriter streamwrite = new StreamWriter(File.OpenWrite(#"Technologija.csv")))
{
if (a[2] == "Technologija")
{
streamwrite.WriteLine("\n ISBN : {0}, Pavadinimas: {1}, Autorius: {2}, Tipas: {3}, Leidykla: {4}, Išleidimo Metai: {5}, Puslapių skaičius: {6}", a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
}
}
}
public void Output(string[] a)
{
if (!File.Exists(#"Autoriai.csv"))
File.Create(#"Autoriai.csv").Dispose();
using (StreamWriter streamWriter = new StreamWriter(File.OpenWrite(#"Autoriai.csv")))
{
streamWriter.WriteLine("\n{0}", a[2]);
}
}
public void Publishyear(string[] a)
{
if (a[5] == "2014")
{
for (int j = 1; j <= 5; j++)
Console.WriteLine("\nKnygos ISBN: {0}, Pavadinimas {1}, Autorius {2}", a[0], a[1], a[2]);
}
}
}
}
Here's the .txt example:
9781408855669, Harry Potter and the Chamber of Secrets, Joanne K Rowling, Apysaka, Bloomsbury Publishing PLC, 1998, 270. (It's one line)
a and line are scoped to the static Main method (well, actually a is defined twicein Main, which isn't legal). They do not exist outside of there, unless you make them available, either by passing them in as parameters, or by making them available via fields. You should probably:
come up with more meaningful names; a will not help you
pass the value in as a parameter (IMO this would be cleaner than fields, but fields would work too)
decide whether you are working in instance or static context - at the moment you have both, but never instantiate an object, so you won't be able to call any of the methods
Note that the using and foreach should not be terminated like that ; you probably meant:
foreach (string line in File.ReadAllLines(#"Duomenys.txt"))
{
string[] a = line.Split(',');
...
}
(no need for the using / StreamReader)
'a' only exists in the main function. Like Marc said, you'll want to pass in 'a' as a parameter if you're using it in a different function.
So first line of the function:
public void BookWithTheMostPages() {
}
Should be:
public void BookWithTheMostPages(string[] a)
And should be called in the main function like this:
BookeWithTheMostPages(a);
That-a-ways the function "knows" what 'a' is.
Also, I notice that you're not telling your Main function to run any of the functions you wrote. The program runs everything inside the Main function, not just everything in the Main.cs file. So your 'Publishyear', 'Output', 'Publish', and 'BookWithTheMostPages' function simply aren't running.
Now in regards to your Split function not working here's 2 things:
You have already have something name 'a' in your program, you cannot name another variable by the same name. Make sense?
You must 'Split' into another array, since Split returns a series of strings
So it should look like this:
string[] splitLine = line.split(',');
Also these to lines are not correct:
int PublishYear = Convert.ToInt32(a[5]);
int PageNumber = Convert.ToInt32(a[6]);
If you're wanting to have the 'PublishYear' and 'PageNumber' functions to return an int, they cannot be void functions.
public int Publishyear() {
/*Write your code in here*/
return year;
}
Then later you can use the Function like this to get a value.
int i = Publishyear();
Same goes for your 'PageNumber' Function.
There are still a lot of little errors in the program I haven't mentioned and it would take forever to write down everyone with an explination, but for a beginner like yourself take it piece by piece. Follow a guideline like this:
Write down what the program is supposed to do on paper.
Write a small portion of code (couple lines)
Test it.
Repeat steps 2 and 3 until finished.
One last thing, get in the habit of naming your variables with more descriptive names. 'a' doesn't let a reader know at a glance what 'a' is. Write code that is easy for other people to read. I know at the beginning programming can seems very hard and confusing, but keep at it, don't give up. And little by little you'll get this whole programming things figured out.
Cheers!
Alright so first of all, remove the
using (StreamReader dn = new StreamReader(#"Duomenys.txt"));
if you are not using it. If you are reading the file with File.ReadAllLines you are not going to need it. Also, you are not using your foreach loop correctly. The way you want to go would be something like this:
foreach (string line in File.ReadAllLines(#"Duomenys.txt"))
{
string[] a = line.split(',');
int ISBN = Convert.ToInt32(a[0]);
string BookName = a[1];
string Author = a[2];
string Genre = a[3];
string Publisher = a[4];
int PublishYear = Convert.ToInt32(a[5]);
int PageNumber = Convert.ToInt32(a[6]);
}
What I fixed aswell is that you first create a string array named a, but then create a normal string named a which does not work. Also no need to set a size for the array, string.Split() does this automatically.
EDIT: To loop the file lines, assuming they are seperated by line terminators, you could do this:
string[] lines = File.ReadAllText(filename).Split('\n');
// '\n' as the regular line terminator
foreach (string line in lines)
{
// Your other code ...
Got stuck with this.. can you please explain what is happening in it? or give me any link!
String s1="C# Example";
Char[] s3 = s1.ToCharArray();
Console.WriteLine("S3 : {0}",s3);
I want to display the Character which is converted. Output displayed is System.Char[]. Now i need to do some changes, but what is that ?
It is possible in two ways.
1) I need to Change it to String, before i'm going to Print.
Or
2) I need to print it with Char by defining the index, (i.e) s3[0];
Am i correct. Anything More?
The explanation of what happens:
Console.WriteLine("{0}", s3) calls s3.ToString().
Because WriteLine() calls ToString() on each argument
Method ToString() isn't overridden in type System.Array so Object.ToString() is called.
Because Char[] is System.Array and all types inherit from Systen.Object.
Which is equivalent to s3.GetType().ToString() and outputs System.Char[].
Because this is the default implementation. Subtypes can override it. For instance, System.String does, StringBuilder too.
Solution A:
If you want to display the characters individually on console then you need to get each character separately and display it using a loop.
foreach(char ch in s3)
{
Console.WriteLine("S3 : {0}", ch);
}
or, using for-loop,
for (int i = 0; i < s3.Length; i++)
{
Console.WriteLine("S3 : {0}", s3[i]);
}
Solution B :
There's anbther way that I prefer which might not be helpful for you but for those who always looks into better solutions it can be an option also.
Use Extension methods,
Add this class with the extension method in your solution,
public static class DisplayExtension
{
public static string DisplayResult(this string input)
{
var resultString = "";
foreach (char ch in input.ToCharArray())
{
resultString += "S3 : " + ch.ToString() + "\n";
}
return resultString;
}
}
And call the DisplayResult() extension method from your program like this,
Console.WriteLine(s1.DisplayResult());
This will give you the same result but extend the re-usability of your code without writing the for loop for all the repeated situation.
Good answers so far, and great explanation from #abatishchev on why WriteLine() prints System.Char[]
How ever I would like to add an additional solution, because using loops inside your WriteLine() will look confusing and its not very pleasing to the eye. For better readability you can use new string()
In this example it would look like this:
String s1="C# Example";
Char[] s3 = s1.ToCharArray();
Console.WriteLine("S3 : {0}",new string(s3));
Console.WriteLine("S3 : {0}",s3);
gives result s3.ToString() which results System.Char[]
Instead create a for loop like:
Console.Write("S3 :");
for(int i=0; i<s3.Length; i++)
{
Console.Write(s3[i]);
}
which gives desired output
char [] str = new char[20];
Suppose str is the character array, and we need to display it. Do the following (provided you enter something in the str using loop):
Console.WriteLine("The string is: {0}", string.Join("",str));
Here, each character in str is joined and displayed.
I'm working on a Hangman project that requires me to change characters "-" to "a to z". Since I'm learning how to code with C#, I have no clue how to do it.
I obviously need to use position because of the case where the word as duplicated letters (EX.: C oo kies)
Here's the code I developed, it makes my thing crashes and it's obviously incomplete.
private void chkA_Checked(object sender, RoutedEventArgs e)
{
if (motRechercher.Contains("a"))
{
int indexDemotRechercher = motRechercher.IndexOf("a");
int k = indexDemotRechercher;
var StringBuilderOP = new StringBuilder(motRechercher);
StringBuilderOP.Remove(indexDemotRechercher, indexDemotRechercher);
StringBuilderOP.Insert(k, "A");
}}
motRechercher is a STRING that I can use everywhere that I randomly pick from a list of 27 words. If this bother, it's a check-box and where I write the text is a Text-box(called txtMot).
Feel free to use other variables, I'll re-adapt after for my own comprehension. I would just like some explanation/examples to help my learning experience.
Here is the code of the randomiser if you really feel like this can help you understand[It works] :
private void btnDemarrer_Click(object sender, RoutedEventArgs e)
{
Random rdn = new Random();
int nbreAleatoire = rdn.Next(0, 27);
motRechercher = lesMots[nbreAleatoire];
if (motRechercher.Length > 0)
{
String str = new String('-', motRechercher.Length);
txtMot.Text = str;
}
}
QUESTION : How do I make a thing that detects duplicate and that will change the "-" to "a-z"?
Ask questions and I'll try to answer them if you think it's unclear.
Here is a quick sample... I have two strings... one for the hidden word the user does NOT see, and another for the one presented, using "-" or even "_" as place-holders for the actual characters.
I have a simple function "IsThereA" which expects a single letter as to the guess of a letter in the word. I then just call for all the letters including a few random ones. The function returns boolean so you can draw the hangman as each failure occurs.
In the "IsThereA" method, I am looking one character at a time for the guessed letter. If found, I replace it by using substring instead of the "-". So once updated, you can use the "WordUserCanSee" property however you need to.
This version doesn't do case-sensitive, but you can adjust as needed.
public class Hangman
{
string HangmanWord = "cookies";
string WordUserCanSee = "-------";
public Hangman()
{
IsThereA("o");
IsThereA("f");
IsThereA("k");
IsThereA("w");
IsThereA("i");
IsThereA("c");
IsThereA("s");
IsThereA("e");
}
public bool IsThereA(string guessLetter)
{
bool anyMatch = false;
for (int i = 0; i < HangmanWord.Length; i++)
{
if (HangmanWord.Substring(i, 1).Equals(guessLetter))
{
anyMatch = true;
WordUserCanSee = WordUserCanSee.Substring(0, i) + guessLetter + WordUserCanSee.Substring(i + 1);
}
}
return anyMatch;
}
}
motRechercher = motRechercher.Replace("-", "a-z");
I have a function in a class called Function, like below:
public int SearchedRecords(String [] recs)
{
int counter = 0;
String pat = "-----";
String[] records = recs;
foreach (String line in records)
{
if (line.Contains(pat) == true)
{
counter++;
}
}
return counter;
}
And I am calling this method from my main class this way:
String [] file = File.ReadAllLines("C:/Users.../results.txt");
int counter = Function.SearchedRecords( []file);
But I get an error saying:
;expected
What is wrong?
Another question: The function above is counting from a file all the lines with the pattern ----- in them (even if with more dashes, or if the line has some chars before or after the dashes). Am I right?
It's something like the patterns in Java so maybe there is an other way.
Can you enlighten me?
Remove the [] from your parameter.
e.g.
int counter = Function.SearchedRecords(file);
And yes, your assumption about the behavior of the Contains method is correct - you'll match any line containing five consecutive dashes, regardless of what characters are before or after them.
If you want to parse for exactly five dashes, with nothing before or after them I suggest looking into the RegEx class (regular expressions).
Change
int counter = Function.SearchedRecords( []file);
to
int counter = Function.SearchedRecords(file);
and yes, this will work, for that string.
However Contains is case sensitive, if you were matching on a name, or another string with alphabetic characters, the case would have to be identical to match e.g. line.Contains("Binary Worrier") will not match a string "Hello binary worrier".
Also, reading the entire file into memory is fine if you know that the file will always be small, this method gets less efficient the larger the file.
Better to always use something like System.IO.StreamReader or System.IO.File.ReadLines (available in .Net 4 and later), these allow you to consume the file one line at a time. e.g.
using (var reader = new System.IO.StreamReader("MyFile.txt"))
{
while(!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains(pattern))
counter++;
}
}
Change it to
int counter = Function.SearchedRecords(file);
Remove '[]' from a method call. Yes, your function seems to count what you want.
First of all you need to create an instance of function class and then run the function. Hope following code helps
Function fb = new Function();
int counter = fb.SearchedRecords(file);
Right now, you are using SearchRecords as an static function of a static class which doesn't require instantiation.
You can do this in a shorter way using LINQ:
int counter = file.Count(line => line.Contains("-----"));