简体   繁体   中英

How can I cut a string in C?

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

int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "Usage: greeting message name\n");
        exit(1);
    }
    char greeting[20];
    char *name = argv[2];

    // Your code goes here
    for (int i = 0; i < strlen(argv[1]); i++) {
        if (i < 20) {
            greeting[i] = argv[1][i];
        }
        else {
            greeting[i] = '\0';
        }
    }

    int greeting_len = strlen(greeting);
    strcat(greeting, " ");
    strncat(greeting, name, 20-greeting_len-2);

    printf("%s\n", greeting);
    return 0;
}

In this practice, I am required to concatenate the two command line arguments, which are greeting and name , together and separated by a space. What's more, the greeting and the string after concentrated cannot be longer than 20 characters.

When I run ./a.out "Good morninggggggggggggggggggg" "Emmanuel" , there is an error saying

*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)

How can I fix it?

If the message argument is longer than 20 characters, your first loop will write outside the bounds of greeting . The if statement doesn't stop the loop, it keeps going, but assigns null bytes instead of argv[1][i] .

And if the message argument fits into greeting , you never add a null byte at all. The loop stops after copying the last character, not including the null terminator.

You can simply use strncpy() , and then set the last byte of greeting to a null byte.

strncpy(greeting, argv[1], sizeof greeting);
greeting[sizeof greeting - 1] = '\0';

You need to check if you've hit the limit before adding the space:

if (greeting_len < 18) {
    greeting[greeting_len] = ' ';
    greeting[greeting_len+1] = '\0';
    greeting_len++;
}
if (greeting_len < 18) {
    strncat(greeting, name, 19-greeting_len);
}

But if you can use snprintf() it's all much easier:

snprintf(greeting, sizeof greeting, "%s %s", argv[1], name);

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. properly checks for (and handles) errors
  4. has no openings for undefined behavior nor buffer overflows
  5. places a space between argv[1] and argv[2]

and now, the proposed code:

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

int main(int argc, char **argv) 
{
    if (argc != 3) 
    {
        fprintf(stderr, "Usage: greeting message name\n");
        exit(1);
    }


    char *greeting = malloc( strlen( argv[1] ) + strlen( argv[2] ) +1 +1 );
    if( !greeting )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }


    strcpy( greeting, argv[1] );
    strcat( greeting, " " );
    strcat( greeting, argv[2] );


    printf("%s\n", greeting);

    free( greeting );
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM