-5

why doesn't this code work?

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

int main(void)
{
// local declarations
int len;
char* pStr;

// statements
printf(" how many characters you want to enter?\n");
scanf("%d", &len);
pStr=(char*)calloc(len+1,sizeof(char));
printf("\n enter your string:  ");
gets(pStr);
*(pStr+len)='\0';
printf("\n your string: ");
puts(pStr);
printf(" oops! last character deleted.");

getch();
return 0;
}

although it runs correct, when i use scanf function to read the string, but why it does not with gets?

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • *(pStr+len) -> *(pStr+len*sizeof(char)) – Gar May 30 '16 at 13:31
  • Don't mix usage of scanf with gets . [check this SO answer](http://stackoverflow.com/questions/22226529/program-doesnt-execute-gets-after-scanf-even-using-fflushstdin) – RaidenF May 30 '16 at 13:31
  • 6
    Asking the user how long the input will be is a questionable endeavor. *Trusting* the user's input to match is foolish. @K.Gkinis: Don't use `gets()`, period. It's removed from C for good reason. – EOF May 30 '16 at 13:31
  • @EOF I agree, no reason *not* to prefer scanf anyway. – RaidenF May 30 '16 at 13:33
  • Please indent your code. – Jabberwocky May 30 '16 at 13:57

2 Answers2

3

scanf("%s", pStr) skips to the first non-whitespace character while gets doesn't.

After the first scanf the trailing newline is still in the input buffer so that when you call gets the result is an empty line unless you entered extra characters after the number.

Note that gets is marked as obsolete due to serious security flaws. It is recommended that any use of gets(var) is replaced with fgets(var, length, stdin).

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
1

Because arrays are zero based, and (assuming the input is valid and the correct length, assumption which your code ought not to make) *(ptr + len) already contains \0 and you are just overwriting it. You meant to overwrite ptr[len-1]

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • For great fun as the user, input `0` for the length. – EOF May 30 '16 at 13:45
  • 1
    The first element of the array is indexed by 0. If the array A contains the string "foo", then `A[0] == 'f'`, `A[1] == 'o'`, `A[2] == 'o'`, and `A[3] == '\0'`. Notice that `A[len("foo")] == '\0'`, so it doesn't change the string to overwrite it. – William Pursell May 30 '16 at 13:53
  • pStr is allocated memory for (len+1) bytes. '\0' will be at len +1; not len. –  May 30 '16 at 18:37
  • No, in the string "foo", which has length 3, the `\0` is in the "length + 1" position (eg, the "fourth"), which is at index 3, because arrays are zero based. A[3] is the fourth element of the array. – William Pursell May 31 '16 at 17:38
  • See the statement in which I have allocated memory to pStr, it will be allocated a memory of (len+1) bytes. Let LEN=len+1. Now according to your logic ,string delimiter will be at LEN. In order to make last character null, I should code pStr[LEN-1]='\0', which is correct. Simplifying code we can write pStr[(len+1)-1] which is equivalent to pStr[len] or *(pStr +len), which is correct. This was exactly my logic. –  Jun 01 '16 at 09:47