Why did System.String[] appear as the output from printing 2d array? - c#

Using this, I'm trying to print a list of the contents of players.text
I know that the foreach loop will print it just fine if the Console.Writeline
is used. But I'm attempting to manipulate the data in particular ways later, and need it split using the indicated delimiter.
However, with the given code all I get is a repeated System.String[] printout.
I've done a search or two and most of what I've found has to do with one part or the other, I haven't found any information on how to use them together.
string[] playerFile = File.ReadAllLines("players.txt");
foreach (string s in playerFile)
{
//Console.WriteLine(s);
string[] playerStuff = s.Split(';');
Console.WriteLine(playerStuff);
}
Console.ReadKey();
I realize it's a simplistic question. But often, for me at least, it's missing the obvious that drives me the most crazy.
Thanks in advance.
Player;Team;POS;HR;RBI;AVG
Abreu, J;CWS;1B;30;101;0.29
Altuve, J;HOU;2B;15;66;0.313
Andrus, E;TEX;SS;7;62;0.258
Arenado, N;COL;3B;42;130;0.287
Aybar, E;LAA;SS;3;44;0.27
The above is the first few lines of the input.
Basically, I want it to look just like that, minus the semicolons. Formatting will come later.
Attempting to add a second foreach, such as was suggested below, the code looked like this:
foreach (string s in playerFile)
{
//Console.WriteLine(s);
string[] playerStuff = s.Split(';');
foreach (string player in playerStuff)
{
Console.WriteLine(player);
}
}
This resulted in EACH piece of information getting it's own line. I follow the logic of why it did that, but I'm not sure what to do about it.

For a method call to compile the compiler has to figure out what you want to do and here, in particular, there are many overloads to the Console.WriteLine method. An "overload" basically means that there are several definitions of Console.WriteLine, all taking different types of parameters.
If the compiler can find an overload that takes exactly what you're trying to pass it, in this case string[], then good, that's the overload that will be called.
If not then it will take "the next best thing", if at all possible.
Let's list all the overloads to Console.WriteLine:
WriteLine()
WriteLine(Boolean)
WriteLine(Char)
WriteLine(Char[])
WriteLine(Char[], Int32, Int32)
WriteLine(Decimal)
WriteLine(Double)
WriteLine(Int32)
WriteLine(Int64)
WriteLine(Object)
WriteLine(Single)
WriteLine(String)
WriteLine(String, Object)
WriteLine(String, Object, Object)
WriteLine(String, Object, Object, Object)
WriteLine(String, Object, Object, Object, Object)
WriteLine(String, Object[])
WriteLine(UInt32)
WriteLine(UInt64)
Now, now of these will be able to accept a string[] except one:
WriteLine(Object)
This particular overload will simply call .ToString() on whatever it is passed.
Since a string array does not have a ToString implementation that looks at the contents of the array, or anything like that, the basic System.Object.ToString() method that every type inherits is used, and this simply returns the full name of the type as a string, which is basically System.String[].
So that's why the code compiles, and also why it doesn't do what you expect it to do.
The question is, what do you expect it to do?
If you wanted it to output all the strings as a comma-separated set of values on each line you can do this:
Console.WriteLine(string.Join(", ", playerStuff));
If you simply wanted to concatenate all the strings and put nothing between them, replace the ", " in the above statement with "" or string.Empty:
Console.WriteLine(string.Join(string.Empty, playerStuff));

The reason you are getting the output that you are is because it is trying to write the Array object to the console; and it doesn't know how to handle it, so it is just printing out the Type of the object that it is trying to write out.
You need to do another foreach or something similar on playerStuff.
string[] playerFile = File.ReadAllLines("players.txt");
foreach (string s in playerFile)
{
//Console.WriteLine(s);
string[] playerStuff = s.Split(';');
//Inner foreach that writes out each entry of the array
foreach(var item in playerStuff)
{
Console.Write(item + " ");
}
Console.Write(Environment.NewLine);
}
Console.ReadKey();
OR even simpler
string[] playerFile = File.ReadAllLines("players.txt");
foreach (string s in playerFile)
{
Console.WriteLine(s.Replace(';', ' '));
}
Console.ReadKey();
OR a one liner
string[] playerFile = File.ReadAllLines("players.txt");
playerFile.ForEach(x => Console.WriteLine(x.Replace(';', ' ')));
Console.ReadKey();
Sample output image for all 3 of the above solutions:
Console.WriteLine docs for reference
String.Replace docs for reference

Related

How would I change how arguments are passed to a string.format() function depending how how many there are?

Currently I am trying to write something to take strings from a txt file and input them into an array. I was doing it by manually inputting them and using interpolated strings but that is becoming unfeasible now. I need to be able to change parts of the string depending on the result of a function, and on any given string there could 0 to any number of parts that need to be changed. I figured this would work in theory but that there had to be a better way:
public void formatStringInSentencesArray(int numOfArgs, int arrIndexToBeFormatted, UnityAction[] funcsToBePutIn)
{
if (numOfArgs == 1)
{
conversation[index].sentences[arrIndexToBeFormatted] = string.Format(conversation[index].sentences[arrIndexToBeFormatted], funcsToBePutIn[0]);
}
...
else if (numOfArgs == 5)
{
conversation[index].sentences[arrIndexToBeFormatted] = string.Format(conversation[index].sentences[arrIndexToBeFormatted], funcsToBePutIn[0], funcsToBePutIn[1], funcsToBePutIn[2], funcsToBePutIn[3], funcsToBePutIn[4]);
}
Is there any way I could go about doing this in a way that isn't just a hacked together bunch of ifs and else ifs? (This is all written in C# for a unity game btw)
Welcome to SO.
string.format already supports arrays. Is this what you're looking for?
var paramArray = new string[] { "a", "b", "c", "d", "e" };
var output = string.Format("{0} {1} {2} {3}", paramArray);
Based on your example, I'd probably replace your function with:
conversation[index].sentences[arrIndexToBeFormatted] = string.Format(conversation[index].sentences[arrIndexToBeFormatted], funcsToBePutIn);
By using the params keyword, you can specify a method parameter that takes a variable number of arguments. The parameter type must be a single-dimensional array.
No additional parameters are permitted after the params keyword in a method declaration, and only one params keyword is permitted in a method declaration.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params
The compiler will deal with turning that line of Arguments into a single array.
The String.Format() - and function that use it like Console.WriteLine() - use the params keyword. The main function behaves as if it does, but given that the data comes from the OS it is possible it is not using the keyword (making the array is somebody elses job).

adding a string to an array

I'm just doing a little project in C# (I'm a beginner), my code is basically asking you "how many words are in this sentence?" and then asks you for every word, once it gets all of them it prints it out with "ba" attached to every word.
I know I'm a real beginner and my code's probably a joke but could you please help me out with this one?
Console.WriteLine("How many words are in this sentence?");
int WordAmount = Convert.ToInt32(Console.ReadLine());
int i = 1;
while (i <= WordAmount)
{
Console.WriteLine("Enter a word");
string[] word = new string[] { Console.ReadLine() };
i++;
}
Console.WriteLine(word + "ba");
You're close, you've just got one issue.
string[] word = new string[] { Console.ReadLine() };
You are creating a new array list inside the scope of a while loop. Not only will this disappear every loop, meaning you never save the old words, but you also won't be able to use it outside of the loop, making it useless.
Create a string[] words = new string[WordAmount];. Then iterate through it to add your Console.ReadLine() to it, and finally, iterate through it once more and Console.WriteLine(words[i] + "ba");
string[] wordList = new string[WordAmount];
while (i <= WordAmount)
{
Console.WriteLine("Enter a word");
wordList[i-1] = Console.ReadLine() ;
i++;
}
foreach (var item in wordList)
Console.WriteLine(item + "ba");
Working Fiddle: https://dotnetfiddle.net/7UJKwN
your code has multiple issues. First you need to define your array outside of your while loop, and then fill it one by one.
In order to read/write array of strings (string[]), you need to loop through (iterate) it.
My code actually iterates your wordList. In the first While loop I am iterating to fill the wordList array. then printing it in the second loop
First of all, consider storing your words in some kind of collection, for example a list.
List<string> words = new List<string>();
while (i <= WordAmount)
{
Console.WriteLine("Enter a word");
string word = Console.ReadLine();
words.Add(word);
i++;
}
I don't think your code compiles - the reason is you are trying to use the word variable outside of the scope that it is defined in. In my solution I have declared and initialized a list of strings (so list of the words in this case) outside of the scope where user has to input words, it is possible to access it in the inner scope (the area between curly brackets where user enters the words).
To print all the words, you have to iterate over the list and add a "ba" part. Something like this:
foreach(var word in words)
{
Console.WriteLine(word + "ba");
}
Or more concisely:
words.ForEach(o => Console.WriteLine(o + "ba"));
If you want to print the sentence without using line breaks, you can use LINQ:
var wordsWithBa = words.Select(o => o + "ba ").Aggregate((a, b) => a + b);
Console.WriteLine(wordsWithBa);
Although I would recommend learning LINQ after you are a bit more familiarized with C# :)
You can look here and here to familiarize yourself with the concept of collections and scopes of variables.
You could also use a StringBuilder class to do this task (my LINQ method is not very efficient if it comes to memory, but i believe it is enough for your purpose).

Getting "System.String[]" instead of actual value after splitting.

So I have a very simple bit of code
public static string[] config = File.ReadAllLines(Environment.CurrentDirectory.ToString() + "\\documents\\config.json");
public static void Start()
{
Console.WriteLine(config[4]);
Console.ReadKey();
}
This properly displays the 5th item in the array, which is "0x00=jU0UrZBkqPXfp8MsMoILSRylevQGaUmJRnpFbfUvcGs=7lvpCgtyWl0 : crypt_wallet". I only want the first part of the string, so "0x00=jU0UrZBkqPXfp8MsMoILSRylevQGaUmJRnpFbfUvcGs=7lvpCgtyWl0".
When I use Console.WriteLine(config[4].split(null); or anything else in the split arguments, I just get back System.String[].
How would I fix that so it properly displays the answer?
Should rather be like below since you will have to choose the element to print since Split() returns a string[]
Console.WriteLine(config[4].Split(':')[0]);
Not sure what you mean by the "the first part of the string". But you can achieve this by using .Substring().
If you know that the beginning will always be a fixed length, you can do:
config[4].Substring(0, 4);
If you know the value will be followed by a certain character (like the "=" for an example:
config[4].Substring(0, config[4].IndexOf("="));

C# string Thread.Sleep()

Hi i'm currently using Thread.Sleep(200); in between text for it to look like old pokemon game with the text not appearing all at once but going a bit laggy word for word like this
Console.Write("help"); Thread.Sleep(200); Console.Write("me");
And i'm wondering if you can name/shorten the Thread.Sleep(200) to something like Ts200. (I mean to text). So it's not much clutter.
So it would be something like this with a string.
string Ts200
Ts200 = Thread.Sleep(200)
Console.Write("help"); Ts200; Console.Write("me")
But it's not working.
I get this error:
cannot implicitly convert type void to string
a simple way to do this would be to split the strings into arrays on spaces, then loop over them.
using System;
using System.Threading;
public static void slowType(string fullSentence, int millis_pause)
{
string[] words = fullSentence.Split(' ');
foreach(string s in words)
{
Console.Out.Write(s);
Thread.Sleep(millis_pause);
//we must reintroduce the space, since we were splitting on it.
Console.Out.Write(' ');
}
//optionally ; start a new line at the end of the sentence
Console.Out.Write("\r\n");
}
usage example :
public static void Main()
{
string sentence = "i am a terribly slow typist";
slowType(sentence, 200);
}
Try lambda if you don't mind () after Ts200:
Action Ts200 = () => Thread.Sleep(200);
...
Ts200();
However, even if it's possile Ts200() is far less readable than Thread.Sleep(200), that's why don't do it.
You call the Thread.Sleep(200); on its own, it doesnt contain any value. So you cant return any value neither can you allocate it any value, except as the method parameter Thread.Sleep("Here belongs the method parameter, this method accepts an 'int' value"). The int method parameter sets for how many milli seconds you want to pause the mainthread.
Try something like this:
The main method is the entry point in your application once it gets executed. So when you start your application, you call the main method and execute it.
static void Main(string[] args)
{
string sentence = "Here you enter your sentence...";
string[] words = sentence.Split(' ');
OutputDelayedText(words);
}
The string sentence is the string variable that contains the sentence you want to ouput on the console. So we split the sentence into single words with the method .Split(' '). This splits the spring on each space ' ' and puts the single words into a string[] array. Note that you have to use in the .Split('') method these '' instead of what you are probably used to "". Thats because the method accepts a char value and those '' indicate that you just put a single char in as the method parameter.
So in the end we call the OutputDelayedText() method with our word array as method parameter.
private static void OutputDelayedText(string[] myText)
{
foreach (var word in myText)
{
Console.Write(word + " ");
Thread.Sleep(200);
}
}
Now we use a foreach loop to iterate over the array and write every single element of our array (one single word of our sentence) in one line on the console. If you are not familiar with foreach you could use either a for or while loop as well.
In generell i advice you to use Task.Delay(). Or in WinForms the Backgroundworker, those will allow you to work on different threads and if you pause those threads you dont pause your main thread. You will come across this issue later, this is used to pause any process or to execute a long task in the background to not freeze your GUI when the task is still running.
However just start with Thread.Sleep(), but keep in mind: In the art of programming are so many ways how to achieve your goal and you might stumble quite often over a better solution.

Check if Characters in ArrayList C# exist - C# (2.0)

I was wondering if there is a way in an ArrayList that I can search to see if the record contains a certain characters, If so then grab the whole entire sentence and put in into a string. For Example:
list[0] = "C:\Test3\One_Title_Here.pdf";
list[1] = "D:\Two_Here.pdf";
list[2] = "C:\Test\Hmmm_Joke.pdf";
list[3] = "C:\Test2\Testing.pdf";
Looking for: "Hmmm_Joke.pdf"
Want to get: "C:\Test\Hmmm_Joke.pdf" and put it in the Remove()
protected void RemoveOther(ArrayList list, string Field)
{
string removeStr;
-- Put code in here to search for part of a string which is Field --
-- Grab that string here and put it into a new variable --
list.Contains();
list.Remove(removeStr);
}
Hope this makes sense. Thanks.
Loop through each string in the array list and if the string does not contain the search term then add it to new list, like this:
string searchString = "Hmmm_Joke.pdf";
ArrayList newList = new ArrayList();
foreach(string item in list)
{
if(!item.ToLower().Contains(searchString.ToLower()))
{
newList.Add(item);
}
}
Now you can work with the new list that has excluded any matches of the search string value.
Note: Made string be lowercase for comparison to avoid casing issues.
In order to remove a value from your ArrayList you'll need to loop through the values and check each one to see if it contains the desired value. Keep track of that index, or indexes if there are many.
Then after you have found all of the values you wish to remove, you can call ArrayList.RemoveAt to remove the values you want. If you are removing multiple values, start with the largest index and then process the smaller indexes, otherwise, the indexes will be off if you remove the smallest first.
This will do the job without raising an InvalidOperationException:
string searchString = "Hmmm_Joke.pdf";
foreach (string item in list.ToArray())
{
if (item.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0)
{
list.Remove(item);
}
}
I also made it case insensitive.
Good luck with your task.
I would rather use LINQ to solve this. Since IEnumerables are immutable, we should first get what we want removed and then, remove it.
var toDelete = Array.FindAll(list.ToArray(), s =>
s.ToString().IndexOf("Hmmm_Joke.pdf", StringComparison.OrdinalIgnoreCase) >= 0
).ToList();
toDelete.ForEach(item => list.Remove(item));
Of course, use a variable where is hardcoded.
I would also recommend read this question: Case insensitive 'Contains(string)'
It discuss the proper way to work with characters, since convert to Upper case/Lower case since it costs a lot of performance and may result in unexpected behaviours when dealing with file names like: 文書.pdf

Categories

Resources