I am hoping that by asking this question I find a far more effiecient method of doing what it is that I am trying to do.
To start, I have a function whose parameters look as follows:
private void exampleVoid(string filePath, params string[] sourceFile) {
// Code ...
}
**Notice: I am passing the 'sourceFile' parameters into a CodeDom method. This method throws an error if any of the parameters are null.**
My call to exampleVoid looks as follows:
exampleVoid(#"C:\test.txt",
"Some Data",
"Some More Data",
"Even more data");
Under certain cercumstances, the second string in the array (labled "Some More Data") may have to be removed and not passsed to the exampleVoid() method. So, is there some way of removing this string from the array alltogether? Keep in mind that nulling the string out will not work as an exception will be thrown.
Thank you for reading, as well as any further help.
Evan
You cannot remove the string from the array. Creating a new array that includes all other items except the one you want to include is your only option. The code is easy enough:
// Filters out the second item (zero-based index 1)
sourceFile = sourceFile.Where((s, i) => i != 1).ToArray();
I am not sure if I understand your question...
Having said that, you could try this:
string[] sourceFile;
if(condition)
sourceFile = new []{"Some Data","Even more data"};
else
sourceFile = new []{"Some Data","Some More Data","Even more data"};
exampleVoid(#"C:\test.txt", sourceFile);
Related
So, I've been learning C# and I need to remove everything after the
":" character.
I've used a StreamReader to read the text file, but then I can't use the Split function, then I tried it by using an int function to import it, but then again I can't use the Split function?
What I want this to do is import a text file that's written like;
name:lastname
name2:lastname2
And so that it only shows name and name2.
I've been searching this for a couple of days but I can't seem to figure it out!
I don't know what I'm doing wrong and how to import the text file without using StreamReader or anything else.
Edit:
I'm trying to post something to a website that goes like;
example.com/q=(name without ":")
Edit 2:
StreamReader list = new StreamReader(#"list.txt");
string reader = list.ReadToEnd();
string[] split = reader.Split(":".ToCharArray());
Console.WriteLine(split);
gives output as;
System.String[]
You've got a few issues here. First, use File.ReadLines() instead of a StreamReader, its much simpler and easier:
IEnumerable<string> lines = File.ReadLines("path/to/file");
Next, your lines variable needs to be iterated so you can get to each line of the collection:
foreach (string line in lines)
{
//TODO: write split logic here
}
Then you have to split each line on the ':' character:
string[] split = line.Split(":");
Your split variable is an array of string (i.e string[]) which means you have to access a specific index of the array if you want to see its value. This is your second issue, if you pass split to Console.WriteLine() under the hood it just calls .ToString() on the object you have passed it, and with a string[] it won't automatically give you all the values, you have to write that yourself.
So if your line variable was: "name:Steve", the split variable would have two indexes and look like this:
//split[0] = "name"
//split[1] = "Steve"
I made a fiddle here that demonstrates.
I your file size small and your name:lastname in one line use:
var lines = File.ReadAllLines("filaPath");
foreach (var line in lines)
{
var array = line.Split(':');
if (array.Length > 0)
{
var name = array[0];
}
}
if name:lastname isn't in new line tell me how it's seprated
I'm trying make the user select a path, which the program will later on use, the reason why I want it to write it to a file, may be a little irrelevant but I see it as the simplest way for myself to handle the user wanting it to change it at anytime trough the GUI. I'm trying to what I believe is a string array converted to a normal string to use for File.Writealltext but I am failing to do so.
The code I am using is as follows:
string[] selecteddir = Directory.GetDirectories(folderBrowserDialog1.SelectedPath).ToString();
File.WriteAllText(#"/Data/storagedir.cfg", insertstringhere);
The entire strech of code(form load) is as follows.
private void savelocation_Load(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string[] selecteddir = Directory.GetDirectories(folderBrowserDialog1.SelectedPath).ToString();
File.WriteAllText(#"/Data/storagedir.cfg", insertstringhere);
}
else
{
MessageBox.Show("Something went wrong");
}
}
The error is as follows:
CS0029 "Cannot implicitly convert type 'string' to 'string[]' "
To write all the directories names into storagedir.cfg you can use WriteAllLines:
string[] selecteddir = Directory.GetDirectories(folderBrowserDialog1.SelectedPath);
File.WriteAllLines(#"/Data/storagedir.cfg", selecteddir);
^^^^^
That takes an array as second parameter.
Or use String.Join
string[] selecteddir = Directory.GetDirectories(folderBrowserDialog1.SelectedPath);
File.WriteAllText(#"/Data/storagedir.cfg", String.Join(", ", selecteddir);
If you're trying to save the selected path to storagedir.cfg:
File.WriteAllText(#"/Data/storagedir.cfg", olderBrowserDialog1.SelectedPath)
Little difficult to make out exactly what you're trying to achieve, though your problem is that you are getting a list of sub-directories with Directory.GetDirectories(folderBrowserDialog1.SelectedPath) but then calling .ToString() on it. This is throwing your error.
perhaps you don't need to store an array of directories, but only the directory that the user selected. If that is the case then you can omit that line altogether and then store the selected directory in your config.
So this:
File.WriteAllText(#"/Data/storagedir.cfg", insertstringhere);
Becomes this:
File.WriteAllText(#"/Data/storagedir.cfg", folderBrowserDialog1.SelectedPath);
Then later, when you need a list of your config directories you can read that setting from your config and get an array of directories like:
string[] dirs = Directory.GetDirectories(theStringInMyConfig);
That is the corrections:
string selecteddir = Directory.GetDirectories(folderBrowserDialog1.SelectedPath).ToString();
File.WriteAllText(selecteddir + #"\Data\storagedir.cfg", insertstringhere);
ToString() din't return aray of strings, just simple one string.
Use full path or ./ in path. Thats shy "selecteddir" you need, right?
With "#" attribute you can use a normal "\"
Ensure, thats a "Data" folder is exist. And what are you will doing, when the user select "Data" folder in dialog? Save into "...\Data" + #"\Data\storagedir.cfg" :) Affraid it will be too many "Data" folders inside "Data" folders
Do you know another more proper way to do the same things ?
string initialTemplate = "{0}-{1}";
string template = string.Format(initialTemplate, "first", "{0}");
string answer = string.Format(template, "second");
Also the following way has actually known, but in my current case unfortunatelyI can't use that method(i think that that way more proper and the logic more clear):
string initialTemplate = "{0}-{{0}}";
string template = string.Format(initialTemplate, "first");
string answer = string.Format(template, "second");
Maybe is there another hint how to do that?
UPDATE
I'm so sorry but from yours answers I've learnt that my question wasn't enough clear. So I've added a little bit more description.
My situation:
//that template is actually placed in *.resx file
//I want storing only one template and use that in different situations
public const string InitialTemplate = "{0}-{1}";
public static string GetMessage(string one, string two)
{
return string.Format(InitialTemplate, one, two);
}
public static string GetTemplate(string one)
{
return string.Format(InitialTemplate, one, "{0}");
}
//or morew universal way
public static string GetTemplate(params object[] args)
{
return string.Format(InitialTemplate, args, "{0}");
}
static void Main(string[] args)
{
//in almost all cases in my project i need to use string.format like this
string message = GetMessage("one", "two");
//but there is another way where i have to use
//the template have already been assigned first argument
//the result must be "one-{0}"
string getTemplateWithAssignedFirstArg = GetTemplate("one");
}
Do you know more proper way for that kind of situation ?
If you are using C# 6 you can also use string interpolation.
https://msdn.microsoft.com/en-us/library/dn961160.aspx
var answer = $"{firstVar}-{secondVar}";
string initialTemplate = "{0}-{1}";
string answer = string.Format(initialTemplate, "first", "second");
Should do the trick. Or cut out the middle man with:
string answer = string.Format("{0}-{1}", "first", "second");
String.Format is a very useful convenience, but I'd be wary of using it to build format strings that you're going to use to create other format strings. Someone trying to maintain that code, figure out what's going on, and perhaps modify it will be baffled. Using String.Format that way is technically possible, and there could even be scenarios where it's useful, but it's probably just going to result in something that works but is very difficult to understand and debug.
My first suggestion would be to use a StringBuilder. Even when you're appending to the StringBuilder you can use String.Format if needed to create the individual strings.
I wonder if perhaps what you describe in the question is taking place across multiple methods (which is why you might be building your format string in steps.) If that's the case, I recommend not building the string in steps like that. Don't actually start building the string until you have all of the data that you need together, and then build the string at once.
PHP developer here working with c#.
I'm using a technique to remove a block of text from a large string by exploding the string into an array and then shifting the first element out of the array and turning what remains back into a string.
With PHP (an awesome & easy language) it was just
$array = explode('somestring',$string);
array_shift($array);
$newstring = implode(' ', $array);
and I'm done.
I get so mad at c# for not allowing me to create dynamic arrays and for not offering me default functions that can do the same thing as PHP regarding arrays. Instead of dynamic arrays I have to create lists and predefine key structures etc. But I'm new and I'm sure there are still equally graceful ways to do the same with c#.
Will someone show me a clean way to accomplish this goal with c#?
Rephrase of question: How can I remove the first element from an array using c# code.
Here is how far I've gotten, but RemoveAt throws a error while debugging so I don't believe it works:
//scoop-out feed header information
if (entry_start != "")
{
string[] parts = Regex.Split(this_string, #entry_start);
parts.RemoveAt(0);
this_string = String.Join(" ", parts);
}
I get so mad at c# for not allowing me to create dynamic arrays
You may take a look at the List<T> class. Its RemoveAt might be worth checking.
But for your particular scenario you could simply use LINQ and the Skip extension method (don't forget to add using System.Linq; to your file in order to bring it into scope):
if (entry_start != "")
{
string[] parts = Regex.Split(this_string, #entry_start).Skip(1).ToArray();
this_string = String.Join(" ", parts);
}
C# is not designed to be quick and dirty, nor it particularly specializes in text manipulation. Furthermore, the technique you use for removing some portion of a string from a beginning is crazy imho.
Why don't you just use String.Substring(int start, int length) coupled with String.IndexOf("your delimiter")?
Here is the corresponding C# code:
string input = "a,b,c,d,e";
string[] splitvals = input.Split(',');
string output = String.Join(",", splitvals, 1, splitvals.Length-1);
MessageBox.Show(output);
You can use LINQ for this:
if (entry_start != "")
this_string = String.Join(" ", Regex.Split(this_string, #entry_start).Skip(1).ToArray());
string split = ",";
string str = "asd1,asd2,asd3,asd4,asd5";
string[] ary = str.Split(new string[] { split }, StringSplitOptions.RemoveEmptyEntries);
string newstr = string.Join(split, ary, 1, ary.Count() - 1);
splits at ",". removes the first record. then combines back with ","
As stated above, you can use LINQ. Skip(int) will return an IEnumerable<string> that you can then cast back as array.
string[] myArray = new string[]{"this", "is", "an", "array"};
myArray = myArray.Skip(1).toArray();
You might be more comfortable with generic lists than arrays, which work more like PHP arrays.
List<T>
But if your goal is "to remove a block of text from a large string" then the easier way would be:
string Example = "somestring";
string BlockRemoved = Example.Substring(1);
// BlockRemoved = "omestring"
Edit
I misunderstood the question, thinking you were just removing the first element from the array where the array consisted of the characters that make up the string.
To split a string by a delimiter, look at the String.Split method instead. Some good examples are given here.
I have a string which consists of different fields. So what I want to do is get the different text and assign each of them into a field.
ex: Hello Allan IBM
so what I want to do is:
put these three words in different strings like
string Greeting = "Hello"
string Name = "Allan"
string Company = "IBM"
//all of it happening in a loop.
string data = "Hello Allan IBM"
string s = data[i].ToString();
string[] words = s.Split(',');
foreach (string word in words) {
Console.WriteLine(word);
}
any suggestions?
thanks hope to hear from you soon
If I understand correctly you have a string with place-holders and you want to put different string in those place-holders:
var format="{0}, {1} {2}. How are you?";
//string Greeting = "Hello"
//string Name = "Allan"
//string Company = "IBM"
//all of it happening in a loop.
string data = ...; //I think you have an array of strings separated by ,
foreach( va s in data){
{
//string s = data[i];//.ToString(); - it is already a string array
string[] words = data[i].Split(',');
Console.WriteLine(format, words[0], words[1], words[2]);
}
To me it sound not like a problem that can be solved with a loop. The essential problem is that the loop can only work if you do exactly the same operation on the items within the loop. If your problem doesn't fit, you end up with a dozen of lines of code within the loop to handle special cases, what could have been written in a shorter way without a loop.
If there are only two or three strings you have to set (what should be the case if you have named variables), assign them from the indexes of the split string. An alternative would be using regular expressions to match some patterns to make it more robust, if one of the expected strings is missing.
Another possibility would be to set attributes on members or properties like:
[MyParseAttribute(/*position*/ /*regex*/)]
string Greeting {get;set;}
And use reflexion to populate them. Here you could create a loop on all properties having that attribute, as it sounds to me that you are eager to create a loop :-)