0

I have a large table of values (35x23 cells) and I need to use them in a C program. I would like to know what is the most efficient way of going about this.

I know that I can manually create a 2D array and put each custom element in as follows:

int arr[2][5] = {
    {1,0,0,1,1},
    {1,0,1,1,0}
  };

This would work however it will be very time consuming and messy to create it this way for so many variables in a 35x23 array, so I was wondering if there is a better or more efficient way to do this.

Thanks in advance

wolly981
  • 29
  • 8
  • 3
    1. Type all them in. (Tedious, as you said.) 2. Use `sed` or some other command-line tool to mechanically transform your table into the initializer you needed for (1). 3. Use a search/replace function in your favorite text editor to automate the tedious work in (1). 4. Put the numbers in a file and have the program read them in at run time. (I have used all four of these techniques; I can't even say what my "favorite" is.) – Steve Summit Sep 18 '19 at 13:50
  • @Steve Thank you for your clarification – wolly981 Sep 18 '19 at 13:54
  • Personally, I typically generate my values in excel and save it as a CSV. Then I open the CSV in Notepad++ and manipulate it from there to be copy/pasteable for code. Here's an interesting thought: how *could* someone design it better? I can't think of a better way, and maybe that means I'm shortsighted. – yhyrcanus Sep 18 '19 at 14:12
  • What is the largest value you will allow to exist in your array? eg. the range of values for an `int` type is -2147483648 to 2147483647. With commas and braces, and for 35 values, each line will be ~423. Is this a problem for you? (_[Max legal line in C is 4095](https://stackoverflow.com/questions/11614687/maximum-length-of-statement-in-c)_.) – ryyker Sep 18 '19 at 14:37
  • Not a problem, honestly just feeling lazy (or rather didn't want to type them all in) and was curious if there was a better way to do it. The values are 0 and 1 only. In the end I manually typed it out and stored it in its own file as the answer below has also suggested. – wolly981 Sep 18 '19 at 15:29

2 Answers2

1

If the numbers of columns and rows, and the elements of the table do not change, you can do this:

// file: foobar.c
int arr[2][5] = {
    #include "data.tab"
};
// file: data.tab
{1,0,0,1,1},
{1,0,1,1,0},
  • I don't see the point. It is the same work to type the data in `foobar.c` or `data.h` – schorsch312 Sep 18 '19 at 14:59
  • @schorsch312 But the data is stored only in ```data.h```. – Togtokh Khorchin Sep 18 '19 at 15:11
  • And if the numbers of columns and rows do not change, you can even call the file `data.tab`, and leave out the `{` and `}` on each row, that is, have the file contain numbers and commas and newlines only. This is either a neat hack or a disgusting kludge, depending on your point of view, but it makes the file even easier to prepare. (Unfortunately, a helpful compiler might warn about the "missing" `{}`, because most of the time, explicitly including them is the preferred style.) – Steve Summit Sep 18 '19 at 15:44
1

In case you ever want to do it the Option 4 way (as suggested in the comments under your post), here is an implementation that will get you started. It was written to use command line values for input file (a CSV) and values for rows and cols. It is partially done allowing you to finish with the final line creation to a header file.

#define DEST "C:\\dir1\\desination.h"

int main(int argc, char *argv[])
{
    char *temp = NULL;
    int rows, cols;
    char linebuf[500];  //accomodates 35 values (and punctuation) per row


    if(argc != 4)
    {
        printf("Usage *.exe <filespec> <n1> <n2> where n1 & n2 are positive integer values.\nHit any key to exit");
        getchar();
        return 0;
    }

    rows = strtol(argv[2], &temp, 10);
    if (temp == argv[2] || ((rows == LONG_MIN || rows == LONG_MAX) && errno == ERANGE))
    {
        //handle error
    }
    cols = strtol(argv[3], &temp, 10);
   if (temp == argv[3] || ((cols == LONG_MIN || cols == LONG_MAX) && errno == ERANGE))
    {
        //handle error
    }

    //read in rows*cols values from input file into data[]
    int data[cols*rows];
    FILE *fpin = fopen(argv[1], "r");
    if(fpin)
    {

        char buf[20];

        int i=0;

        //populate
        while(fgets(buf, 20, fpin) && (i < rows*cols))
        {
            data[i] = strtol(buf, &temp, 10);
            if (temp == buf || ((data[i] == LONG_MIN || data[i] == LONG_MAX) && errno == ERANGE))
            {
                //handle error
            }
            i++;

        }

        fclose(fpin);
    }
    FILE *fpout = fopen(DEST, "w");
    if(fpout)
    {
        // place first line of array in header file:
        sprintf(linebuf, "int array[%d][%d] = {\n", rows, cols);
        fputs(linebuf, fpout);
        // for you to do, 
        // loop on array data and create "lines" with 
        // values, commas and "{}" and fputs into fpout
        // 
    }
    fclose(fpout); //header file DEST should now be ready to use.

    return 0;
}
ryyker
  • 22,849
  • 3
  • 43
  • 87