I'm reading from a file with numbers and then when I try to convert it to an Int I get this error, System.FormatException: 'Input string was not in a correct format.' Reading the file works and I've tested all of that, it just seems to get stuck on this no matter what I try. This is what I've done so far:
StreamReader share_1 = new StreamReader("Share_1_256.txt");
string data_1 = share_1.ReadToEnd();
int intData1 = Int16.Parse(data_1);
And then if parse is in it doesn't print anything.
As we can see in your post, your input file contains not one number but several. So what you will need is to iterate through all lines of your file, then try the parsing for each lines of your string.
EDIT: The old code was using a external library. For raw C#, try:
using (StringReader reader = new StringReader(input))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Do something with the line
}
}
In addition, I encourage you to always parse string to number using the TryParse method, not the Parse one.
You can find some details and different implementations for that common problem in C#: C#: Looping through lines of multiline string
parser every single line
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
int intData1 = Int16.Parse(line);
}
You can simplify the code and get rid of StreamReader with a help of File class and Linq:
// Turn text file into IEnumerable<int>:
var data = File
.ReadLines("Share_1_256.txt")
.Select(line => int.Parse(line));
//TODO: add .OrderBy(item => item); if you want to sort items
// Loop over all numbers within file: 15, 1, 48, ..., 32
foreach (int item in data) {
//TODO: Put relevant code here, e.g. Console.WriteLine(item);
}
Related
I am making a number to music note value converter from text files and I am having trouble parsing text files in my C# code. The stream reader or parser seems to ignore every first line of text from different text files, I am learning from parsing CSV and assumed that I can parse text files the same way that I can parse CSV files. Here is my code:
static List<NoteColumns> ReadNoteValues(string fileName)
{
var allNotes = new List<NoteColumns>();
using (var reader = new StreamReader(fileName))
{
string line = "";
reader.ReadLine();
while ((line = reader.ReadLine()) != null)
{
string[] cols = line.Split('|');
var noteColumn = new NoteColumns();
if (line.StartsWith("-"))
{
continue;
}
double col;
if (double.TryParse(cols[0], out col))
{
noteColumn.QCol = col;
}
if (double.TryParse(cols[1], out col))
{
noteColumn.WCol = col;
}
}
}
return allNotes;
}
Here are the first 4 lines of one of my text file:
0.1|0.0|
0.0|0.1|
0.3|0.0|
0.1|0.0|
So every time that I have an output it will always skip the first line and move onto the next line. After it misses the first line it converts all the other values perfectly.
I have tried using a foreach loop but I end up getting an 'Index Out Of Range Exception'. Am I missing something/being stupid? Thanks for your time
You have a call to reader.ReadLine(); before your loop, which you don't assign to anything
It's because you have already added ReadLine() before the while loop which skips the first line
In order to avoid such errors (erroneous reader.ReadLine() in the beginning) get rid of Readers at all and query file with Linq (let .Net open and close the file, read it line after line and do all low level work for you):
using System.IO;
using System.Linq;
...
static List<NoteColumns> ReadNoteValues(string fileName) {
return File
.ReadLines(fileName)
.Where(line => !line.StartsWith('-'))
.Select(line => line.Split('|'))
.Select(cols => {
var noteColumn = new NoteColumns();
if (double.TryParse(cols[0], out var col))
noteColumn.QCol = col;
if (double.TryParse(cols[1], out var col))
noteColumn.WCol = col;
return noteColumn;
})
.ToList();
}
This is something that should be very simple. I just want to read numbers and words from a text file that consists of tokens separated by white space. How do you do this in C#? For example, in C++, the following code would work to read an integer, float, and word. I don't want to have to use a regex or write any special parsing code.
ifstream in("file.txt");
int int_val;
float float_val;
string string_val;
in >> int_val >> float_val >> string_val;
in.close();
Also, whenever a token is read, no more than one character beyond the token should be read in. This allows further file reading to depend on the value of the token that was read. As a concrete example, consider
string decider;
int size;
string name;
in >> decider;
if (decider == "name")
in >> name;
else if (decider == "size")
in >> size;
else if (!decider.empty() && decider[0] == '#')
read_remainder_of_line(in);
Parsing a binary PNM file is also a good example of why you would like to stop reading a file as soon as a full token is read in.
Brannon's answer explains how to read binary data. If you want to read text data, you should be reading strings and then parsing them - for which there are built-in methods, of course.
For example, to read a file with data:
10
10.5
hello
You might use:
using (TextReader reader = File.OpenText("test.txt"))
{
int x = int.Parse(reader.ReadLine());
double y = double.Parse(reader.ReadLine());
string z = reader.ReadLine();
}
Note that this has no error handling. In particular, it will throw an exception if the file doesn't exist, the first two lines have inappropriate data, or there are less than two lines. It will leave a value of null in z if the file only has two lines.
For a more robust solution which can fail more gracefully, you would want to check whether reader.ReadLine() returned null (indicating the end of the file) and use int.TryParse and double.TryParse instead of the Parse methods.
That's assuming there's a line separator between values. If you actually want to read a string like this:
10 10.5 hello
then the code would be very similar:
using (TextReader reader = File.OpenText("test.txt"))
{
string text = reader.ReadLine();
string[] bits = text.Split(' ');
int x = int.Parse(bits[0]);
double y = double.Parse(bits[1]);
string z = bits[2];
}
Again, you'd want to perform appropriate error detection and handling. Note that if the file really just consisted of a single line, you may want to use File.ReadAllText instead, to make it slightly simpler. There's also File.ReadAllLines which reads the whole file into a string array of lines.
EDIT: If you need to split by any whitespace, then you'd probably be best off reading the whole file with File.ReadAllText and then using a regular expression to split it. At that point I do wonder how you represent a string containing a space.
In my experience you generally know more about the format than this - whether there will be a line separator, or multiple values in the same line separated by spaces, etc.
I'd also add that mixed binary/text formats are generally unpleasant to deal with. Simple and efficient text handling tends to read into a buffer, which becomes problematic if there's binary data as well. If you need a text section in a binary file, it's generally best to include a length prefix so that just that piece of data can be decoded.
using (FileStream fs = File.OpenRead("file.txt"))
{
BinaryReader reader = new BinaryReader(fs);
int intVal = reader.ReadInt32();
float floatVal = reader.ReadSingle();
string stringVal = reader.ReadString();
}
I like using the StreamReader for quick and easy file access. Something like....
String file = "data_file.txt";
StreamReader dataStream = new StreamReader(file);
string datasample;
while ((datasample = dataStream.ReadLine()) != null)
{
// datasample has the current line of text - write it to the console.
Console.Writeline(datasample);
}
Not exactly the answer to your question, but just an idea to consider if you are new to C#: If you are using a custom text file to read some configuration parameters, you might want to check XML serialization topics in .NET.
XML serialization provides a simple way to write and read XML formatted files. For example, if you have a configuration class like this:
public class Configuration
{
public int intVal { get; set; }
public float floatVal { get; set; }
public string stringVal { get; set; }
}
you can simply save it and load it using the XmlSerializer class:
public void Save(Configuration config, string fileName)
{
XmlSerializer xml = new XmlSerializer(typeof(Configuration));
using (StreamWriter sw = new StreamWriter(fileName))
{
xml.Serialize(sw, config);
}
}
public Configuration Load(string fileName)
{
XmlSerializer xml = new XmlSerializer(typeof(Configuration));
using (StreamReader sr = new StreamReader(fileName))
{
return (Configuration)xml.Deserialize(sr);
}
}
Save method as defined above will create a file with the following contents:
<Configuration>
<intVal>0</intVal>
<floatVal>0.0</floatVal>
<stringVal></stringVal>
</Configuration>
Good thing about this approach is that you don't need to change the Save and Load methods if your Configuration class changes.
C# doesn't seem to have formatted stream readers like C++ (I would be happy to be corrected). So Jon Skeet approach of reading the contents as string and parsing them to the desired type would be the best.
Try someting like this:
http://stevedonovan.blogspot.com/2005/04/reading-numbers-from-file-in-c.html
IMHO Maybe to read a c# tutorial it will be really useful to have the whole picture in mind before asking
Here is my code to read numbers from the text file. It demonstrates the concept of reading numbers from text file "2 3 5 7 ..."
public class NumberReader
{
StreamReader reader;
public NumberReader(StreamReader reader)
{
this.reader = reader;
}
public UInt64 ReadUInt64()
{
UInt64 result = 0;
while (!reader.EndOfStream)
{
int c = reader.Read();
if (char.IsDigit((char) c))
{
result = 10 * result + (UInt64) (c - '0');
}
else
{
break;
}
}
return result;
}
}
Here is sample code to use this class:
using (StreamReader reader = File.OpenText("numbers.txt"))
{
NumberReader numbers = new NumberReader(reader);
while (! reader.EndOfStream)
{
ulong lastNumber = numbers.ReadUInt64();
}
}
I am reading a CSV file and want to read it line by line. The code below does not have any error but when execute the code it reads from middle of the CSV, it just prints last four lines of CSV but i need the whole CSV data as output. please assist what i an missing in my code
I want to achieve this using streamreader only and not parser.
using (StreamReader rd = new StreamReader(#"C:\Test.csv"))
{
while (!rd.EndOfStream)
{
String[] value = null;
string splits = rd.ReadLine();
value = splits.Split(',');
foreach (var test in value)
{
Console.WriteLine(test);
}
}
}
Test.csv
TEST Value ,13:00,,,14:00,,,15:00,,, "Location","Time1","Transaction1","Transaction2","Tim2", "Pune","1.07","-","-","0.99", "Mumbai","0.55","-","-","0.59", "Delhi","1.00","-","-","1.08", "Chennai","0.52","-","-","0.50",
There is already a stack overflow article about this.
Also, the article provides a much better way to do this same:
using (TextFieldParser parser = new TextFieldParser(#"c:\test.csv"))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
//Processing row
string[] fields = parser.ReadFields();
foreach (string field in fields)
{
//TODO: Process field
}
}
}
I believe there is something wrong with your CSV file, it may contain some unexpected characters.Several things you can try:
You can let StreamReader class to detect correct encoding of your CSV
new StreamReader(#"C:\Test.csv", System.Text.Encoding.Default, true)
You can force your StreamReader class to read your CSV from the beginning.
rd.DiscardBufferedData();
rd.BaseStream.Seek(0, SeekOrigin.Begin);
rd.BaseStream.Position = 0;
You can try to fix your CSV file, such as clean null character and Convert Unix newline to Windows newline.
I've been noticing that the following segment of code does not scale well for large files (I think that appending to the paneContent string is slow):
string paneContent = String.Empty;
bool lineFound = false;
foreach (string line in File.ReadAllLines(path))
{
if (line.Contains(tag))
{
lineFound = !lineFound;
}
else
{
if (lineFound)
{
paneContent += line;
}
}
}
using (TextReader reader = new StringReader(paneContent))
{
data = (PaneData)(serializer.Deserialize(reader));
}
What's the best way to speed this all up? I have a file that looks like this (so I wanna get all the content in between the two different tags and then deserialize all that content):
A line with some tag
A line with content I want to get into a single stream or string
A line with content I want to get into a single stream or string
A line with content I want to get into a single stream or string
A line with content I want to get into a single stream or string
A line with content I want to get into a single stream or string
A line with some tag
Note: These tags are not XML tags.
You could use a StringBuilder as opposed to a string, that is what the StringBuilder is for. Some example code is below:
var paneContent = new StringBuilder();
bool lineFound = false;
foreach (string line in File.ReadLines(path))
{
if (line.Contains(tag))
{
lineFound = !lineFound;
}
else
{
if (lineFound)
{
paneContent.Append(line);
}
}
}
using (TextReader reader = new StringReader(paneContent.ToString()))
{
data = (PaneData)(serializer.Deserialize(reader));
}
As mentioned in this answer, a StringBuilder is preferred to a string when you are concatenating in a loop, which is the case here.
Here is an example of how to use groups with regexes and retrieve their contents afterwards.
What you want is a regex that will match your tags, label this as a group then retrieve the data of the group as in the example
Use a StringBuilder to build your data string (paneContent). It's much faster because concatenating strings results in new memory allocations. StringBuilder pre-allocates memory (if you expect large data strings, you can customize the initial allocation).
It's a good idea to read your input file line-by-line so you can avoid loading the whole file into memory if you expect files with many lines of text.
How to search the keywords in logfile using c#.net.
I had a log file which has some information preceded by a key word like ipaddress, userid etc., I need to parse the log file and get the data and show in grid view.
any suggetions in c#
Thank you,
jagadeesh kumar.
I don't know which format the file has exactly, but I would suggest you to use a StreamReader to read the file, then split it at \n and then process every single line...
This would then look somthing like this (not tested):
string wholeFile = "";
using(StreamReader str = new StreamReader(path))
{
wholeFile = str.ReadToEnd();
}
string[] lines = wholeFile.Split('\n').Replace("\r", "");
for(int i = 0; i < lines.Length; i++)
{
//parse the line
string line = lines[i];
if(line.Trim().StartsWith("ipaddress"))
{
string value = line.Trim().Replace("ipaddress", "");
//Do something with the value here...
}
}
You could also consider using RegExp to parse the file or even every line.
Good luck, Alex
Use a reader to read the file, and then a regexp on each line to find what you want..
var reader = new StreamReader("path/to/file");
string line;
while ((line = reader.ReadLine()) != null)
{
//parse the line here.
}
See the tutorial about regular expressions from Microsoft. Without seeing the format of the file it's not possible to give a more specific answer.