简体   繁体   中英

Find String Length without recursion in C

#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.

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

int str1[25]; 

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

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;
}

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