-1

I am trying to find Length of a string w/o using library function.

char card[16];                  //card number in char array.
unsigned int cardno[16]={0};    //card number in int array for calculations.

int i,length=0,len;
printf("Credit Card Number[without any spaces]: "); 
gets(card);

for(i=0;card[i]!='\0';i++);
len=i;
length=strlen(card);

printf("%d %d",len,length);

But if i enter a 16 digit card number the output is 16 17 but otherwise[card number less than 16 digit] both output is same. Is this effect of pre and post increment or some other thing. Please explain.

ckruczek
  • 2,361
  • 2
  • 20
  • 23
mukesh.kumar
  • 1,100
  • 16
  • 30
  • Which programming language do you use? – slartidan Jun 18 '15 at 06:33
  • @slartidan I use C language. – mukesh.kumar Jun 18 '15 at 06:35
  • 2
    do not use 'gets()' It is depreciated, It is removed in the next C standard, it (amongst other problems) allows the user to overflow the input buffer. Strongly suggest using 'fgets()'. Overrunning the input buffer results in undefined behaviour, which can/will lead to a seg fault event – user3629249 Jun 18 '15 at 06:47
  • @user3629249 thanks for suggestion. – mukesh.kumar Jun 18 '15 at 06:53
  • 1
    in C, a string is terminated with a NUL char ('\0'). A Credit Card has (typically) 16 numbers. so when reading in the value, need to allow room for the NUL char. (and when you use fgets() also need to allow room for the trailing '\n' (which in most OSs is a single char, but in Windows/DOS it is two characters. – user3629249 Jun 18 '15 at 06:56
  • @user3629249 gets was deprecated in the _previous_ C standard and was removed entirely in the current C standard. – Lundin Jun 18 '15 at 06:57
  • using pre or post increment in the for loop has no effect on the number of times the loop is executed (and in some architectures, the pre increment takes one less instruction – user3629249 Jun 18 '15 at 06:58
  • 2
    A semicolon at the end of a for loop is a really bad idea. We can't tell if that's a typo (most often they are), or intentional. If intentional, put the semi colon on a line of its own. – Lundin Jun 18 '15 at 06:59
  • @Lundin, thanks for the update. – user3629249 Jun 18 '15 at 07:00
  • @Lundin Semicolon was Intentional. for loop was just to increase value of i so as to get the length. – mukesh.kumar Jun 18 '15 at 07:08

2 Answers2

2

First, you need a longer char array for a 16 digit number:

char card[17];  // 16 digits + `\0`  

Then try this:

for(len=0; card[len] != '\0'; len++);

Do not rely on the value of i outside the loop.

DrKoch
  • 9,556
  • 2
  • 34
  • 43
  • It's working.Thank you. Will you please explain why it's not working in my way? – mukesh.kumar Jun 18 '15 at 06:50
  • 1
    see @user3629249's comment above. You had abuffer overflow. You wrote a `\0` char in card[16] when entering a 16 digit string while your buffer was declared char card[16] with last available slot at card[15]. The second part is mere readability/understandability. – DrKoch Jun 18 '15 at 06:55
0

The quick answer is to use fgets() to replace the gets()

char *fgets(char *str, int n, FILE *stream)

n -- This is the maximum number of characters to be read (including the final null-character). Usually, the length of the array passed as str is used.

It is unsafe to use the function gets() which could cause stack overflow :) e.g. if you'd like to enter 16 digit card number into the card[16], there is no place to put '\0'.

Eric Tsui
  • 1,924
  • 12
  • 21
  • And I guess your compile tool is not gcc ? Because gcc will friendly remind you like this, "the `gets' function is dangerous and should not be used". – Eric Tsui Jun 18 '15 at 07:26