I am trying to read from each line in a file and grab specific strings and integers. However the values of the found integers are not added up at the end and i'm unsure why. I apologize if this is a simple error.
If a line in the file contains "Event Type: Music", store "Music" in the EventType[] array using MusicTrace. Music trace begins at 0 and increments each time the string above is found. So it works its way down the array. the array size is the amount of lines in the file to ensure there is always enough array space.
I have another Array for attendance named EventAttendance[] which does the same steps above, but cuts the first 18 characters from the found line giving the remaining number (the line in the file is a fixed length). AttendanceTrace is used in the same manner a the above MusicTrace.
I then have a loop for the EventAttendance array which uses i and starts at 0 and carries out code until the EventAttendance.Length property is reached. The code adds up the total attendance from each EventAttendance[] index using i
The code is below:
private void frmActivitiesSummary_Load(object sender, EventArgs e)
{
if (File.Exists(sVenueName.ToString() + ".txt"))
{
using (StreamReader RetrieveEvents = new StreamReader(sVenueName.ToString() + ".txt")) //Create a new file with the name of the username variable
{
string[] ReadLines = File.ReadAllLines(sVenueName + ".txt"); //Read File
int MusicTrace = 0;
int AttendanceTrace = 0;
string[] EventType = new string[ReadLines.Length]; //Store found event types
int[] EventAttendance = new int[ReadLines.Length]; //Store Event Attendance
string line; //Declare String to store line
using (StreamReader file = new StreamReader(sVenueName + ".txt")) //Using StreamReader
{
while (!file.EndOfStream)
{
line = file.ReadToEnd();
//Get All Music Event to Array
if (line.Contains("Event Type: Music"))
{
EventType[MusicTrace] = "Music"; //[0] = Music
if (MusicTrace != 0)
MusicTrace = MusicTrace + 1;
else
MusicTrace = 1;
}
//Get All attendances to Array
if (line.Contains("People Attending:"))
{
line.Remove(0, 18);
int ConvertedLine = Convert.ToInt32(line);
EventAttendance[AttendanceTrace] = ConvertedLine; //[0] = 10
if (AttendanceTrace != 0)
AttendanceTrace = AttendanceTrace + 1;
else
AttendanceTrace = 1;
}
}
}
//for each array index and if array index contains music, add this to total amount of music events
for (int i = 0; i <= EventAttendance.Length; i++)
{
if (EventAttendance[i] > 0)
{
if (iMusicAttendance > 0)
iMusicAttendance = iMusicAttendance + EventAttendance[i];
else
iMusicAttendance = EventAttendance[i];
}
}
}
}
}
The Attendance is then show on the click on a button:
private void btnShow_Click(object sender, EventArgs e)
{
lblMusicOutput.Text = "After analysis, we can see that Music Events have a total attendance of " + iMusicAttendance;
lblArtOutput.Text = "After Analysis, we can see that Events have a total Attenance of " + iArtAttendance;
lblDance.Text = "After Analysis, we can see that Dance Events have a total Attenance of " + iDanceAttendance;
lblTheatreOutput.Text = "After Analysis, we can see that Theatre Events have a total Attenance of " + iTheatreAttendance;
}
There where a several useless variables inside your code, that I took the liberty to remove. I also changed arrays for List<T> in order to use Linq.
You were adding a Convert.ToIn32 with the full line, because String.Remove() doesn't change the object it's called on but return a new string that you have to assign to something : line = line.Remove(0, 18);
Also, you were doing useless checks for the counters:
if (MusicTrace != 0)
MusicTrace = MusicTrace + 1;
else
MusicTrace = 1;
is the same than
MusicTrace++;
which leads us to:
if (!File.Exists(sVenueName.ToString() + ".txt"))
return;
List<String> EventType = new List<string>(); //Store found event types
List<int> EventAttendance = new List<int>(); //Store Event Attendance
using (StreamReader file = new StreamReader(sVenueName + ".txt")) //Using StreamReader
{
while (!file.EndOfStream)
{
var line = file.ReadLine(); //Declare String to store line
//Get All Music Event to Array
if (line.Contains("Event Type: Music"))
{
EventType.Add("Music"); //[0] = Music
}
//Get All attendances to Array
if (line.Contains("People Attending:"))
{
line = line.Remove(0, 18);
EventAttendance.Add(Convert.ToInt32(line)); //[0] = 10
}
}
}
//for each array index and if array index contains music, add this to total amount of music events
iMusicAttendance = EventAttendance.Sum();
Please change :
while (!file.EndOfStream)
{
line = file.ReadToEnd();
to
while (!file.EndOfStream)
{
line = file.ReadLine();
explanation:
You are reading the entire file at once, then you check once your two conditions. But you want to read line by line. So you need to use ReadLine.
As for the rest, you declare but never use the StreamReader RetrieveEvents. You can get rid of it.
You can use List<T> to store the read information. This way you get more flexibility into your code. And the Sum can be calculated without a loop.
EDIT:
I took the liberty to cut down your programm a little. The Code below should do exactly what you describe in your post:
string[] allLines = File.ReadAllLines(sVenueName + ".txt");
List<string> EventType = allLines.Where(x => x.Contains("Event Type: Music"))
.Select(x => x = "Music").ToList();
List<int> EventAttendance = allLines.Where(x => x.Contains("People Attending:"))
.Select(x => Convert.ToInt32(x.Remove(0,18))).ToList();
int iMusicAttendance = EventAttendance.Sum();
EDIT2:
seeing your file content it becomes obvious that you want only to sum up the attending people of the music event, but in your approach you sum up all attending people of all event.
Looking at your file it seems you have an offset of 3 lines. So I would suggest, to get all indices of the Music lines and then grab only the numbers that are 3 lines further:
List<string> allLines = File.ReadAllLines("input.txt").ToList();
List<int> indices = Enumerable.Range(0, allLines.Count)
.Where(index => allLines[index].Contains("Event Type: Music"))
.Select(x => x+=3).ToList();
List<int> EventAttendance = allLines.Where(x => indices.Contains(allLines.IndexOf(x))).Select(x => Convert.ToInt32(x.Remove(0,18))).ToList();
int iMusicAttendance = EventAttendance.Sum();
This will get you the sum of only the music people ;) hop it helps.
Related
I have a text file that is divided up into many sections, each about 10 or so lines long. I'm reading in the file using File.ReadAllLines into an array, one line per element of the array, and I'm then I'm trying to parse each section of the file to bring back just some of the data. I'm storing the results in a list, and hoping to export the list to csv ultimately.
My for loop is giving me trouble, as it loops through the right amount of times, but only pulls the data from the first section of the text file each time rather than pulling the data from the first section and then moving on and pulling the data from the next section. I'm sure I'm doing something wrong either in my for loop or for each loop. Any clues to help me solve this would be much appreciated! Thanks
David
My code so far:
namespace ParseAndExport
{
class Program
{
static readonly string sourcefile = #"Path";
static void Main(string[] args)
{
string[] readInLines = File.ReadAllLines(sourcefile);
int counter = 0;
int holderCPStart = counter + 3;//Changed Paths will be an different number of lines each time, but will always start 3 lines after the startDiv
/*Need to find the start of the section and the end of the section and parse the bit in between.
* Also need to identify the blank line that occurs in each section as it is essentially a divider too.*/
int startDiv = Array.FindIndex(readInLines, counter, hyphens72);
int blankLine = Array.FindIndex(readInLines, startDiv, emptyElement);
int endDiv = Array.FindIndex(readInLines, counter + 1, hyphens72);
List<string> results = new List<string>();
//Test to see if FindIndexes work. Results should be 0, 7, 9 for 1st section of sourcefile
/*Console.WriteLine(startDiv);
Console.WriteLine(blankLine);
Console.WriteLine(endDiv);*/
//Check how long the file is so that for testing we know how long the while loop should run for
//Console.WriteLine(readInLines.Length);
//sourcefile has 5255 lines (elements) in the array
for (int i = 0; i <= readInLines.Length; i++)
{
if (i == startDiv)
{
results = (readInLines[i + 1].Split('|').Select(p => p.Trim()).ToList());
string holderCP = string.Join(Environment.NewLine, readInLines, holderCPStart, (blankLine - holderCPStart - 1)).Trim();
results.Add(holderCP);
string comment = string.Join(" ", readInLines, blankLine + 1, (endDiv - (blankLine + 1)));//in case the comment is more than one line long
results.Add(comment);
i = i + 1;
}
else
{
i = i + 1;
}
foreach (string result in results)
{
Console.WriteLine(result);
}
//csvcontent.AppendLine("Revision Number, Author, Date, Time, Count of Lines, Changed Paths, Comments");
/* foreach (string result in results)
{
for (int x = 0; x <= results.Count(); x++)
{
StringBuilder csvcontent = new StringBuilder();
csvcontent.AppendLine(results[x] + "," + results[x + 1] + "," + results[x + 2] + "," + results[x + 3] + "," + results[x + 4] + "," + results[x + 5]);
x = x + 6;
string csvpath = #"addressforcsvfile";
File.AppendAllText(csvpath, csvcontent.ToString());
}
}*/
}
Console.ReadKey();
}
private static bool hyphens72(String h)
{
if (h == "------------------------------------------------------------------------")
{
return true;
}
else
{
return false;
}
}
private static bool emptyElement(String ee)
{
if (ee == "")
{
return true;
}
else
{
return false;
}
}
}
}
It looks like you are trying to grab all of the lines in a file that are not "------" and put them into a list of strings.
You can try this:
var lineswithoutdashes = readInLines.Where(x => x != hyphens72).Select(x => x).ToList();
Now you can take this list and do the split with a '|' to extract the fields you wanted
The logic seems wrong. There are issues with the code in itself also. I am unsure what precisely you're trying to do. Anyway, a few hints that I hope will help:
The if (i == startDiv) checks to see if I equals startDiv. I assume the logic that happens when this condition is met, is what you refer to as "pulls the data from the first section". That's correct, given you only run this code when I equals startDiv.
You increase the counter I inside the for loop, which in itself also increases the counter i.
If the issue in 2. wouldn't exists then I'd suggest to not do the same operation "i = i + 1" in both the true and false conditions of the if (i == startDiv).
Given I assume this file might actually be massive, it's probably a good idea to not store it in memory, but just read the file line by line and process line by line. There's currently no obvious reason why you'd want to consume this amount of memory, unless it's because of the convenience of this API "File.ReadAllLines(sourcefile)". I wouldn't be too scared to read the file like this:
Try (BufferedReader br = new BufferedReader(new FileReader (file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
}
You can skip the lines until you've passed where the line equals hyphens72.
Then for each line, you process the line with the code you provided in the true case of (i == startDiv), or at least, from what you described, this is what I assume you are trying to do.
int startDiv will return the line number that contains hyphens72.
So your current for loop will only copy to results for the single line that matches the calculated line number.
I guess you want to search the postion of startDiv in the current line?
const string hyphens72;
// loop over lines
for (var lineNumber = 0; lineNumber <= readInLines.Length; lineNumber++) {
string currentLine = readInLines[lineNumber];
int startDiv = currentLine.IndexOf(hyphens72);
// loop over characters in line
for (var charIndex = 0; charIndex < currentLine.Length; charIndex++) {
if (charIndex == startDiv) {
var currentCharacter = currentLine[charIndex];
// write to result ...
}
else {
continue; // skip this character
}
}
}
There are a several things which could be improved.
I would use ReadLines over File.ReadAllLines( because ReadAllLines reads all the lines at ones. ReadLines will stream it.
With the line results = (readInLines[i + 1].Split('|').Select(p => p.Trim()).ToList()); you're overwriting the previous results list. You'd better use results.AddRange() to add new results.
for (int i = 0; i <= readInLines.Length; i++) means when the length = 10 it will do 11 iterations. (1 too many) (remove the =)
Array.FindIndex(readInLines, counter, hyphens72); will do a scan. On large files it will take ages to completely read them and search in it. Try to touch a single line only ones.
I cannot test what you are doing, but here's a hint:
IEnumerable<string> readInLines = File.ReadLines(sourcefile);
bool started = false;
List<string> results = new List<string>();
foreach(var line in readInLines)
{
// skip empty lines
if(emptyElement(line))
continue;
// when dashes are found, flip a boolean to activate the reading mode.
if(hyphens72(line))
{
// flip state.. (start/end)
started != started;
}
if(started)
{
// I don't know what you are doing here precisely, do what you gotta do. ;-)
results.AddRange((line.Split('|').Select(p => p.Trim()).ToList()));
string holderCP = string.Join(Environment.NewLine, readInLines, holderCPStart, (blankLine - holderCPStart - 1)).Trim();
results.Add(holderCP);
string comment = string.Join(" ", readInLines, blankLine + 1, (endDiv - (blankLine + 1)));//in case the comment is more than one line long
results.Add(comment);
}
}
foreach (string result in results)
{
Console.WriteLine(result);
}
You might want to start with a class like this. I don't know whether each section begins with a row of hyphens, or if it's just in between. This should handle either scenario.
What this is going to do is take your giant list of strings (the lines in the file) and break it into chunks - each chunk is a set of lines (10 or so lines, according to your OP.)
The reason is that it's unnecessarily complicated to try to read the file, looking for the hyphens, and process the contents of the file at the same time. Instead, one class takes the input and breaks it into chunks. That's all it does.
Another class might read the file and pass its contents to this class to break them up. Then the output is the individual chunks of text.
Another class can then process those individual sections of 10 or so lines without having to worry about hyphens or what separates on chunk from another.
Now that each of these classes is doing its own thing, it's easier to write unit tests for each of them separately. You can test that your "processing" class receives an array of 10 or so lines and does whatever it's supposed to do with them.
public class TextSectionsParser
{
private readonly string _delimiter;
public TextSectionsParser(string delimiter)
{
_delimiter = delimiter;
}
public IEnumerable<IEnumerable<string>> ParseSections(IEnumerable<string> lines)
{
var result = new List<List<string>>();
var currentList = new List<string>();
foreach (var line in lines)
{
if (line == _delimiter)
{
if(currentList.Any())
result.Add(currentList);
currentList = new List<string>();
}
else
{
currentList.Add(line);
}
}
if (currentList.Any() && !result.Contains(currentList))
{
result.Add(currentList);
}
return result;
}
}
This question already has answers here:
C# parsing a text file and storing the values in an array
(3 answers)
Closed 5 years ago.
I am trying to store values in an array from reading from a file. I have the reading from a file part but I can't get it to store in an array because it gives me an error "Value cannot be null" because after the loop the value of my variable becomes null and the array cannot be null. Here's what I have. And I realize that the for loop probably isn't in the correct spot so any help with where to put it would be great.
Program p = new Program();
int MAX = 50;
int[] grades = new int[MAX];
string environment = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "\\";
string path = environment + "grades.txt";
StreamReader myFile = new StreamReader(path);
string input;
int count = 0;
do
{
input = myFile.ReadLine();
if (input != null)
{
WriteLine(input);
count++;
}
} while (input != null);
for (int i = 0; i < count; i++)
{
grades[i] = int.Parse(input);
}
You start the for loop just after exiting from the while loop. And the condition to exit from the while loop is true when input is null. Of course this is not well accepted by Int.Parse.
Instead you can use a single loop, taking in consideration that you don't want to loop more than 50 times otherwise you exceed the array dimensions
int count = 0;
while((input = myFile.ReadLine()) != null && count < 50)
{
WriteLine(input);
grades[count] = int.Parse(input);
count++;
}
However you can have a more flexible way to handle your input if you use a List<int> instead of an array of integers. In this way you don't have to check for the number of lines present in your file
List<int> grades = new List<int>();
while((input = myFile.ReadLine()) != null)
grades.Add(int.Parse(input));
if we want to get really condensed
var grades = File.ReadAllLines(path).Select(l=>Int.Parse(l)).ToArray();
Utilize the Path.Combine() to help you in concatenating paths.
string environment = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
String fullPath = Path.Combine(environment, "grades.txt");
int[] grades = File.ReadAllLines(fullPath).Select(p => int.Parse(p)).ToArray<int>();
Console.WriteLine(grades);
Refer to https://www.dotnetperls.com/file-readalllines on how to use File.ReadAllLines() its very handy.
I'm using LINQ here, which sometimes simplifies things. Even though it looks a bit intimidating now. We read all lines, the result of that is then parsed by selecting each one and converting it to an integer then outputting an array of integers and saving that to grades.
Program p = new Program();
int MAX = 50;
int[] grades = new int[MAX];
string environment = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "\\";
string path = environment + "grades.txt";
using (StreamReader myFile = new StreamReader(path))
{
string input;
int count = 0;
while((!myFile.EndOfStream) && (count < MAX))
{
input = myFile.ReadLine();
if (!String.IsNullOrWhiteSpace(input))
{
WriteLine(input);
grades[count] = int.Parse(input);
count++;
}
}
}
You should definitely use the "using" pattern around your stream object. Got rid of the for-loop for you while maintaining mostly your code and style. Your issue was that you weren't using the input value before moving on to the next line. You only ever had the last value in your original code.
I am creating an application to read and display Pokemon stats. Currently, I have 6 txt files, one for each stat. I have 6 arrays reading each txt file and displaying each stat in a label.
I want to condense this information into a single text file, splitting each stat by a " " to keep each Pokemon's data on a single line.
Current code if it helps explain the idea better:
using System;
using System.Windows.Forms;
using System.IO;
namespace Pokedex
{
public partial class Pokedex : Form
{
public Pokedex()
{
InitializeComponent();
}
//Read stat data from text files into string arrays
string[] HP = File.ReadAllLines("HP.txt");
string[] Atk = File.ReadAllLines("Atk.txt");
string[] Def = File.ReadAllLines("Def.txt");
string[] SpAtk = File.ReadAllLines("SpAtk.txt");
string[] SpDef = File.ReadAllLines("SpDef.txt");
string[] Spe = File.ReadAllLines("Spe.txt");
private void cbxPokemon_SelectedIndexChanged(object sender, EventArgs e)
{
//Get array index of currently selected Pokemon
int index = cbxPokemon.SelectedIndex;
//Get integer values out of the string arrays for appropriate use
int intHP = int.Parse(HP[index]);
int intAtk = int.Parse(Atk[index]);
int intDef = int.Parse(Def[index]);
int intSpAtk = int.Parse(SpAtk[index]);
int intSpDef = int.Parse(SpDef[index]);
int intSpe = int.Parse(Spe[index]);
//Update labels with stat values in string forme, could also assign intStat.ToString()
lblDexNum.Text = (index + 1).ToString("d3");
lblHP.Text = HP[index];
lblAtk.Text = Atk[index];
lblDef.Text = Def[index];
lblSpAtk.Text = SpAtk[index];
lblSpDef.Text = SpDef[index];
lblSpe.Text = Spe[index];
lblBST.Text = (intHP + intAtk + intDef + intSpAtk + intSpDef + intSpe).ToString();
//Update bar width based on stat value
barHP.Width = intHP;
barAtk.Width = intAtk;
barDef.Width = intDef;
barSpAtk.Width = intSpAtk;
barSpDef.Width = intSpDef;
barSpe.Width = intSpe;
//Disable Previous and Next buttons when they cannot be used
if (index == 0) { btnPrev.Enabled = false; }
else { btnPrev.Enabled = true; }
if (index == cbxPokemon.Items.Count - 1) { btnNext.Enabled = false; }
else { btnNext.Enabled = true; }
}
private void btnPrev_Click(object sender, EventArgs e)
{
cbxPokemon.SelectedIndex -= 1;
}
private void btnNext_Click(object sender, EventArgs e)
{
cbxPokemon.SelectedIndex += 1;
}
}
}
Ideally, the file would contain the 6 stats, for example "100 90 80 70 60 50" on each line, with each of those valued being stored.
Is there a simple way to read until a space, store that value, and keep doing that until the end of the line?
Yes, this is very simple to do. You can use the String.Split() method to break apart the lines into parsable pieces.
You can read the stats file in the same way you are now, except you would only need to read one file instead of six:
string[] lines = File.ReadAllLines("PokemonStats.txt");
Then, inside your cbxPokemon_SelectedIndexChanged method, you can retrieve the stats for a Pokemon like this:
//Get integer values out of the string for appropriate use
string line = lines[index];
string[] parts = line.Split(' ');
int intHP = int.Parse(parts[0]);
int intAtk = int.Parse(parts[1]);
int intDef = int.Parse(parts[2]);
int intSpAtk = int.Parse(parts[3]);
int intSpDef = int.Parse(parts[4]);
int intSpe = int.Parse(parts[5]);
Of course this assumes there will always be exactly 6 integer stats per line and they will all be in a specific order.
Try something like this:
static void Main(string[] args)
{
//list to store stats
List<string[]> pokemonStats = new List<string[]>();
//get a reader on the file
using (StreamReader reader = new StreamReader("TextFile1.txt"))
{
//while we still have lines to read
while (!reader.EndOfStream)
{
//get the line of stats
string line = reader.ReadLine();
//split it on the ' ' character and store it in our list of pokemon stats
pokemonStats.Add(line.Split(' '));
}
}
//we have them all so do something, like print to screen
foreach (string[] pokemon in pokemonStats)
{
foreach (string stat in pokemon)
Console.Write(stat + " ");
Console.WriteLine();
}
Console.ReadLine();
}
Where TextFile1.txt contains; which also happens to be the output...
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
Ideally, the file would contain the 6 stats, for example "100 90 80 70 60 50" on each line, with each of those valued being stored.
So this solution is actually very simple, assuming you have a file that looks like this:
100
90
80
70
60
50
You could write code that looks like this:
public string[] ReadStats(string fileName)
{
return File.ReadAllLines(fileName);
}
This would return:
[ "100", "90", "80", "70", "60", "50" ]
This is obviously an over-simplified version that does not checking on whether the file exists, whether there are more than 6 lines, etc. But it gets the idea across, and you could enhance it to suit your needs.
The answer to your main question:
Is there a simple way to read until a space, store that value, and keep doing that until the end of the line?
This is a bit more complicated, but this should work:
public IEnumerable<string[]> ReadAllPokemonStats(string fileName)
{
List<string[]> allPokemon = new List<string[]>();
string[] allStats = new string[6];
var allText = File.ReadAllText(fileName);
int nextStatIndex = 0;
string thisStat;
for(int i=0; i < allText.Length; i++)
{
var nextChar = allText[i];
if(nextChar == ' ')
{
allStats[nextStatIndex] = thisStat;
nextStatIndex++;
continue;
}
if(nextChar == '\r')
{
allPokemon.Add(allStats);
nextStatIndex = 0;
allStats = new string[6];
continue;
}
thisStat += nextChar.ToString();
}
return allPokemon;
}
Again, the above code is not perfect, for example it reads the entire file into memory so there's a potential attack vector there. It also does not ensure that the stats are actually numeric, but neither did your code (it would just blow up on the int.Parse()). But again, it gives you the general idea. You can see this approach is actually a lot more complex that reading each stat line by line.
I am thinking that each file is a one column file that represents one type of stat. If this is correct, you can try this:
Perhaps creating a class the represents all the stats that you are loading and then treat that as an array or a dictionary to fetch the proper stat or to create a single stat file.
public class PokemonStat
{
public int Hp { get; set; }
public int Atk { get; set; }
public int Def { get; set; }
public int SpAtk { get; set; }
public int SpDef { get; set; }
public int Spe { get; set; }
}
Then in your executing file:
var newPokemanData = new Dictionary<int, PokemonStat>();
var fileNames = new string[] { "Hp.txt", "Atk.txt", "Def.txt", "SpAtk.txt", "SpDef.txt", "Spe.txt" }
foreach (var fileName in fileNames)
{
var lineNumber = 0;
using (var stream = new StreamReader(fileName))
{
while (!stream.EndOfStream)
{
var singleStat = stream.ReadLine();
if (!newPokemanData.Keys.Contains(lineNumber))
{
newPokemanData.Add(lineNumber, new PokemonStat());
}
switch(fileName)
{
case "Hp.txt":
newPokemanData[lineNumber].Hp = int.Parse(singleStat);
break;
case "Atk.txt":
newPokemanData[lineNumber].Atk = int.Parse(singleStat);
break;
case "Def.txt":
newPokemanData[lineNumber].Def = int.Parse(singleStat);
break;
case "SpAtk.txt":
newPokemanData[lineNumber].SpAtk = int.Parse(singleStat);
break;
case "SpDef.txt":
newPokemanData[lineNumber].SpDef = int.Parse(singleStat);
break;
case "Spe.txt":
newPokemanData[lineNumber].Spe = int.Parse(singleStat);
break;
default:
Console.WriteLine("Error");
break;
}
lineNumber++;
}
}
}
using (var unifiedStats = new StreamWriter("unifieldFile.txt"))
{
foreach (var line in newPokemanData.Keys)
{
//write to a file
unifiedStats.WriteLine(newPokemanData[line].Hp.ToString() + " " +
newPokemanData[line].Atk.ToString() + " " +
newPokemanData[line].Def.ToString() + " " +
newPokemanData[line].SpAtk.ToString() + " " +
newPokemanData[line].SpDef.ToString() + " " +
newPokemanData[line].Spe.ToString() + " "
);
}
}
//
I will do what I can to get a snipit of the txt files on here for you to look at. most of them are class and it will take a bit of work for me to do that. The idea is to take a txt file with say a list of over 500 places run them against a list of 50 places and pull out the ones that match. As I said I have tried many diffrent ways, well all the ones I know, and I can not seem to get it to work right. I am trying to take the following code and have it do the above action. Does that help.
InPutBox = Input.Text;
int x = 1;
var lines = Input.Text.Split(new string[] { Environment.NewLine },StringSplitOptions.None);
for (var index = 0; index < lines.Length; index++)
{
var line = lines[index];
do
{
x++;
System.Console.WriteLine("'{0}'", InPutBox);
bool test1 = InPutBox.StartsWith("TAG");
bool test2 = InPutBox.EndsWith("TAG");
if (test1 && test2)
{
int first = InPutBox.IndexOf("TAG");
int last = InPutBox.LastIndexOf("TAG");
InPutBox = InPutBox.Substring(first, last - first);
}
}
while (x < 50);
System.Console.WriteLine("'{0}'", line);
if ((line.StartsWith("TAG") && line.EndsWith("TAG")))
{
MessageBox.Show("These are errors in line" + index + ": " + line);
break;
}
}
I have a text file this is a small part of him its format:
DANNY VIDEO HISTOGRAM DATA
FORMAT VERSION:1.00
SOURCE: <MVI_2483.AVI_Automatic>
DATA:
Frame 000000: 5977,40775,174395,305855,265805
Frame 000001: 5432,21333,456789,123456,111111
Now every line Frame.....Have 256 numbers 5977,40775,174395,305855,265805
In the example i show here only 5 numbers but each line/frame have 256 numbers.
In Form1 i have a List: List Histograms
What i need to do is to read the text file in this case the text file name is Histograms.txt to read the text file and each line/frame with 256 numbers i need to add back to the List.
So the List Histograms will be in the end that in index [0] for example i will have 256 indexes in [0] 5977 in 1 40775 in [2] 174395 in [3] 305955 in [4] 265805 and so on 256 numbers.
Then in index 1 again 256 numbers ...
Then in index [2] and so on...
In the end i should have in the List 3803 index that each index have inside 256 index that each one contain a number.
This is the code of how i am writing the text file when the List is with the numbers and then when i am running the program again i need that it will read and load the text file back to the List. When i am running the program the List is empty.
private void WriteHistograms() // For automatic mode only for now
{
HistogramsFile = new StreamWriter(_outputDir + "\\" + averagesListTextFileDirectory + "\\" + "Histograms.txt", false, Encoding.ASCII);
HistogramsFile.WriteLine("DANNY VIDEO HISTOGRAM DATA\r\nFORMAT VERSION:1.00\r\nSOURCE: " + "<" + averagesListTextFile + ">" + "\r\nDATA: ");
for (int i = 0; i < Histograms.Count; i++)
{
HistogramsFile.Write("Frame " + i.ToString("D6") + ": ");
for (int x = 0; x < Histograms[i].Length; x++ )
{
HistogramsFile.Write(Histograms[i][x] + ",");
}
HistogramsFile.WriteLine("!");
}
HistogramsFile.WriteLine("DATA");
HistogramsFile.Close();
}
Now i have another function: LoadHistograms(), i need to read the text file and add back the numbers to the List.
I added now a photo of the List how it is when writing it to the text file and how the List should looks like after reading it back from the text file.
You can have a fairly good idea how to get it done by using this piece of code.
string line;
List<long[]> list = new List<long[]>();
using (StreamReader file = new StreamReader(#"..\..\Histograms.txt"))
{
do { line = file.ReadLine(); } while (!line.Trim().Equals("DATA:"));
while ((line = file.ReadLine()) != null)
{
long[] valArray = new long[256];
var split = line.Split(new char[] { ':' });
if (split.Length == 2)
{
var valArrayStr = split[1].Split(new char[] { ',' });
for (int i = 0; i < valArrayStr.Length; i++)
{
int result;
if (int.TryParse(valArrayStr[i].Trim(), out result))
valArray[i] = result;
}
}
list.Add(valArray);
}
}
Happy Coding...