-5

I need to find the length of a Message which was entered. I have put all the characters in the msg into an array msg[], but when I check for the size of this array, it comes out to zero. Thank you for your help.

#include <stdio.h>
#define SIZE ((int) (sizeof(msg)/sizeof(msg[0])))

int main(void){
    int i = 0,j = 0;
    char msg[i];
    char ch = ' ';
    printf("Please enter a msg you want traslated: ");
    while(ch != '\n'){
        scanf("%c",&ch);
        if(ch == '\n'){
            break;
        }
        i++;
        msg[j] = ch;
        j++;
    }
    printf("%d\n",SIZE);
    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 8
    `msg[i]` and `i=0` ? – Inian Aug 03 '20 at 18:58
  • 2
    `int i = 0; char msg[i];` is an invalid a attempt to form a variable length array of size 0 - undefined behavior. Once an array is defined, its size cannot change. – chux - Reinstate Monica Aug 03 '20 at 18:58
  • change `char msg[i]` to `char msg[50]` and see what happens. Not that this is the correct way to do any of this, but maybe you will then understand what's happening. – Andy Aug 03 '20 at 19:01
  • 1
    Size and length are two different notions in C. Size is typically the length of an allocated data structure (it's fixed at allocation time). Length is the number of actual elements in an allocated data structure (e.g. the number of characters in a string, or the number of ints in an array) and it's variable. – jarmod Aug 03 '20 at 19:04

2 Answers2

1

The reason of your confusion is that you do not understand variable length arrays correctly.

For starters take into account that you may not declare a variable length array with the size equal to 0. So in any case this array declaration

int i = 0,j = 0;
char msg[i];

is incorrect.

To change the size of the array msg it is not enough to change the value of the variable i used in the array declaration. It is required that the execution control of the program would go through the array declaration each time for a new value of i.

Here is a demonstrative program.

#include <stdio.h>

int main(void) 
{
    int i = 1;
    
    L1:;
    char msg[i];

    printf( "The size of msg is %zu\n", sizeof( msg ) );
    
    if ( i++ < 10 ) goto L1;
}

The program output is

The size of msg is 1
The size of msg is 2
The size of msg is 3
The size of msg is 4
The size of msg is 5
The size of msg is 6
The size of msg is 7
The size of msg is 8
The size of msg is 9
The size of msg is 10

As you can see, the control is transferred to the label L1 after changing the variable i. And the control goes through the declaration of the array with a value of the variable i.

But the early stored values in the array will be lost.

According to the C Standard (6.2.4 Storage durations of objects)

7 For such an object that does have a variable length array type, its lifetime extends from the declaration of the object until execution of the program leaves the scope of the declaration.35) If the scope is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate.

So either use a character array with a fixed size or reallocate the array dynamically within the loop using the standard function realloc.

Here is a demonstrative program.

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

int main(void) 
{
    char *msg = malloc( sizeof( char ) );
    size_t i = 0;
    
    printf( "Please enter a msg you want to translate: " );

    for ( char c; scanf( "%c", &c ) == 1 && c != '\n'; i++ )
    {
        char *tmp = realloc( msg, i + 1 );
        
        if ( tmp == NULL ) break;
        
        msg = tmp;
        msg[i] = c;
    }
    
    msg[i] = '\0';
    
    printf( "You entered %zu characters: %s\n", i, msg );
    
    free( msg );
    
    return 0;
}

Its output might look like

Please enter a msg you want to translate: Humza Ahmed
You entered 11 characters: Humza Ahmed
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

So here's the issue.

You are defining an array with zero elements:

int i = 0,j = 0;
char msg[i];

If you examine sizeof(msg), you will get zero.

If you examine sizeof(msg[0]) you will get 1 (At element 0 of your array, char is 1 byte).

So your math at the end of the program is correct: 0 / 1 == 0

What you need to do is allocate some space for an array which will give msg a size. If you do this:

char msg[50]

then sizeof(msg) will be 50. Since a char is 1 byte, and you want 50 of them: 50 * 1 == 50

I see what you are going for here. You want to count how many elements a user entered. Unfortunately, you can't use this method. The msg array will always be 50 bytes no matter how many iterations your loop takes.

But, you already are on the right path. You are incrementing i and j every time someone adds something. So at the end of the program you could do:

printf("User entered %d records\n", i);
Andy
  • 12,859
  • 5
  • 41
  • 56