Question

#include<stdio.h>
#include<conio.h>
void main()
{
    int str1[25];
    int i=0;
    printf("Enter a string\n");
    gets(str1);
    while(str1[i]!='\0')
    {
        i++;
    }
    printf("String Length %d",i);
    getch();
    return 0;
}

i'm always getting string length as 33. what is wrong with my code.

Était-ce utile?

La solution

That is because, you have declared your array as type int

int str1[25]; 

^^^-----------Change it to `char`

Autres conseils

You don't show an example of your input, but in general I would guess that you're suffering from buffer overflow due to the dangers of gets(). That function is deprecated, meaning it should never be used in newly-written code.

Use fgets() instead:

if(fgets(str1, sizeof str1, stdin) != NULL)
{
  /* your code here */
}

Also, of course your entire loop is just strlen() but you knew that, right?

EDIT: Gaah, completely missed the mis-declaration, of course your string should be char str1[25]; and not int.

So, a lot of answers have already told you to use char str1[25]; instead of int str1[25] but nobody explained why. So here goes:

A char has length of one byte (by definition in C standard). But an int uses more bytes (how much depends on architecture and compiler; let's assume 4 here). So if you access index 2 of a char array, you get 1 byte at memory offset 2, but if you access index 2 of an int array, you get 4 bytes at memory offset 8.

When you call gets (which should be avoided since it's unbounded and thus might overflow your array), a string gets copied to the address of str1. That string really is an array of char. So imaging the string would be 123 plus terminating null character. The memory would look like:

Adress:    0    1    2    3
Content:  0x31 0x32 0x33 0x00

When you read str1[0] you get 4 bytes at once, so str1[0] does not return 0x31, you'll get either 0x00333231 (little-endian) or 0x31323300 (big endian).

Accessing str1[1] is already beyond the string.

Now, why do you get a string length of 33? That's actually random and you're "lucky" that the program didn't crash instead. From the start address of str1, you fetch int values until you finally get four 0 bytes in a row. In your memory, there's some random garbage and by pure luck you encounter four 0 bytes after having read 33*4=132 bytes.

So here you can already see that bounds checks are very important: your array is supposed to contain 25 characters. But gets may already write beyond that (solution: use fgets instead). Then you scan without bounds and may thus also access memory well beyond you array and may finally run into non-existing memory regions (which would crash your program). Solution for that: do bounds checks, for example:

// "sizeof(str1)" only works correctly on real arrays here,
// not on "char *" or something!
int l;
for (l = 0; l < sizeof(str1); ++l) {
    if (str1[l] == '\0') {
      // End of string
      break;
    }
}

if (l == sizeof(str1)) {
  // Did not find a null byte in array!
} else {
   // l contains valid string length.
}

I would suggest certain changes to your code.

1) conio.h

    This is not a header that is in use. So avoid using it. 

2) gets

    gets is also not recommended by anyone. So avoid using it. Use fgets() instead

3) int str1[25] If you want to store a string it should be

     char str1[25]        

The problem is in the string declaration int str1[25]. It must be char and not int

char str1[25]
void main() //"void" should be "int"
{
    int str1[25]; //"int" should be "char"
    int i=0;
    printf("Enter a string\n");
    gets(str1);
    while(str1[i]!='\0')
    {
        i++;
    }
    printf("String Length %d",i);
    getch();
    return 0;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top