简体   繁体   中英

Is it possible to use a loop for declaring variables?

I have huge amount of txt files which contains 64x64 matrices consisting of integers. txt files has names like:

mat_1.txt, mat_2.txt, mat_3.txt, mat_4.txt, .... , mat_n.txt.

I have to create a variable, allocate space on host and device, read txt file and copy to device. is it possible to do it all in one loop?

I know how to create a string with sprintf but do not know how to use this string for example for declaring variables.

char fname[10]; 
for( int k=1; k<=n; k++ )
{
    sprintf( fname, "mat_%d", k );
    int *fname;    // how to say to compiler that insted of `fname` there 
                   // should be `mat_1` and in next cycle `mat_2`?
}

You can't create a variable name at runtime. Variable names are for compiler and only compiler to know and cannot be generated on the fly.

What you need is an array. Since the data already need to be stored in an array, you need to add 1 dimension to your array.

For example, if data in mat_1.txt is a 1 dimensional array, you can have:

int **mat;                        // 2D array
int k;
mat = malloc(n * sizeof(*mat));   // get an array of pointers (add error checking)
for (k = 1; k <= n; ++k)
{
    char fname[20]; 
    FILE *fin;
    sprintf(fname, "mat_%d.txt", k);
    fin = fopen(fname, "r");
    if (fin == NULL)
        /* Handle failure */
    /* read number of items */
    mat[k-1] = malloc(number of items * sizeof(*mat[k-1]));  // allocate an array for each file
    /* read data of file and put in mat[k-1] */
    fclose(fin);
}
/* At this point, data of file mat_i.txt is in array mat[i-1] */
/* When you are done, you need to free the allocated memory: */
for (k = 0; k < n; ++k)
    free(mat[k]);
free(mat);

What computer are you using?

A 64x64 array of int, where int is 4 bytes, is array of 16,386 bytes, 22,500 files with 1 matrix/file would be 368,640,000 bytes.

That works fine on my 5 year old laptop:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define MAX_FILES (22500)
#define MAX_J (64)
#define MAX_K (64)

int a[MAX_FILES][MAX_J][MAX_K];
const char namefmt[] = "mat_%d";

int main (int argc, const char * argv[]) {
    char fname[strlen(namefmt)+10+1];  // an int has 10 or less digits
    for (int fileNumber=0; fileNumber<MAX_FILES; ++fileNumber) {
        sprintf(fname, namefmt, fileNumber);
        FILE* fp = fopen(fname, "r");
        if (fp == NULL) {
            fprintf(stderr, "Error, can't open file %s\n", fname);
            exit(1);
        }
        for (int j=0; j<MAX_J; ++j) {
            for (int k=0; k<MAX_K; ++k) {
                //... read the value
            }
        }
        fclose(fp);
    }
    return 0;
}

It should work okay (though may become painfully slow) on a modern computer running an operating system with virtual memory, and enough swap space. Declaring it as an array, rather than using malloc will save a miniscule amount of space, but otherwise is the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM