0

I have a problem. I want to create a program that reads from a file different elements - vectors, arrays, scalars. In the struct I have variables like dimension, name, a symbol of element and value etc. I get errors when I use structs

primal.c:10:18: error: ‘dimension’ undeclared here (not in a function)
         double V[dimension];
                  ^~~~~~~~~
primal.c:28:18: error: ‘dimensionX’ undeclared here (not in a function); did you mean ‘dimension’?
         double M[dimensionX][dimensionY];
                  ^~~~~~~~~~
                  dimension
primal.c:28:30: error: ‘dimensionY’ undeclared here (not in a function); did you mean ‘dimensionX’?
         double M[dimensionX][dimensionY];
                              ^~~~~~~~~~

This is my whole program.

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

    struct Vector 
    { 
        char keyWord;
        char elementName[20];
        int dimension;
        double V[dimension];
    };
    typedef struct Vector wek;

    struct Scalar 
    { 
        char keyWord;
        char elementName[20];
        double wartosc;
    };
    typedef struct Scalar ska;

    struct Array
    {
        char keyWord;
        char elementName[20];
        int dimensionX;
        int dimensionY;
        double M[dimensionX][dimensionY];
    };
    typedef struct Array mac;

int main (int argc, char *argv[])
{    
    FILE *wz, *wc;  
    int dimension, dimensionX, dimensionY;

    if (argc != 3) {                                
    printf("Wrong arguments number\n");
    printf("I should run this way:\n");
    printf("%s source\n",argv[0]);
    exit(1);
    }
    
    if( (wz= fopen(argv[1],"r")) == NULL) {
        printf("Open error %s\n", argv[1]);
        exit(1);
    }
    if( (wc= fopen(argv[2], "w")) == NULL) {
    printf("Open error %s\n", argv[2]);
    exit(2);
    }
    


            
    
    struct Vector w1, w2;
    struct Scalar s1, s2;
    struct Array m1, m2;
    
    
    wek readVector(FILE *wz)
{
    wek w;
    fscanf(wz, "%s", &w.keyWord);
    fscanf(wz, "%20s", &w.elementName[0]);
    for (int j = 0; j < dimension; ++j)
            fscanf(wz, "%10lf", &w.V[j]);
    return w;
}
    ska readScalar(FILE *wz)
{
    ska s;
    fscanf(wz, "%s", &s.keyWord);
    fscanf(wz, "%20s", &s.elementName[0]);
    fscanf(wz, "%10lf", &s.wartosc);
    return s;
}
    mac readArray(FILE *wz)
{
    mac m;
    fscanf(wz, "%s", &m.keyWord);
    fscanf(wz, "%20s", &m.elementName[0]);
    for (int i = 0; i < m.dimensionX; ++i)
        for (int j = 0; j < m.dimensionY; ++j)
            fscanf(wz, "%10lf", &m.M[i][j]);
    return m;
}
    s1 = readScalar(wz);
    s2 = readScalar(wz);
    w1 = readVector(wz);
    w2 = readVector(wz);
    m1 = readArray(wz);
    m2 = readArray(wz);
    printf("Symbol %c, nazwa %s, wartosc %lf", s1.keyWord, s1.elementName, s1.wartosc);
    fclose(wz);
    fclose(wc);
    
    return 0;
}

I don't know why that this is undeclared, I have for example first struct and I declared this variable.

    struct Vector 
    { 
        char keyWord;
        char elementName[20];
        **int dimension;**
        double V[**dimension**];
    };

Edit I edited my code

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

    struct Vector 
    { 
        char keyWord;
        char elementName[20];
        int dimension;
        double *V;
    };
    typedef struct Vector wek;

    struct Scalar 
    { 
        char keyWord;
        char elementName[20];
        double wartosc;
    };
    typedef struct Scalar ska;

    struct Array
    {
        char keyWord;
        char elementName[20];
        int dimensionX;
        int dimensionY;
        double **M;
    };
    typedef struct Array mac;

int main (int argc, char *argv[])
{    
    FILE *wz, *wc;  
    int dimension, dimensionX, dimensionY;

    if (argc != 3) {                                
    printf("Wrong arguments number\n");
    printf("I should run this way:\n");
    printf("%s source\n",argv[0]);
    exit(1);
    }
    
    if( (wz= fopen(argv[1],"r")) == NULL) {
        printf("Open error %s\n", argv[1]);
        exit(1);
    }
    if( (wc= fopen(argv[2], "w")) == NULL) {
    printf("Open error %s\n", argv[2]);
    exit(2);
    }
    


            
    
    struct Vector w1, w2;
    struct Scalar s1, s2;
    struct Array m1, m2;
    
    
    wek readVector(FILE *wz)
{
    wek w;
    w.V = malloc( sizeof *w.V * w.dimension );
    fscanf(wz, "%s", &w.keyWord);
    fscanf(wz, "%20s", &w.elementName[0]);
    for (int j = 0; j < dimension; ++j)
            fscanf(wz, "%10lf", &w.V[j]);
    return w;
}
    ska readScalar(FILE *wz)
{
    ska s;
    fscanf(wz, "%s", &s.keyWord);
    fscanf(wz, "%20s", &s.elementName[0]);
    fscanf(wz, "%10lf", &s.wartosc);
    return s;
}
    mac readArray(FILE *wz)
{
    mac m;
    m.M = malloc( sizeof *m.M * m.dimensionX * m.dimensionY);
    fscanf(wz, "%s", &m.keyWord);
    fscanf(wz, "%20s", &m.elementName[0]);
    for (int i = 0; i < m.dimensionX; ++i)
        for (int j = 0; j < m.dimensionY; ++j)
            fscanf(wz, "%10lf", &m.M[i][j]);
    return m;
}
    s1 = readScalar(wz);
    s2 = readScalar(wz);
    w1 = readVector(wz);
    w2 = readVector(wz);
    m1 = readArray(wz);
    m2 = readArray(wz);
    printf("Symbol %c, nazwa %s, wartosc %lf", s1.keyWord, s1.elementName, s1.wartosc);
    fclose(wz);
    fclose(wc);
    
    return 0;
}

but I get warnings, when I compiled with -Wall

primal.c:65:34: warning: ‘w.dimension’ is used uninitialized in this function [-Wuninitialized]
     w.V = malloc( sizeof *w.V * w.dimension );
                                 ~^~~~~~~~~~
primal.c: In function ‘readArray’:
primal.c:83:34: warning: ‘m.dimensionX’ is used uninitialized in this function [-Wuninitialized]
     m.M = malloc( sizeof *m.M * m.dimensionX * m.dimensionY);
                                 ~^~~~~~~~~~~
primal.c:83:49: warning: ‘m.dimensionY’ is used uninitialized in this function [-Wuninitialized]
     m.M = malloc( sizeof *m.M * m.dimensionX * m.dimensionY);

The warnings are pretty self-explanatory - you haven’t assigned any values to w.dimension or m.dimensionX. Their values are indeterminate. You need to assign values to them before you can use them in the malloc call. – John Bode 5 hours agoPlease use the edit link on your question to add additional information. The Post Answer button should be used only for complete answers to the question. - From Review – Rob 27 mins ago

2
  • 2
    V should be a pointer if the array size is unknown: double *V, etc. Or... you need a constant: #define DIMENSION (5), double V[DIMENSION]. Looks like you want the flexibility of the first one. Commented Jul 3, 2020 at 15:12
  • 1
    Or you need to use a 'flexible array member' (FAM), which must be the last element in the structure. struct Vector { char keyWord; char elementName[20]; int dimension; double V[]; /* FAM */ };. They are a part of C99 and beyond. Commented Jul 3, 2020 at 15:18

2 Answers 2

3

In the declaration

double V[dimension];

dimension is not a constant expression, which means you’re declaring V as a variable-length array. Unfortunately, VLAs may not be struct or union members.

Edit

Of course, that’s not why you’re getting the compiler error - the dimension you’re using in the array declaration is not the same dimension that you’ve declared in the struct type. C has different name spaces for identifiers:

  • label names (must be preceded by goto or followed by a :);
  • tag names (must be preceded by the struct or union keyword);
  • struct and union member names (must be preceded by an identifier followed by . or ->);
  • all other identifiers (variable names, function names, enumeration constants, etc.);

In the declaration

double V[dimension];

the compiler is looking for a dimension variable outside of your struct definition - there’s no way to specify that you want to use the member variable (which won’t work anyway for the reason given above).

End edit

In this case, you’ll need to allocate memory for V dynamically, so you’ll need to declare it as a pointer:

double *V;

and then after you read or compute the dimension allocate memory for it as

w.V = malloc( sizeof *w.V * w.dimension );
Sign up to request clarification or add additional context in comments.

2 Comments

Flexible array members?
@JonathanLeffler: Maybe. They’d have to allocate the whole struct instance dynamically, though.
1

You can't assign the length of an array inside a structure with another member of the structure.try to use a pointer and allocate it dynamically.Or if you don't want to use pointer,define a max macro for the dimension.

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.