-1

This is part of an assignment that I'm supposed to submit, this program is supposed to take 2 inputs, a name containing 4 letters and a city containing 5 letters then sub them in that sentence. The problem is that the first word is not being output properly, like if I type john all I get is 'r' instead of the word. I'm new to this and there might be other mistakes, but I wanna fix this one. Help greatly appreciated. :l

#include <stdio.h>


int main(int argc, char **argv)
{

char name1[4];
char city1[5];

printf("\nEnter four letter name:\n");
scanf("%s", name1);
printf("\nEnter five letter city:\n");
scanf("%s", city1);

printf("%s was afraid of the airplane, he walked from %s to Romaine.", name1, city1);

return 0;
}

When I put John and Denver it output "r was afraid of the airplane he walked from Denver to Romaine"

  • 5
    `char city1[5];`, but `"Denver"` has 6 letters before the 0-terminator, so needs at least a `char[7]`. Undefined behaviour, writing outside array bounds. Apparently it overwrote the beginning of `name1`. – Daniel Fischer Jul 13 '13 at 11:58
  • 2
    Common mistakes with strings: a string in C consists of the characters of the string and an additional termination character `\0`, so John needs to be saved as `John\0` (`char[5+]`). – Zeta Jul 13 '13 at 11:59

3 Answers3

1

Aham, so this is a buffer overflow. What you should do is:

I. Allocate two reasonably long buffers. 4 and 5 just make me cry. There's a LINE_MAX macro in <limits.h> which may be useful.

II. Use a safe function that lets you specify how big your buffer is. For example, fgets() is an excellent function for inputting a line of text. Using it also has the benefit that it really always reads an entire line (if the buffer passed to it is large enough). scanf() requires some messing with the %s conversion specifier before you can make it accept whitespace and stuff.

char name[LINE_MAX];
char city[LINE_MAX];
fgets(name, sizeof name, stdin);
fgets(city, sizeof city, stdin);
  • He's asking for a word as input, not a whole line, so the whitespace is useless in this answer. –  Jul 13 '13 at 12:38
  • @DavidOtano Still, `scanf()` is less quite counter-intuitive. He better sticks with `fgets()` (search a bit around on Stack Overflow and you'll see more examples, it's not only me recommending it.) –  Jul 13 '13 at 12:39
  • I understand your concern, and it is a safer alternative, I agree. But he still doesn't need a full line. –  Jul 13 '13 at 12:41
  • @DavidOtano OK, then he will have some bonus functionality for free because I feel benefactor today. –  Jul 13 '13 at 12:44
  • By the way LINE_MAX is only a POSIX macro. –  Jul 13 '13 at 12:59
0
#include <stdio.h>


int main(int argc, char **argv)
{

char name1[8];
char city1[8];

printf("\nEnter four letter name:\n");
scanf("%s", name1);
printf("\nEnter five letter city:\n");
scanf("%s", city1);

printf("%s was afraid of the airplane, he walked from %s to Romaine.", name1, city1);

return 0;
}

The solution: Make sure the character arrays are large enough for the input.

  • 8 is not much better. And `scanf()` is still unsafe (and has other drawbacks as well). –  Jul 13 '13 at 12:18
  • @H2CO3 No it isn't much better, but I stated clearly for him to make his character arrays large enough for the desired input, as I did to compliment his example. –  Jul 13 '13 at 12:36
-1

scanf is an unsafe function as it will fetch data from its input stream and copy it past the end of the buffer you provide if it's not large enough. In addition it will place a nul terminating character at the end of the copied string.

In your example John requires at least 5 characters while Denver at least 7 because you must account for the terminating character.

You should consider using a larger buffer for both strings, or as a better alternative, write your own function which uses a buffer to store the string and then copies it to the final destination buffer (assuming length is enough, truncating otherwise).

Take a look at this answer: How to prevent scanf causing a buffer overflow in C?, there are some common work arounds for your problem.

Community
  • 1
  • 1
Jack
  • 131,802
  • 30
  • 241
  • 343