Why this c-program gives error when I initialize structure member outside the main function?

Viewed 72

Why this c-program gives error when I initialize structure members (user.username and user.pin) outside the main function?, But everything becomes fine when I initialize it inside the main function.

Also is there any way to initialize a char array (member of structure)?

#include <stdio.h>

typedef struct {
    int pin;
    char username[20];
} portal;

portal user;

// user.username = "alex"; 
// user.pin[20] = 1234;  //Why this gives error when I intialize it here(i.e outside the main function)?

int main() {
    user.username = "alex"; //How to intialize a memeber(having type char) of structure?
    user.pin[20] = 1234;

    printf("WELCOME TO PORTAL\n");
    printf("ENTER YOUR USERNAME:\n");
    scanf("%[^\n]%*c", user.username);
    .
    .
    .

Actually I'm getting this output when I initialize user.username outside the main function.

enter image description here

4 Answers

// user.username = "alex"; // user.pin[20] = 1234; //Why this gives error when I intialize it here(i.e outside the main function)?

This is not an initialization. This is assignment statements. Outside functions you may place only declarations not statements.

Moreover even as statements they are incorrect.

Look at your structure definition

typedef struct
{
 int pin;
 char username[20];
}portal;

The data member pin has the type int. It is not an array. So this assignment

user.pin[20] = 1234;

does not make a sense. You should write at least like

user.pin = 1234;

On the other hand, the data member username is a character array. Arrays do not have the assignment operator. You have to copy a string into the character array. For example

#include <string.h>

//...

strcpy( user.username, "alex" );

But you could initialize the object user when it was declared. For example

portal user = { 1234, "alex" };

or

portal user = { .pin = 1234, .username = "alex" };

Here is a demonstrative program

#include <stdio.h>

typedef struct
{
    int pin;
    char username[20];
} portal;

portal user = { .pin = 1234, .username = "alex" };

int main(void) 
{
    printf( "pin = %d, user name = %s\n", user.pin, user.username );

    return 0;
}

The program output is

pin = 1234, user name = alex

Global variables can be initialized as the point of definition, but not as stand alone statements:

portal user = { 1234, "alex" };  // definition with an initializer

user.pin = 1234;        // assignment is invalid outside a function
user.username = "Alex"; // assignment is invalid outside a function and assigning to an array is invalid as well

The structure members can be set inside a function, but arrays contents cannot be assigned with the = operator, you need to assign array elements explicitly or use a function call:

int main() {
    char extra[20];

    user.pin = 1234;         // OK

    user.username[0] = 'A';  // tedious, but OK
    user.username[0] = 'l';
    user.username[0] = 'e';
    user.username[0] = 'x';
    user.username[0] = '\0'; 

    strcpy(user.username, "Alex"); // OK if username has at least 5 elements

    snprintf(user.username, sizeof user.username, "%s", "Alex"); // overkill, but OK

    // read values from stdin:
    // scanf will return the number of members successfully converted:
    switch (scanf("%d%19s%19[^\n]", &user.pin, user.username, extra)) {
      case EOF:
        printf("premature end of file\n");
        break;
      case 0:
        printf("input is not a number for user.pin\n");
        break;
      case 1:
        printf("user.pin=%d, no input for user.username\n", user.pin);
        break;
      case 2:
        printf("user.pin=%d, user.username=%s\n", user.pin, user.username);
        break;
      case 3:
        printf("user.pin=%d, user.username=%s, extra input=%s\n", user.pin, user.username, extra);
        break;
    }
    return 0;
}

In C, outside of functions, you can have only declarations and preprocessor directives. The source text user.username = "alex"; is a statement, as is user.pin[20] = 1234;. The compiler error message occurs because the compiler is expecting a declaration, and your statements do not fit what it is expecting.

To initialize objects as you are defining them, you use a syntax for initialization with the definition rather than writing separate statements. user could be defined and initialized with either of:

portal user = { "alex", 1234 };
portal user = { .username = "alex", .pin = 1234 };

Although definitions use = in initialization, this is not an assignment. It is a different use of the = symbol for a similar effect (put this value in that place). Another difference is that, in an initialization, you can use a string literal to initialize a character array. In a statement, you cannot.

Another way to give initial values to user would be to write statements inside main:

int main(void)
{
    strcpy(user.username, "alex");
    user.pin = 1234;
    …
}

That struct member was already initialised. When you do it outside main the compiler can optimise it by setting it to the string literal straight away.

If main is entered, then it's too late to initialise. The compiler does not make the assumption that main is guaranteed to be called or called immediately. Therefore the statement within main is not initialisation but assignment. You cannot assign to a character array, that's what strcpy and related functions are for.

This should work:

strcpy(user.username, "Alex")

or

snprintf(user.username, sizeof user.username, "Alex");
Related