0
char teamA[20];
char teamB[20];

printf("Enter the name of the teams\n");
gets(teamA);
gets(teamB);

char gamesA[5];
char gamesB[5];

printf("Enter the results of the last 5 games between the two teams (W,D,L)\n");
scanf("%s%s",gamesA , gamesB);

. . . .

printf("%s has %d%% chances to win\n", teamA , pgames( gamesA , gamesB ) );

gamesA and gamesB contain Ws, Ls, and Ds. When gamesB is full (contains 5 characters) the string teamA is not printed, but when gamesB contains less than 5 characters the string teamA is printed.

Can anyone help?

  • 1
    Please show details, like what is in these variables, what actually gets printed and what you want/expect to be printed. – Scott Hunter Dec 05 '19 at 16:57
  • 1
    Can you also add the part where you initialize `teamA` `gamesA` and `gamesB` and also, add `pgames` function – gkpln3 Dec 05 '19 at 16:57
  • And please use proper code formatting in the question. – Eugene Sh. Dec 05 '19 at 16:57
  • If you want to store 5 characters in a string then use: `char game[6]` not `char game[5]`. – jarmod Dec 05 '19 at 16:59
  • 1
    `gets` is depreciated and impossible to use securely. If your textbook is telling you to use it -- throw away the book. No telling what other bad habits it is teaching. See [this answer](https://stackoverflow.com/a/4346650/4996248) about the problems with `gets`. – John Coleman Dec 05 '19 at 17:00
  • @jarmod Thank you very much! It worked! – Spyros Mouchlianitis Dec 05 '19 at 17:02
  • @JohnColeman I found it online. Won't use it again. Thanks for the heads up! – Spyros Mouchlianitis Dec 05 '19 at 17:05
  • 1
    @SpyrosMouchlianitis The problem with `gets` is that it really is a pretty convenient function which isn't really a problem for code where you are the only intended user (though even there it can be hard to debug). Since it is so easy to use, it is easy to fall into the habit of using it, leading to its use in situations where it really is dangerous. It has probably caused tens of millions of dollars in problems over the last several decades. – John Coleman Dec 05 '19 at 17:08
  • 1
    @JohnColeman Good to learn that now, I just started studying Computer Science – Spyros Mouchlianitis Dec 05 '19 at 17:14
  • @SpyrosMouchlianitis Then you might find [c - Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/q/1694036/4996248) good reading. One of the answers mentions the Morris Worm, which was one of the earliest and best known exploits, but definitely not the only one. – John Coleman Dec 05 '19 at 17:18
  • 1
    @SpyrosMouchlianitis You're welcome. I could not see your code earlier, but the symptoms suggested that your two char arrays were adjacent on the stack (they are automatic variables) and they were too short to contain a full string *plus* its null-terminator. When you wrote "ABCDE" (which requires 6 bytes, not 5) into the first char[5], what you actually did was overwrite the first character of the next char[5] with the null terminator from the end of the "ABCDE" string. And that made the second string empty (because its 1st character was now a null terminator). Hence it didn't print anything. – jarmod Dec 05 '19 at 17:25
  • @jarmod Thanks again! You guys helped me a lot! – Spyros Mouchlianitis Dec 05 '19 at 17:31
  • Don't use `*scanf()` on potentially malformed (human) input. **Never** use it without checking its return value. For human input, `fgets()` followed by in-memory parsing of the string is preferable. – DevSolar Dec 05 '19 at 19:55

1 Answers1

1

The way you define your two "strings", gamesA and gamesB, it is very likely that they are linked consecutively in memory. I.e. that gamesB starts at a low address and ends right before gamesA, i.e. the last byte belonging to gamesB is immediatly followed by gamesA.

gamesB         gamesA
[0][1][2][3][4][0][1][2][3][4]

Note that above is speculation. There are no guarantees for this. But often compilers/linkers do it that way.

Now lets see what happens in the situation you describe.

When gamesB is full (contains 5 characters) ...

Well that is the core of the matter, when there are 5 characters read by a scanf("%s", X) into that array of characters of size 5, then that array is actually too small, because there will be a 6th character written, the terminating '\0'.
That terminator will be written one byte beyond the last byte owned by gamesB and end up in the first byte owned by gamesA. This situation means that there is an error in the program (or if you want to see it like that, in the input by the user; but a program should live with any input...).

gamesB         gamesA
[0][1][2][3][4][0][1][2][3][4]
"a  b  c  d  e \0""B  C  D \0 "

In this erroneous situation, you find some 0-terminated characters in gamesB, wrong, but easily printable by anything expecting a 0-terminated character sequence.
In this situation you find in gamesA NO characters whatsoever, and that sequence of no characters is nicely 0-termianted right in the first byte of gamesA. Whatever you had in gamesA is ignored by anything expecting a 0-terminated character sequence.

Just for fun, try inputting 6 characters to gamesB and then print both. You get the whole sequence output as gamesB and just the last character gamesA.

gamesB         gamesA
[0][1][2][3][4][0][1][2][3][4]
"a  b  c  d  e  f \0""C  D\0"
Yunnosch
  • 26,130
  • 9
  • 42
  • 54