Reputation: 3
I want to read file text. Save only numbers and the final letter to two-dimensional array. Line of the file (example):
[4; 5)|[1; 1,5)|B
static void read()
{
string[] lines = System.IO.File.ReadAllLines(@"C:\learning.txt");
int n = lines.Length;
string[ , ] tab = new string[n, 5];
int i = 0;
foreach (string line in lines)
{
Char[] znaki = { '[', ';', ')', '|', ' ' };
string[] names = line.Split(znaki);
// Console.WriteLine(names[1]+"\t"+names[3] + "\t" + names[6] + "\t" + names[8] + "\t" + names[10]);
tab[i, 0] = names[1];
tab[i, 1] = names[3];
tab[i, 2] = names[6];
tab[i, 3] = names[8];
tab[i, 4] = names[10];
i++;
}
Console.ReadKey();
}
I would like to have data separated in 5 columns and n lines (the file may be expanded in the future with new lines) but it always saves only the first line.Thanks
Upvotes: 0
Views: 78
Reputation: 5753
I am running your code and not seeing that it only saves one line as you experience. Something else is going on in that regard.
KreLou is absolutely right in pressing you to put the lines into a class instance. Otherwise, you loose type-safety, meaning many errors will arise at run-time as opposed to compile-time or design-time. It also lets users of your code (including yourself, later in time) understand the purpose of the object much more easily.
Again KreLou is right in that StreamReader is better than File.ReadAllLines, because the latter loads all lines into memory at once instead of just loading one line at a time.
However, I'm posting my own version for the following benefits:
Here's the class to hold each line of your file:
public class learnLine {
static Char[] delimiters = { '[', ';', ')', '|', ' ' };
public int num1 { get; set; }
public int num2 { get; set; }
public int num3 { get; set; }
public int num4 { get; set; }
public string letter { get; set; }
public learnLine (string line) {
string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
num1 = Convert.ToInt32(parts[0]);
num2 = Convert.ToInt32(parts[1]);
num3 = Convert.ToInt32(parts[2]);
num4 = Convert.ToInt32(parts[3].Substring(0,1)); // from your logic it seems like you only want the first?
letter = parts[4];
}
public override string ToString () =>
$"contents: {num1}|{num2}|{num3}|{num4}|{letter}";
}
Here's the function to read your lines:
IEnumerable<learnLine> read(string path) {
foreach (var line in File.ReadLines(path)) {
yield return new learnLine(line);
}
}
And here's how to use your function to output the results to the console:
IEnumerable<learnLine> lines = read(@"C:\learning.txt");
foreach(var line in lines) {
Console.WriteLine(line.ToString());
}
Upvotes: 0
Reputation: 125
Why not creating objects/dtos?
Create an object:
public class ElementDTO {
public int Number1 {get; set}
public int Number2 {get; set}
public int Number3 {get; set}
public int Number4 {get; set}
public char InputChar {get; set}
}
And read the file via StreamReader:
List<ElementDTO> list = new List<ElementDTO>();
using (StreamReader sr = new StreamReader("/path/to/file"){
string line;
while((line = sr.ReadLine()) != null) {
...//here your split code
ElementDTO element = new Element {
Number1 = ...;
Number2 = ...;
Number3 = ...;
Number4 = ...;
InputChar = ....;
};
list.add(element);
}
}
return list.ToArray();
Upvotes: 1