Click here to Skip to main content
15,904,652 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello I been working on a project that involves reading data from several txt files in several folders. The txt files contain data mostly numbers for example;

test.txt
1001 1200 1300 1400 1500
1400 7100 6500 8500 6000
5000 3000 4000 5000 2000
6000 2200 6333 0000 0000
...

I can read this particular file and divide it into arrays so I can do calculations for every single column with the following code;

C#
List<Double> List1 = new List<Double>();
List<Double> List2 = new List<Double>();
.....

string path = @"H:\test";
string searchPattern = "*.txt";
string[] filePaths = Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories);

for (int x = 0; x < filePaths.Length; x++)
{

    StreamReader file = new System.IO.StreamReader(filePaths[x]);
    string line = file.ReadLine();
    while ((line = file.ReadLine()) != null)
    {
        string[] data = line.Split(' ');
        List1.Add(Convert.ToDouble(data[0]));
        List2.Add(Convert.ToDouble(data[1]));
        ....

    }
    Double[] L1Array = List1.ToArray();
    Double[] L2Array = List2.ToArray();
    ...


This part of code works very well and gets me what I want but when I try to get data from a different file that is not only digits but letters with the same code as above for example;

test2.txt
Name = Marc
Surname = Lauren
Gender = Male
...
ID = 123456789

where I been trying to get only ID value (123466789) into an Array I keep encountering the error;

An unhandled exception of type 'System.FormatException' occurred in mscorlib.dll

Additional information: String must be exactly one character long.

I also tried changing the code as following;

StreamReader file = new System.IO.StreamReader(filePaths[x]);
string line = file.ReadLine();
while ((line = file.ReadLine()) != null)
{
char[] delimiters = new char[] { '\r', '\n', ' ', '='};
string[] data = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);


I am not very good in c# and couldn't find a way around it.

I would be Glad if you could help me out.
Thank you
Posted
Updated 17-May-15 11:05am
v3
Comments
FrostedSyntax 17-May-15 18:41pm    
Would using Regex be a viable solution to getting just the id number? Something like "\d{9}". Or at least using the Split method in the Regex class instead of in the string class like: new Regex(@"[\s=]").Split(line);
Sergey Alexandrovich Kryukov 17-May-15 19:57pm    
In what line, with what data?
—SA

1 solution

Not clear why would you use such primitive data format…

But the solution of the problem is simple: just write the code accurately. Use the debugger and accurate approaches. Your code shown many problems related to lack of neatness.

First, you don't dispose your instances of the StreamReader. This is the correct pattern:
C#
using (StreamReader reader = new System.IO.StreamReader(filePaths[index])) {
   string line = reader.ReadLine();
   //...
} // reader.Dispose is automatically called here

Makes sure you know all types implementing the interface System.IDisposable and make sure you call Dispose, via the using statement (not to be confused with using directive) or not:
https://msdn.microsoft.com/en-us/library/system.idisposable%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/yh598w02.aspx[^].

Don't use variable/type/member names line <codex>x (I renamed it to <code>index.) Use semantically sensitive names, in correct English spelling, without abbreviations.

Don't hard-code immediate constants like strings '\r', '\n', ' ', '='. Explicitly define constants or <code>readonly static members; in other cases, use the resources.

Now, if you read the whole file using reader.ReadLine(), you never need '\r', '\n'. Just know how your file is generated and use exact delimiters which can be there.

Two big mistakes are in the lines like List1.Add(Convert.ToDouble(data[0]));. Again, never use bad names line List1. Don't hard-code 0, 1, etc. Instead, use the number of element in the array returned by string.Split and use the loop. And finally, don't use Convert.ToDouble. This is what it is: parsing, not "conversion". Please understand that parsing can be successful or failed. Instead, use double.TryParse: https://msdn.microsoft.com/en-us/library/system.double.tryparse%28v=vs.110%29.aspx[^].

And so on…

When you rewrite your code in a neat way, if you still have any concerns about runtime, try to debug it using the debugger. Anyway, CodeProject questions on some exception without finding out what's going wrong under the debugger makes little sense…

—SA
 
Share this answer
 
v2
Comments
Yol_Gezer 17-May-15 20:50pm    
Hello Sergey,

As I said I am not that good in c# yet and the code above is just to make every one understand what I engage with. As you suggested I changed the code structure as ;

using (StreamReader reader = new System.IO.StreamReader(filePaths[index]))
{
string line = reader.ReadLine();
string[] data = line.Split(' ');
....
}

but how should I continue. I mean to save the split values into a list and I didn't get the usage of double.TryParse right.
Sergey Alexandrovich Kryukov 17-May-15 21:19pm    
Just continue. You are making some progress; as I said in first place it's all about neat code; but that said, you are not doing anything fundamentally wrong. What's the problem with TryParse? If there is any, read the help page. Create list(s) and add elements to them one by one. What's the problem with it? And so on...
—SA
Yol_Gezer 17-May-15 23:00pm    
using (StreamReader reader = new System.IO.StreamReader(filePaths[index]))
{
string line = reader.ReadLine();
string[] data = line.Split(' ');
.....
UserID.Add(Double.TryParse(data[10]));

I am trying it this way but still getting erros is my approach wrong or do I still make some mistakes?

Because no matter what I changed data[1] comes out as either Name or Marc, data[2] does not even get a value from the reading
Sergey Alexandrovich Kryukov 17-May-15 23:32pm    
Now, don't use data[10], ever. 10 is hard-coded. Use
for (int columnIndex = 0; columnIndex < data.Length; ++columnIndex) {
// and here, use, data[columnIndex]
// isn't it obvious?!
}

—SA
Yol_Gezer 17-May-15 23:58pm    
Thank you a lot for all the information I really appreciate it. But Maybe I couldn't explain myself clearly.

If my example date is like;

1000 2000 3000 4000
1000 2000 3000 4000
1000 2000 3000 4000

I want to read them and list them by column,
List 1 will have 1000 1000 1000
List 2 will have 2000 2000 2000
List 3 will have 3000 3000 3000
List 4 will have 4000 4000 4000

Thats why I use data[10] or etc so I will get specific values in specific lists. than I transfer all the lists into separate arrays. The First Code in my question does this. But on a second different file I have values like;

[user]
Name = Marc
Surname = Freed
Gender = Male
Age = 23
ID = 123456789

My Problem is that I want to assign the ID value only (123456789) to a list so I can pass that list as array and continue to work with it.

PS: I have files for each user that include their unique ID

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900