0

This might sound a bit dumb but am confused. I know the strlen() would return the size of the character array in c. But there is something different going on with pointers to character. This is my code:

void xyz(char *number)
{
    int i = 0;
    int length = strlen(number) - 2;
    while(i <= length)
    {
        printf("Number[]: %c",number[i]);
        i++;
    }
}

This prints the entire number I enter (Eg: 12345) but if I remove the -2 the result is not the same. Could anyone tell me what am I missing?

noMAD
  • 7,744
  • 19
  • 56
  • 94
  • 4
    How are you calling this function? How are you initializing `i`? You'll probably understand a lot more clearly if you change the line like this: `printf("Number[%d]: %c\n",i,number[i]);` – David Schwartz Nov 03 '11 at 04:39
  • 5
    Where's `i` being declared and initialized? Also `i` should usually be < `length` not <=. – AusCBloke Nov 03 '11 at 04:41
  • @user1026764: strlen() would NOT return the size of the character array in c, it is returning its length. The amount of non null characters. – eyalm Nov 03 '11 at 05:06
  • your code is working yar.. u should have to init i =0 and its works i checked. you want to remove last 2 character ?? – sam_k Nov 03 '11 at 06:20
  • @user1026764-Hey what you have tried here show it to us.Give the complete code and you didn't initialized the i in above code – Gouse Shaik Nov 03 '11 at 06:21

6 Answers6

6

There's a good chance that you're doing this to a string that you have obtained with fgets or a similar input function. In that case, it may well have the newline at the end still.

If you change your code temporarily to:

void xyz (char *number) {
    int i = 0, length = strlen (number);
    while (i < length)
        printf ("Number[%d]: %c (%d)", i, number[i], number[i]);
        i++;
    }
}

that should also show the numeric codes for all characters.

The problem with encoding something like that - 2 in your function is that it will not work with:

xyz ("123");

since it will stop early, printing out only 12. The caller should be calling with valid data, meaning that it should adjust the value to be a numeric string before calling.


You can see this happening in the following program:

#include <stdio.h>
#include <string.h>

void xyz (char *number) {
    int i = 0, length = strlen(number) - 2;
    while(i <= length)
    {
        printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
        i++;
    }
    puts ("===");
}

void xyz2 (char *number) {
    int i = 0, length = strlen(number);
    while(i < length)
    {
        printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
        i++;
    }
    puts ("===");
}

int main (void) {
    char buff[100];
    printf ("Enter number: ");
    fgets (buff, sizeof (buff), stdin);
    xyz (buff);
    xyz ("12345");
    xyz2 (buff);
    xyz2 ("12345");
    return 0;
}

The (annoted) output of this, if you enter 98765, is:

Enter number: 98765
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55)  # Your adjustment works here because of the newline.
Number[3]: 6 (54)
Number[4]: 5 (53)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51)  # But not here, since it skips last character.
Number[3]: 4 (52)
===
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55)  # Here you can see the newline (code 10).
Number[3]: 6 (54)
Number[4]: 5 (53)
Number[5]:
 (10)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51)  # And proper numeric strings work okay.
Number[3]: 4 (52)
Number[4]: 5 (53)
===

If you're looking for a robust user input function that gets around this problem (and avoids dangerous things like unbounded scanf("%s") and gets), I have one elsewhere on SO (right HERE, in fact) drawn from my arsenal.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • your code is working yar.. u should have to init i =0 and its works i checked. you want to remove last 2 character ?? – sam_k Nov 03 '11 at 06:20
1

Check if this works for you --

void xyz(char *number)
{
    int length = strlen(number);

    while(i < length)
    {
        printf("Number[]: %c",number[i]);
        i++;
    }
}

and this function, if invoked as

xyz("1234");

should print out:

Number[]: 1
Number[]: 2
Number[]: 3
Number[]: 4

Is that what you really wanted ? If so, then let me point 2 mistakes.

1) "i" is not initialized. It is more a question of good practise. Explicitly initialize your loop control variable (to zero in this case), just don't assume it to be set. 2) your while loop condition with "<=" runs 1 extra cycle that it should.

Remember that arrays start from index '0' (zero), and an array of size 10, has valid index from 0 to 9, and C lang uses null character ('\0'), to terminate a string. So, your "1234" is actually stored as:-

string[0] = '1' string[1] = '2' string[2] = '3' string[3] = '4' string[4] = '\0' (<= NULL)

so if your loop-counter (control variable) i=0 at beginning of loop, for first iteration, you pick string[0], and for 2nd iteration (when i=1) you pick string[1]... and this way, the loop should run only 4 times, i.e. when i==4 (i.e. loopcounter < string-length), you must stop & exit loop.

Hope this clears up your doubt and help. If so, please don't forget to accept the answer.

bdutta74
  • 2,798
  • 3
  • 31
  • 54
1

I did this and received an output like this:

strlen(number)-2 removes the last null and the last character, which contains 4.

Output:

Number[]: 1
Number[]: 2
Number[]: 3

Code:

int main()
{
    xyz("1234");
}
void xyz(char *number)
{
    int i=0;
    int length = strlen(number) - 2;
    while(i <= length)
    {
        printf("\nNumber[]: %c",number[i]);
        i++;
    }
}

It works, and you have to initialize i.

Jamal
  • 763
  • 7
  • 22
  • 32
sam_k
  • 5,983
  • 14
  • 76
  • 110
0

strlen() returns the length of the string, but C arrays, and thus strings, are zero indexed. So you want to increment until you reach strlen() - 1. You can do that either by subtracting one from your length and using a less-than-or-equal test - <= - in your while loop or you can just use strlen() and continue your loop as long as your counter is strictly less than your length.

Possibly sources of error:

  1. If you don't initialize i, odds are the value it gets from whatever was previously at that memory location will be well above length. So your while condition will fail on the first execution.
  2. If go past the end of the string, you will see a NULL character - '\0' - at the end of the string, and random garbage past that.
ObscureRobot
  • 7,306
  • 2
  • 27
  • 36
0

My guess is you're using fgets to read in some input. If that's the case, when you enter "12345" and hit enter, your buffer will look like this:

{'1', '2', '3', '4', '5', '\n', '\0'}

As you can see there's 2 characters we don't want. So what we can do for a start is chop off the newline char, '\n' from the end of your buffer.

So pretend this is how we read in the input:

int main(void)
{
   char buff[20];
   fgets(buff, 20, stdin);

   buff[strlen(buff) - 1] = '\0'; /* remove the '\n' */
   xyz(buff);
}

Now that annoying newline character won't be there and what will look like empty output for the last iteration of the loop will be gone. Now for xyz:

void xyz(char *number)
{
   int i, length = strlen(number);
   for (i = 0; i < length; i++)
      printf("Number[%d]: %c", i, number[i]);
}

Note that we're now not subtracting anything from the length. This is for 2 reasons: the first that I mentioned above about the newline, and secondly because the condition is now < length as opposed to <= length (which I mentioned in the comment above). <= length means that we would be reading 1 past the end of the string (the '\0' character), since the first index is number[0] and the last number[length - 1].

AusCBloke
  • 18,014
  • 6
  • 40
  • 44
0

You would actually have to do:

int length = strlen(number) - 1;

To get the correct output.

In addition, you have to remember that you are passing a character array to your xyz function. So if you did the following:

xyz("12345")

your length would be 5 bytes. In your while loop, your for number[i] index actually starts at 0, not 1, thus you need to subtract 1 to get the correct result, hence you use int length = strlen(number) - 1.

Eranga
  • 32,181
  • 5
  • 97
  • 96
brazc0re
  • 253
  • 4
  • 13