-> Moreover, the gets() function does not limit the transfer to the size
-> of the supplied buffer, since it does not know that size. The use of
-> fgets() instead is much safer.
DVH> 1: fgets() is for use with files.
What do you think stdin is?
DVH> 2: It works, and works perfectly if you ever bothered to try it.
It works perfectly in the pathological case where < 39 characters are
entered. In other cases, it _can_ work fine, but this is not guaranteed.
DVH> 3: It counts 0 thru 41 standardly. using cin.get() it uses 0 thru 40
DVH> because it already accounts for the NULL on the end.
-> DH>char name[41];
This does NOT account for the "NULL" on the end. Nor does it account for the
nul on the end. YOU have to account for it. The nul must appear anywhere
from name[0] to name[40] since the buffer is only that large.
DVH> Ok? Try it. You'll see that I am right. I use that all the time.
Ever hear of the first internet worm? It was made possible by gets and its
ability to overwrite large amounts of memory.
Anyway, you are _incorrect_, and I would suggest going over your code a
little more carefully. Try the following (it contains code that results in
"undefined results", but most compilers won't complain... it is "bad code"
but it's there to prove a point):
#include
#include
#include
void print10(char* p)
{
int i;
for (i = 0; i < 10; ++i)
{
if (i != 0)
printf(", ");
printf("", p[i]);
}
printf(" : ");
for (i = 0; i < 10; ++i)
{
if (isprint(p[i]))
printf("%c", p[i]);
else
printf(".");
}
printf("\n");
}
int main()
{
char blank1[10] = {0}; /* all nuls */
char buffer[10] = {0}; /* all nuls */
char blank2[10] = {0}; /* all nuls */
printf("Sizes: blank1 , buffer , blank2 \n",
sizeof(blank1), sizeof(buffer), sizeof(blank2));
/* prove the all nuls: */
printf("before copy\n");
printf("blank1: ");
print10(blank1);
printf("buffer: ");
print10(buffer);
printf("blank2: ");
print10(blank2);
/* now copy in 10 characters. */
strcpy(buffer, "0123456789");
/* show the memory now */
printf("after copy\n");
printf("blank1: ");
print10(blank1);
printf("buffer: ");
print10(buffer);
printf("blank2: ");
print10(blank2);
/* blank out everything */
memset(blank1, 0, sizeof(blank1));
memset(buffer, 0, sizeof(buffer));
memset(blank2, 0, sizeof(blank2));
/* get some string */
printf("Enter a string (no more than 19 characters):");
gets(buffer);
/* show the memory now */
printf("after gets\n");
printf("blank1: ");
print10(blank1);
printf("buffer: ");
print10(buffer);
printf("blank2: ");
print10(blank2);
return 0;
}
This compiled cleanly with gcc 2.7.2.1 (EMX 0.9c). The output was:
[0] d:\tmp\src\g>t
Sizes: blank1 , buffer , blank2
before copy
blank1: , , , , , , , , , :
..........
buffer: , , , , , , , , , :
..........
blank2: , , , , , , , , , :
..........
after copy
blank1: , , , , , , , , , :
..........
buffer: , , , , , , , , , :
0123456789
blank2: , , , , , , , , , :
..........
Enter a string (no more than 19 characters):abcdefghijklmn
after gets
blank1: , , , , , , , , , :
mn........
buffer: , , , , , , , , , :
abcdefghij
blank2: , , , , , , , , , :
..........
What I found interesting is the fact that it went BACK... I was expecting
blank2 to be overwritten.
DVH> Ok? Try it. You'll see that I am right. I use that all the time.
David, I challenge YOU to try it.
And post your code to prove it.
---
---------------
* Origin: Tanktalus' Tower BBS (1:250/102)
|