3

So I have a rather large text file with 2 columns of numbers that I would like to be able to use in a program I'm writing as a two-dimensional array. This is data that needs to be accessible every time I start up my program and I feel that it would be too slow/inefficient to have to read in the data with a file reader every single time I start my program.

So I was wondering if there was an easier/more efficient way of accessing the data without having to read it in the traditional way (ifstream, etc)? I believe that I've once seen something like the following done:

float array[]{
    #include "myfile.txt"
}

but I'm not even sure if that's a valid thing to do and I can't find any information on it.

7
  • If your data is formatted in such a way that it creates a legal array initialization then it's possible to do it that way. Of course, you need to recompile every time the data changes. Have you even tried reading the file at startup? How large is "rather large"? Commented Nov 27, 2013 at 6:51
  • if myfile.txt doesn't follow c++ syntax, compilation error. Commented Nov 27, 2013 at 6:51
  • What kind of syntax would myfile.txt need? Right now it is just 2 vertical columns of numbers with a space separating the columns but no other punctuation Commented Nov 27, 2013 at 6:53
  • @me.deeiip People doing this trick usually construct their data so that it does follow C++ syntax. There's no point in generating faulty code. Commented Nov 27, 2013 at 6:53
  • 2
    If you haven't tried reading the file at run time, I recommend trying it, if only to find out how long it really does take. You might be surprised. In the words of that great sage Don Knuth, "Premature optimization is the root of all evil." Commented Nov 27, 2013 at 7:09

4 Answers 4

2

First you have to think about how 2-dimensional arrays declared and initialized. Simply;

int x[5][2] = {
    {1, 1},     
    {2, 2},     
    {3, 3},     
    {4, 4},     
    {5, 5}
};

if array elements coming from file you have to create the file exacly like; in file.txt;

{1, 1},     
{2, 2},     
{3, 3},     
{4, 4},     
{5, 5}

following the rule of C++ include file preprocessor directive, you can simple write your code like this; Source.cpp file;

#include <iostream>
using namespace std;

int x[5][2] = {
    #include "file.txt"
};

int main(int argc, char* argv[])
{   
    for(int i = 0; i < 5; ++i)
    {
        for(int j = 0; j < 2; j++)          
        {
            cout << "x[" << i + 1 << "][" << j + 1 << "] = " << x[i][j] << " , ";
        }
        cout << endl;
    }

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

0

If you stick the way of embedding the data within included file, you can use Macros:

  1. Write your data in the included file ("myfile.txt" in your example, or "myfile.h").
  2. Write the data in in the format of:

    #define DATA 1,2,3,4,5
    

    (you can break it into lines, but keep the comma-separated format).

  3. include "myfile.h" at the top of your source file.

  4. Use DATA instead of your #include statement:

    float array[] {
        DATA
    };
    

3 Comments

what would be the point of using #define DATA instead of directly including the file at the needed position? to me that just seems more complicated
My suggestion just try to keep to existing code conventions, as to make the code more readable. Maybe I'm wrong, but I think that the common programmer may get confused of seeing an "include" statement in the middle of a source file.
but I for my part would be equally confused by a define standing for more than one value. I would end up having to do two lookups (first the macro definition, then inside the file) to find out what is going on there, instead of one if there only is the include
0

To make this work you should format your text file in a way that it follows the C++ syntax. You can follow number of tutorials in order to see good examples of that along with description of what is happening.

Here is a short example:

  • for one dimensional array just type the numbers with comas like this

1.0, 3.4, 3.14, 5.56

  • for two and more dimensions enclose each row in brace {}, separating each column with a coma like this

{1.0, 3.14}, {4.1, 5.674}

Above is assuming you're following your own example of

float array[] = {
    #include "textFile.txt"
};

Comments

0

You're doing it the right way IF you don't mind recompiling when the data changes. Of course the data has to have commas because it has to be valid C/C++ syntax. All #include does is paste the file's contents into your source code.

OTOH, if you DO mind recompiling when the data changes, then you need to allocate the memory dynamically and parse in the data file, when the program starts up. The problem you need to overcome here is you don't necessarily know in advance how big the array will be, and if you use a dynamically-expanding array you could waste a fair amount of time in memory allocation and deletion as it grows the array. My solution is, as usual, counterintuitive. I just read the file twice, once to count how many numbers are in it, then allocate the memory, then read the file again, to parse the numbers into the memory. (If reading it once doesn't take very long, neither does reading it twice, especially since it's already in the system cache.)

You say the data is 2-dimensional, but you could put it in the array as 1-dimensional, and just access it in two dimensions, like this:

#define A(row,col) array[(row)*2 + (col)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.