Super new to C# apologize upfront. My goal is to sort a given string. Each word in the string will contain a single number. This number is the position the word should have in the result. Numbers can be from 1 to 9. So 1 will be the first word (not 0).
My plan of attack is to split the string, having one variable of int data-type (int lookingForNum) and the other variable turning that into a String data-type(string stringLookingForNum), then for each loop over the array looking to see if any elements contain string stringLookingForNum, if they do I add it to an emptry string variable, lastly add 1 to int variable lookingForNum. My issue seems to be with the if statement with the Contains method. It will not trigger the way I currently have it written. Hard coding in if (word.Contains("1")) will trigger that code block but running it as written below will not trigger the if statement.Please can anyone tell my WHY!?!? I console.log stringLookingForNum and it is for sure a string data type "1"
This noobie would appreciate any help. Thanks!
string testA = "is2 Thi1s T4est 3a"; //--> "Thi1s is2 3a T4est"
string[] arrayTestA = testA.Split(' ');
string finalString = string.Empty;
int lookingForNum = 1; //Int32
foreach (string word in arrayTestA){
string stringLookingForNum = lookingForNum.ToString();
//Don't understand why Contains is not working as expected here)
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
}
lookingForNum++;
}
you need this - look for the string with 1, the look for the string with 2 etc. Thats not what you are doing
you look at the first string and see if it contains one
then look at the second one and see if it contains 2
....
int lookingForNum = 1;
while(true){ // till the end
string stringLookingForNum = lookingForNum.ToString();
bool found = false;
foreach (string word in arrayTestA){
if (word.Contains(stringLookingForNum)){
finalString = finalString + $"{word} ";
found = true;
break;
}
}
if(!found) break;
lookingForNum++;
}
To sort you should simply use OrderBy, and since you need to sort by number inside a word - just Find and extract a number from a string
string testA = "is2 Thi1s T4est 3a";
var result = testA.Split().OrderBy(word =>
Int32.Parse(Regex.Match(word, #"\d+").Value));
Console.WriteLine(string.Join(" ", result));
I want to get the value of the first white-space, from the right of a random string as below.
if my
1. string = "sdsd sdsd sdsd 3232323"
or
2. string = "sdsd sdsd dseee3232323"
or
3.string = "sdsd dseee3232323"
or
4.string = "sdsd dseee3232323"
output :
1. 3232323
2. dseee3232323
3. dseee3232323
4. dseee3232323
LastIndexOf method:
string s = "sdsd sdsd sdsd 3232323";
var result = s.Substring(s.LastIndexOf(' ') + 1);
Use Split and LastOrDefault, just like this:
var result = s.Split(' ').LastOrDefault();
Just don't forget to add the following to your using directives first:
using System.Linq;
Linq is not necessary.
String result = "";
String[] tempArray = workString.Split(' ');
if (tempArray.Length > 1)
String result = temparray[tempArray.Length-1];
Split into an array and look at the last element. I don't recommend using linq until you learn the basics.
Also I added a check to see if the result was invalid (no space). If you don't have a space, the other answers will return the entire string.
I've got string that looks like this. Every line is \r delimited, breaks placed here for visual purposes.
BEGIN_SECTIONS_INFORMATION
NUMSECTIONS=6
SECTION_GROUPNAME[1]=GROUP_1
SECTION_NAME[1]=foo
BEGIN_SECTION[1]
//blah...
END_SECTION[1]
SECTION_GROUPNAME[2]=GROUP_2
SECTION_NAME[2]=bazzz
BEGIN_SECTION[2]
//blah...
END_SECTION[2]
END_SECTIONS_INFORMATION
I need to split this string by SECTION_GROUPNAME into an IEnumerable<T> like this:
Index 0:
SECTION_GROUPNAME[1]=GROUP_1
SECTION_NAME[1]=foo
BEGIN_SECTION[1]
//blah...
END_SECTION[1]
Index 1:
SECTION_GROUPNAME[2]=GROUP_2
SECTION_NAME[2]=bazzz
BEGIN_SECTION[2]
//blah...
END_SECTION[2]
Rules:
Every section starts with SECTION_GROUPNAME[n].
Every section has a SECTION_NAME[n] and has an BEGIN_ and END_.
Section names are unique.
I have tried:
var sections = from line in sectionGroups
where line.StartsWith("SECTION_GROUPNAME")
group line by "SECTION_GROUPNAME";
Also tried
var sections = sectionGroups.Split(new string[] { "SECTION_GROUPNAME" }, StringSplitOptions.None);
From this post, OP created enums/list for groups. I can't do that as I don't know how many groups/sections will be in the string.
Assuming you want an IEnumerable<T> of strings that contain all the content you described without a key structure.
The basic idea is to remove the stuff that you don't want (the beginning and end bits), and then split by the start of your desired string. In the end, the split text doesn't make it into the array of results, so you have to manually add it back.
The following worked for me:
static string s = #"BEGIN_SECTIONS_INFORMATIONNUMSECTIONS=6SECTION_GROUPNAME[1]=GROUP_1SECTION_NAME[1] = foo\rBEGIN_SECTION[1]\rEND_SECTION[1]\rSECTION_GROUPNAME[2]=GROUP_2SECTION_NAME[2] = bazzzBEGIN_SECTION[2]END_SECTION[2]END_SECTIONS_INFORMATION";
static void Main(string[] args)
{
var withoutEnd = s.Split(new[] {"END_SECTIONS_INFORMATION"}, StringSplitOptions.RemoveEmptyEntries);
var SplitItems = withoutEnd[0].Split(new[] { "SECTION_GROUPNAME"}, StringSplitOptions.None).ToList();
SplitItems.RemoveAt(0); //the first part is just the introduction
var result = SplitItems.Select(x => "SECTION_GROUPNAME" + x);
}
I have a list of strings stored in an ArrayList. I want to split them by every occurrence of ';'. The problem is, whenever I try to display them using MessageBox, there's an excess space or unnecessary value that gets displayed.
Sample input (variable = a):
Arial;16 pt;None;None;None;None;None;None;FF0000;None;100;Normal;None;Normal;
Below is a line of code I used to split them:
string[] display_document = (a[0] + "").Split(';');
Code to display:
foreach (object doc_properties in display_document)
{
TextBox aa = new TextBox();
aa.Font = new Font(aa.Font.FontFamily, 9);
aa.Text = doc_properties.ToString();
aa.Location = new Point(pointX, pointY);
aa.Size = new System.Drawing.Size(80, 25);
aa.ReadOnly = true;
doc_panel.Controls.Add(aa);
doc_panel.Show();
pointY += 30;
}
The output that displays are the following:
How do I remove the last occurrence of that semicolon? I really need help fixing this. Thank you so much for all of your help.
Wouldnt It be easiest to check if the input ends with a ";" before splitting it, and if so remove the last character? Sample code:
string a = "Arial;16 pt;None;None;None;None;None;None;FF0000;None;100;Normal;None;Normal;";
if (a.EndsWith(";"))
{
a = a.Remove(a.LastIndexOf(";"));
}
//Proceed with split
Split will not print last semicolon if no space character is added and your input is a string.
I don't know why you prefer an array list (which probably is the reason of this strange behaviour) but if you could use your input as a string you could try that
string a = "Arial;16pt;None;None;None;None;None;None;FF0000;None;100;Normal;None;Normal;";
string[] display_document = a.Split(';');
foreach (object doc_properties in display_document)
{
//The rest of your code
}
I'm trying to read in a text file in a c# application, but I don't want to read the first two lines, or the last line. There's 8 lines in the file, so effectivly I just want to read in lines, 3, 4, 5, 6 and 7.
Is there any way to do this?
example file
_USE [Shelley's Other Database]
CREATE TABLE db.exmpcustomers(
fName varchar(100) NULL,
lName varchar(100) NULL,
dateOfBirth date NULL,
houseNumber int NULL,
streetName varchar(100) NULL
) ON [PRIMARY]_
EDIT
Okay, so, I've implemented Callum Rogers answer into my code and for some reason it works with my edited text file (I created a text file with the lines I didn't want to use omitted) and it does exactly what it should, but whenever I try it with the original text file (above) it throws an exception. I display this information in a DataGrid and I think that's where the exception is being thrown.
Any ideas?
The Answer by Rogers is good, I am just providing another way of doing this.
Try this,
List<string> list = new List<string>();
using (StreamReader reader = new StreamReader(FilePath))
{
string text = "";
while ((text = reader.ReadLine()) != null)
{
list.Add(text);
}
list.RemoveAt(0);
list.RemoveAt(0);
}
Hope this helps
Why do you want to ignore exactly the first two and the last line?
Depending on what your file looks like you might want to analyze the line, e.g. look at the first character whether it is a comment sign, or ignore everything until you find the first empty line, etc.
Sometimes, hardcoding "magic" numbers isn't such a good idea. What if the file format needs to be changed to contain 3 header lines?
As the other answers demonstrate: Nothing keeps you from doing what you ever want with a line you have read, so of course, you can ignore it, too.
Edit, now that you've provided an example of your file: For your case I'd definitely not use the hardcoded numbers approach. What if some day the SQL statement should contain another field, or if it appears on one instead of 8 lines?
My suggestion: Read in the whole string at once, then analyze it. Safest way would be to use a grammar, but if you presume the SQL statement is never going to be more complicated, you can use a regular expression (still much better than using line numbers etc.):
string content = File.ReadAllText(filename);
Regex r = new Regex(#"CREATE TABLE [^\(]+\((.*)\) ON");
string whatYouWant = r.Match(content).Groups[0].Value;
Why not just use File.ReadAllLines() and then remove the first 2 lines and the last line? With such a small file speed differences will not be noticeable.
string[] allLines = File.ReadAllLines("file.ext");
string[] linesWanted = new string[allLines.Length-3];
Array.Copy(allLines, 2, linesWanted, 0, allLines.Length-3);
If you have a TextReader object wrapping the filestream you could just call ReadLine() two times.
StreamReader inherits from TextReader, which is abstract.
Non-fool proof example:
using (var fs = new FileStream("blah", FileMode.Open))
using (var reader = new StreamReader(fs))
{
reader.ReadLine();
reader.ReadLine();
// Do stuff.
}
string filepath = #"C:\whatever.txt";
using (StreamReader rdr = new StreamReader(filepath))
{
rdr.ReadLine(); // ignore 1st line
rdr.ReadLine(); // ignore 2nd line
string fileContents = "";
while (true)
{
string line = rdr.ReadLine();
if (rdr.EndOfStream)
break; // finish without processing last line
fileContents += line + #"\r\n";
}
Console.WriteLine(fileContents);
}
How about a general solution?
To me, the first step is to enumerate over the lines of a file (already provided by ReadAllLines, but that has a performance cost due to populating an entire string[] array; there's also ReadLines, but that's only available as of .NET 4.0).
Implementing this is pretty trivial:
public static IEnumerable<string> EnumerateLines(this FileInfo file)
{
using (var reader = file.OpenText())
{
while (!reader.EndOfStream)
{
yield return reader.ReadLine();
}
}
}
The next step is to simply skip the first two lines of this enumerable sequence. This is straightforward using the Skip extension method.
The last step is to ignore the last line of the enumerable sequence. Here's one way you could implement this:
public static IEnumerable<T> IgnoreLast<T>(this IEnumerable<T> source, int ignoreCount)
{
if (ignoreCount < 0)
{
throw new ArgumentOutOfRangeException("ignoreCount");
}
var buffer = new Queue<T>();
foreach (T value in source)
{
if (buffer.Count < ignoreCount)
{
buffer.Enqueue(value);
continue;
}
T buffered = buffer.Dequeue();
buffer.Enqueue(value);
yield return buffered;
}
}
OK, then. Putting it all together, we have:
var file = new FileInfo(#"path\to\file.txt");
var lines = file.EnumerateLines().Skip(2).IgnoreLast(1);
Test input (contents of file):
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
This is line number 10.
Output (of Skip(2).IgnoreLast(1)):
This is line number 3.
This is line number 4.
This is line number 5.
This is line number 6.
This is line number 7.
This is line number 8.
This is line number 9.
You can do this:
var valid = new int[] { 3, 4, 5, 6, 7 };
var lines = File.ReadAllLines("file.txt").
Where((line, index) => valid.Contains(index + 1));
Or the opposite:
var invalid = new int[] { 1, 2, 8 };
var lines = File.ReadAllLines("file.txt").
Where((line, index) => !invalid.Contains(index + 1));
If you're looking for a general way to remove the last and the first 2, you can use this:
var allLines = File.ReadAllLines("file.txt");
var lines = allLines
.Take(allLines.Length - 1)
.Skip(2);
But from your example it seems that you're better off looking for the string pattern that you want to read from the file. Try using regexes.