Sie fügen eine neun (oder mehr, gets
haben keine Grenzen überprüfende) Zeichenkette an eine drei Zeichen lange Zeichenfolge an (die vier Zeichen und kein Zeichenfolgenabschlusszeichen enthält). Kein String Terminierung überhaupt. Wenn Sie also mit puts
drucken, wird so lange gedruckt, bis ein Zeichenkettenbeendigungszeichen gefunden wird, das irgendwo im Speicher sein kann. Dies ist, kurz gesagt, ein Schulbuchbeispiel von Pufferüberlauf, und Pufferüberläufe führen normalerweise zu undefined Verhalten was Sie sehen.
In C und C++ müssen alle C-Style-Strings beendet werden. Sie werden durch ein Sonderzeichen beendet: '\0'
(oder ASCII-Null). Sie müssen außerdem genügend Speicherplatz für die Zielzeichenfolge in Ihrem strcat
-Aufruf bereitstellen.
Proper, Arbeitsprogramm:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main(void)
{
/* Size is 4 + 10 + 1, the last +1 for the string terminator */
char left[15] = "0000";
/* The initialization above sets the four first characters to '0'
* and properly terminates it by adding the (invisible) '\0' terminator
* which is included in the literal string.
*/
/* Space for ten characters, plus terminator */
char str[11];
/* Read string from user, with bounds-checking.
* Also check that something was truly read, as `fgets` returns
* `NULL` on error or other failure to read.
*/
if (fgets(str, sizeof(str), stdin) == NULL)
{
/* There might be an error */
if (ferror(stdin))
printf("Error reading input: %s\n", strerror(errno));
return 1;
}
/* Unfortunately `fgets` may leave the newline in the input string
* so we have to remove it.
* This is done by changing the newline to the string terminator.
*
* First check that the newline really is there though. This is done
* by first making sure there is something in the string (using `strlen`)
* and then to check if the last character is a newline. The use of `-1`
* is because strings like arrays starts their indexing at zero.
*/
if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
str[strlen(str) - 1] = '\0';
/* Here we know that `left` is currently four characters, and that `str`
* is at most ten characters (not including zero terminaton). Since the
* total length allocated for `left` is 15, we know that there is enough
* space in `left` to have `str` added to it.
*/
strcat(left, str);
/* Print the string */
printf("%s\n", left);
return 0;
}
Sie befinden sich über das Ende Ihres Puffers hinaus. Das ist in der Tat undefiniertes Verhalten. –
Funktion [gets()] (http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) ist veraltet und gefährlich, don benutze es nicht. – this
left ist keine Null-terminierte Zeichenfolge. Sie müssen char left [5] definieren; und dann nach der Schleife hinzufügen links [4] = 0; // Note 0 und nicht '0' –