0

why the length of argv changed here to 1 always in the last line ??

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

int main(int argc, string argv[])
{
    string keyword = argv[1];
    printf("\n%ld\n", strlen(argv[1]) );
    for(int i = 0,length = strlen(argv[1]); i < length; i++)
    {
        keyword[i] = tolower(keyword[i])-'a';
    }
    printf("\n%ld\n", strlen(argv[1]) );
}
2

Actually, it's not always changing to 1 on the last line. The result is always dependent on the input to argv[1]. Specifically, the last number printed depends on where the first 'a' appears in the input string.

Here's what's happening. In the last printf() call, strlen(argv[1]) is measured by the appearance of the end of string marker in the string. But, the string is being changed by the for loop. Consider what the end of string marker really is - '\0', or hexadecimal 0. Now, consider what happens as the string is changed. All of the characters are having 'a' subtracted. When you have an 'a' in the string, you get 'a' - 'a', which becomes hex 0, or the end of string marker.

In short, the first 'a' in the string gets transformed to the end of string marker by the for loop. Then, the last printf() sees that marker and behaves as it is supposed to.

If you want proof, try the following inputs to the program: aaaa, bbba, bbab, baba, bbbb. The last printed number for each case will be 0, 3, 2, 1, and 4 respectively.

This is why it's dangerous to depend on strlen() of a string that you are altering in this way, and a good idea to save the string length in a var before any changes to the string.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

[EDIT: tolower() explanation and test code.]

There is doubt about my comment about how tolower() works. To restate, tolower will change an uppercase char to a lower case char. If the char is anything else, it will simply return whatever that value is, unchanged. This is easily demonstrated with a short program.

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

int main(int argc, char* argv[])
{
    char y, x = 'a';
    y = tolower(x);
    printf("x = %c,  ASCII = %i, y = %c,  ASCII = %i\n", x, x, y, y);

    x = 'A';
    y = tolower(x);
    printf("x = %c,  ASCII = %i, y = %c,  ASCII = %i\n", x, x, y, y);

    x = -65;
    y = tolower(x);
    printf("x = %c,  ASCII = %i, y = %c,  ASCII = %i\n", x, x, y, y);
}

result:

@ide50:~/workspace/test $ ./test
x = a,  ASCII = 97, y = a,  ASCII = 97
x = A,  ASCII = 65, y = a,  ASCII = 97
x = �,  ASCII = -65, y = �,  ASCII = -65
@ide50:~/workspace/test $ 
4
  • so string keyword = argv[1]; is coping the pointer to the string not the string itself
    – Robert
    Jun 12 '16 at 11:01
  • is there away to copy the string itself not just the pointer to it's location in memory
    – Robert
    Jun 12 '16 at 11:02
  • 1
    See strcpy(), strncpy() etc.
    – Cliff B
    Jun 12 '16 at 21:20
  • @CliffB when I grow up I want to be just like you, you have your seat, and a cold beer!
    – MARS
    Jun 13 '16 at 13:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .