I'm having some trouble dealing with linebreaks here. Basically, the user puts in some data to a textbox that is then saved directly to the database.
When I display the data in my program, I only want to display the first line of the textbox, so I tried
Regex newLine = new Regex("/[\r\n]+/");
String[] lines = newLine.Split(row[data.textColumn.ColumnName].ToString());
SomeLabel.Text = lines[0];
But it display me all lines after another, so if the user puts in
a
b
c
The label displays
abc
How can I get this to work so it only displays the first line?
(I have added this in another answer because this answer is rather large and I think it will make this thread more clear - please leave a comment if I should make it one answer)
I have made this extension method which often have its uses:
public static IEnumerable<string> Lines(this string data)
{
using (var sr = new StringReader(data))
{
string line;
while ((line = sr.ReadLine()) != null)
yield return line;
}
}
And you can get the first line with:
var line = data.Lines().First();
This should be a lot faster than .Split when only a subset of the lines is used.
var data = row[data.textColumn.ColumnName].ToString();
And one of these (both work with unix and windows line-seperators). The first is fastest because it does not split every line when your only using the first.
int min = Math.Min(data.IndexOf("\r\n"), data.IndexOf("\n"));
string line;
if (min != -1)
line = data.Substring(0, min);
else
line = data;
or
var lines = data.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
var line = lines[0];
(See also a few extension methods I have posted here: How can I convert a string with newlines in it to separate lines?)
Related
I'm writing a small program that reads some people's firstname, surname, ID and email from an Excel sheet into the console, which isn't the problem, but instead of getting this output:
Poul EjnarRovsingpersomething#mail.com
ReneBach2014914something#mail.com
JohnJohnsson3950185something#mail.com
I want the output to be similar to this:
Poul Ejnar Rovsing per something#mail.com
Rene Bach 2014914 something#mail.com
John Johnsson 3950185 something#mail.com
The code I'm using is giving me this output, which is certainly a step in the right direction, but not quite what I'm looking for:
Poul Ejnar Rovsing per something#mail.com
Rene Bach 2014914 something#mail.com
John Johnsson 3950185 something#mail.com
And for some reason it's only outputting every other row instead of all of them, which is also puzzling me quite a bit. What am I missing here?
This is my code:
static void Main(string[] args)
{
string[] tokens;
char[] separators = {';'};
string str = "";
string newSeparator = " ";
FileStream fs = new FileStream(#"D:\Dokumenter\Skole\6. semester\GUI\Exercises\Exercise2\02 deltagerliste.csv", FileMode.Open);
StreamReader sr = new StreamReader(fs, Encoding.Default);
while ((str = sr.ReadLine()) != null)
{
str = sr.ReadLine();
tokens = str.Split(separators, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(tokens[0] + newSeparator + tokens[1] + newSeparator + tokens[2] + newSeparator + tokens[3]);
}
Console.ReadLine();
}
Fixed Width Outputs
For fixed width formatting, you can take advantage of composite formatting and alignments using String.Format. For example:
String.Format("{0,10}", "name"); // output blocks of 10 characters, right aligned
String.Format("{0,-10}", "name"); // output blocks of 10 characters, left aligned
Format strings are of the form: {index[,alignment][:formatString]}. To left align an item, use a negative value for alignment.
To use this in a composite format string, you just add more format placeholders in curly brackets, the index corresponds to the index of the argument in String.Format:
var sString = "name";
var anInt = 1;
var aDecimal = 1.23M;
var s = String.Format("|{0,10}|{1,10:0}|{2,10:0.00}|", sString, anInt, aDecimal);
Output:
| name| 1| 1.23|
Line skipping
And, it is skipping every other line as every time you iterate in the while loop, you read one line, then read again:
while ((str = sr.ReadLine()) != null) // <--- first read
{
str = sr.ReadLine(); // <--- second read replaces the first one
try a do loop with the while and the read at the end
str = sr.ReadLine();
do {
... do stuff here ...
} while ((str = sr.ReadLine()) != null);
You invoke the ReadLine twice, and you are skipping a row also use \t, this indent your output in tabs.
You are reading every other line because there are two calls to the StreamReader
while ((str = sr.ReadLine()) != null)
{
str = sr.ReadLine(); // Don't need this one!
...
The first call in the While statement will advance the reader one line. The second call will advance it again, overwriting what you previously just read.
To get the spacing correct you could use \t to insert tabs, but you would still need to do some math on the size of each token so you can use the correct number of tabs. Alternatively you could use String.PadRight to make each column a specific length.
What would be the best way to search a text file that looks like this..?
efee|| Nbr| Address| Name |Phone|City|State|Zip abc
||455|gsgd |first last|gsg |fef |jk |0393 gjgj||jfj|ddg
|first last|fht |ree |hn |th ...more lines...
I started by reading in the file and all its contexts with a streamreader
I was thinking to count the "|" and grab the text between the 5th and 6th using substring but i'm not sure how to do the count of the "|". Or if someone has a better idea I'm open to it.
Tried something like this:
StreamReader file = new StreamReader(#"...");
string line;
int num=0;
while ((line = file.ReadLine()) != null)
{
for (int i = 1; i <= 6; i++)
{
if (line.Contains("|"))
{
num++;
}
}
int start = line.IndexOf("|");
int end = line.IndexOf("|");
string result = line.Substring(start, end - start - 1);
}
The text I want I beleive is always between the 5th and 6th "|"
You can do it like this:
var res = File
.ReadLines(#"FileName.txt")
.Select(line => line.Split(new[]{'|'}, StringSplitOptions.None)[5])
.ToList();
This produces a List<strings> from the file, where each string is the part of the corresponding line of the file taken from between the fifth and the sixth '|' separator.
For a delimited file you should use a parser - there is one in the Microsoft.VisualBasic.FileIO namespace - the TextFieldParser class, though you could also look at third-party libraries like the popular FileHelpers.
A simpler approach would be to use string.Split on the | character and getting the value in the corresponding index of the returned string[], however, if any of the fields are escaped and can validly contain | internally, this will fail.
You could split each line into an array:
while ((line = file.ReadLine()) != null)
{
var values = line.Split('|');
}
This should work
string txt = File.ReadAllText("file.txt");
string res = Regex.Match(txt, "\\|*?{5}(.+?)\\|", RegexOptions.Singleline).Result("$1");
I'm trying to get the content of a textbox, and split it into an array, and then write each line into a file. It looks something like this:
string[] ban = Regex.Split(ImportText.Text, "\r\n");
foreach (string card in ban)
{
if (card != "")
{
string banlist = isoStorage.getSettings("banList");
banlist = "\r\n" + card + banlist;
isoStorage.changeSettings("banList", banlist);
}
ImportText.Text = "";
updateBanListView();
}
The problem is that textbox doesn't return a new line as \r\n. I've tried \n, \r\n, and even environment.newline. I'm using C# on WP7.
Any ideas on how to split my textbox into an array of lines?
For some reason, Windows Phone only uses a carraige return (\r) for a line split in TextBoxes. Two ways you could go about it are.
string[] ban = ImportText.Text.Split('\r');
But that may break if they decide to actually use \n in the future. I've seen another example here doing it this way:
List<string> ban = new List<string>();
string s;
while ((s = reader.ReadLine()) != null)
{
ban.Add(s);
}
Which feels a bit safter
I have a file created from a directory listing. From each of item a user selects from a ListBox, the application reads the directory and writes out a file that matches all the contents. Once that is done it goes through each item in the ListBox and copies out the item that matches the ListBox selection. Example:
Selecting 0001 matches:
0001456.txt
0001548.pdf.
The code i am using isn't handling 0s very well and is giving bad results.
var listItems = listBox1.Items.OfType<string>().ToArray();
var writers = new StreamWriter[listItems.Length];
for (int i = 0; i < listItems.Length; i++)
{
writers[i] = File.CreateText(
Path.Combine(destinationfolder, listItems[i] + "ANN.TXT"));
}
var reader = new StreamReader(File.OpenRead(masterdin + "\\" + "MasterANN.txt"));
string line;
while ((line = reader.ReadLine()) != null)
{
for (int i = 0; i < listItems.Length; i++)
{
if (line.StartsWith(listItems[i].Substring(0, listItems[i].Length - 1)))
writers[i].WriteLine(line);
}
}
Advice for correcting this?
Another Sample:
I have 00001 in my listbox: it returns these values:
00008771~63.txt
00002005~3.txt
00009992~1.txt
00001697~1.txt
00000001~1.txt
00009306~2.txt
00000577~1.txt
00001641~1.txt
00001647~1.txt
00001675~1.txt
00001670~1.txt
It should only return:
00001641~1.txt
00001647~1.txt
00001675~1.txt
00001670~1.txt
00001697~1.txt
Or if someone could just suggest a better method for taking each line in my listbox searching for line + "*" and whatever matches writes out a textfile...
This is all based pretty much on the one example you gave, but I believe the problem is that when you are performing your matching, you are getting the substring if your list item value and chopping off the last character.
In your sample you are attempting to match files starting with "00001", but when you do the match you are getting substring starting at zero and value.length-1 characters, which in this case would be "0000". For example:
string s = "00001";
Console.WriteLine(s.Substring(0,s.Length-1));
results in
0000
So I think if you just changed this line:
if (line.StartsWith(listItems[i].Substring(0, listItems[i].Length - 1)))
writers[i].WriteLine(line);
to this
if (line.StartsWith(listItems[i]))
writers[i].WriteLine(line);
you would be in good shape.
Sorry if I misunderstood your question, but let's start with this:
string line = String.Empty;
string selectedValue = "00001";
List<string> matched = new List<string>();
StreamReader reader = new StreamReader(Path.Combine(masterdin, "MasterANN.txt"));
while((line = reader.ReadLine()) != null)
{
if(line.StartsWith(selectedValue))
{
matched.Add(line);
}
}
This will match all lines from your MasterANN.txt file which begins with "00001" and add them into a collection (later we'll work on writing this into a file, if required).
This clarifies something?
var t1 = from line in File.ReadAllLines(#"alkahf.txt")
let item = line.Split(new string[] {". "}, StringSplitOptions.RemoveEmptyEntries)
let verse = line.Split(new string[] { "\n. " }, StringSplitOptions.RemoveEmptyEntries)
select new
{
Index = item,
Text = verse
};
having problems with above code im unsure how to parse the lines properly.
the format of the file is like so, I would also like to ignore any empty lines
StringSplitOptions.RemoveEmptyEntries doesn't work for some reason
1. This is text it might have numbers
2. I skipped a line
In the LINQ part, you are inside a single line, so you might want to exclude the empty lines first:
from line in File.ReadAllLines(#"alkahf.txt")
where !string.IsNullOrEmpty(line)
You then do two splits - one on newline, which is odd (since that won't be there, since we know we are reading lines). I expect you mean something like:
let parts = line.Split('.')
where parts.Length == 2
select new {
Index = parts[0],
Text = parts[1]
};
?
Also, note that ReadAllLines is a buffered operation; if you want true streaming, you might want something like:
public static IEnumerable<string> ReadLines(string path) {
using(var reader = File.OpenText(path)) {
string line;
while((line = reader.ReadLine()) != null) {
yield return line;
}
}
}
which is not buffering (you don't load the entire file at once). Just change the first line to:
from line in ReadLines(#"alkahf.txt")
Thanks to Marc's answer I fixed my issue. Sorry for the late response I'm working on this as a personal project.
The code is like so
var t1 = from line in StreamReaderExtension.ReadLinesFromFile(#"alkahf.txt")
let parts = line.Split(new string[]{". "},
StringSplitOptions.RemoveEmptyEntries)
where !string.IsNullOrEmpty(line)
&& int.Parse(parts[0].ToString()).ToString() != ""
select new
{
Index = parts[0],
Text = parts[1]
};
The int parse addition makes sure that the input is returning an integer, if you're using this code it's a good idea to set a flag in case it picks ups a non-integer or it will go unnoticed.