Reading Text file to an array

Started by
11 comments, last by brandonman 16 years, 9 months ago
I'm currently working on terrain, and I need to know how to read a text file to a 1D or 2D array, which ever. I know how to read to say, a string, but not an array. any help is appreciated. edit: in C++
Advertisement
Well. If it's a text file then it's a string. Read the string, convert it to an int or whatever and store it in your array. You'll need to parse the string looking for separators like spaces or tabs or whatever you delineate your data with.

Basically:
1: read a line of text
2: loop over the line creating substrings of the characters that appear between the spaces/tabs
3: for each substring, try to convert it to the correct datatype and if the conversion is successful, store it in your array.

You may need to loop over everything once to count the size of the array you need to allocate (unless you're using a dynamic container like std::vector or std::list).

Better, of course, would be to have a program to generate a binary file of terrain data since string parsing is: (1) a giant pain in the butt (2) really slow.

-me
You really didnt say enough about what you are doing to get proper advice. If you just want to flat out read a text file into a character array then here is how...

#include <iostream>#include <fstream>#include <memory>using namespace std;int main(){	int length; //length of the file	auto_ptr<char> myarray; //pointer to character array	ifstream in_file("myfile.txt", ios::binary); //open file for input	if(in_file.is_open()){  //if the file is open continue with operations			in_file.seekg(0, ios_base::end);  //go to the end of the file		length = in_file.tellg();         //see how many bytes the last operation skipped		in_file.seekg(0, ios_base::beg);  //go back to beginning				myarray.reset(new char[length]);  //create a new array		in_file.read(myarray.get(),length);  //read the file into the array	}	//No need to delete the char array	//Don't acctually have to close the file but it is a nice to do so anyway	in_file.close();	return 0;}


If you need to parse individual words from the file like the previous poster suggested then you should probobly [google] strtok or string tokenizer.

Also if effiency matters then you should probobly ignore Palidine's suggestion to read in a line at a time as I believe it is very inefficient unless the file is acctually in memory. Due to the nature of hard drives the time it takes to return one byte or its maximum is going to be the same so you should grab as many as possible. However I'm going off older information and it may or may not be right.
What do you want to read an array *of*?

And how is it formatted in the file?

These are among the questions you must consider. More discussion.
Quote:Original post by antiquechrono
You really didnt say enough about what you are doing to get proper advice. If you just want to flat out read a text file into a character array then here is how...

*** Source Snippet Removed ***

If you need to parse individual words from the file like the previous poster suggested then you should probobly [google] strtok or string tokenizer.


1) You wouldn't normally open a text file in binary mode, and you usually don't want to read the whole thing into an array either.

2) Parsing *words* is normally done most effectively with good old operator>>. In somewhat more complex circumstances, std::getline is useful.

3) Even strtok()'s own documentation says never to use it.

Quote:Also if effiency matters then you should probobly ignore Palidine's suggestion to read in a line at a time as I believe it is very inefficient unless the file is acctually in memory. Due to the nature of hard drives the time it takes to return one byte or its maximum is going to be the same so you should grab as many as possible. However I'm going off older information and it may or may not be right.


4) The stream object buffers all reads from disk anyway, so this is irrelevant.

5) It's a bad idea to talk about the situation "if efficiency matters" preemptively, when presenting introductory material.

Quote:Original post by Zahlman
1) You wouldn't normally open a text file in binary mode, and you usually don't want to read the whole thing into an array either.

If all the op wants is to move a whole file into an array then thats a great way to do it. If we are talking about a 4GB file then of course thats dumb, but if its a 100k file then theres nothing wrong with it depending on what you need it for. Then again the op has not said exactly what he wants so I can only guess.

Quote:
2) Parsing *words* is normally done most effectively with good old operator>>. In somewhat more complex circumstances, std::getline is useful.

Yes that is a fine solution, but by all means not the only one. Again, we don't know what the op wants unless I am the only one who was slightly confused by the post

Quote:
3) Even strtok()'s own documentation says never to use it.

Where is your source? Just because it isn't thread safe and can bite you in the rear if you are feeling stupid while using it does not make the tool broken. Some people will use it and others won't, it is a personal prefrence. If the op researched my suggestions then he could learn how it works. There is certainly nothing stopping him from writing his own implementation.

Quote:
4) The stream object buffers all reads from disk anyway, so this is irrelevant.

My bad, I forgot that they were buffered.

Quote:
5) It's a bad idea to talk about the situation "if efficiency matters" preemptively, when presenting introductory material.

It's also a bad idea to try and correct people's assumptions based on a vague post. For all we know at this point he may not need to "parse" anything.
Sorry I didn't post more details, the forums had some sort of problem last night. I'm just trying to read a file that has either a line of numbers like so:
 1253795 
or a number on each line:
14973


whichever would work good for loading it into an array for the heights of a terrain.
Yeah I was having problems last night as well. Just put a space between each number or a number on each line and this will work.

#include <iostream>#include <fstream>#include <vector>using namespace std;int main(){	ifstream file("myfile.txt");	int temp;	vector<int> myarray;	while(file >> temp){		myarray.push_back(temp);	}	for(int i=0; i < (int)myarray.size(); i++){		cout << myarray<<" ";	}	system("pause");	return 0;}
antiquechrono be aware that in your first code example you used a std::auto_ptr instance to hold the address of something allocated with new []. This is incorrect, as the std::auto_ptr destructor will call delete on this, not delete [] which is required.

Moral: never use new[]/delete[] Always use std::vector or boost::array.
Quote:Original post by rip-off
antiquechrono be aware that in your first code example you used a std::auto_ptr instance to hold the address of something allocated with new []. This is incorrect, as the std::auto_ptr destructor will call delete on this, not delete [] which is required.

Moral: never use new[]/delete[] Always use std::vector or boost::array.


Ugh, that is what I get for trying to be creative lol. Thanks for the heads up though.

This topic is closed to new replies.

Advertisement