繁体   English   中英

C 中的拆分字符串产生分段错误(核心转储)

[英]Splitting String in C procudes Segmentation fault (core dumped)

我正在尝试从键盘读取类似命令的内容,例如start game,info1,info2我想拆分并保存这两个字符串,一个与用户输入的命令类型有关,另一个与信息有关关于命令。 到目前为止,我已经这样做了,它读取并打印由空格字符串分隔的字符串,但之后它遇到了这个Segmentation fault (core dumped)并且控制台程序停止。

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

typedef struct
{
    char *command;
    char *value;
} string;

string *allocate_memory();
void split_command(char* cmd_info, string **s);

int main(void) {
    char cmd[255];
    memset(cmd, 0, 255);
    do
    {
        // read command
        fgets(cmd, 255, stdin);
        cmd[strcspn ( cmd, "\n")] = '\0';

        string *str;
        str = allocate_memory();
        split_command(cmd, &str);

        puts(str->command);
        puts(str->value);

        if(!strcmp(str->command, "start"))
            printf("Starting...\n");

    } while(strcmp(cmd, "exit"));
    printf("Exiting the command line.");
    return 0;
}

string *allocate_memory() {
  string *p;
  if( (p = (string *) malloc(sizeof(string))) == NULL ) {
    printf("Memory allocation failed\n");
    exit(1);
  }
  return p;
}

void split_command(char* cmd_info, string **s) {

    string *new;
    new = allocate_memory();
    char *token;
    while ((token = strsep(&cmd_info, " ")) != NULL)
    {
      printf("%s\n", token);
      new->command = strdup(token);
    }
    new->value = strdup(token);
    puts(new->value);
    *s = new;
    free(cmd_info);

}

编译

gcc cmd.c -o cmd.out

Output

./cmd.out 
one two
one
two
Segmentation fault (core dumped)

我也尝试过其他东西,但我一直遇到分段错误,我真的被卡住了。 任何帮助将不胜感激。 谢谢

当没有找到其他分隔符时, strsep()将标记设置为NULL 然后将NULL传递给strdup() ,从而导致您的分段错误。

我删除了 split_command( while()中的split_command() (我假设它是一个简单的command arg )并在第二个strdup()之前添加了一个检查并让它工作。 我还修复了一些 memory 泄漏:

  • 您在main()中分配str ,然后在split_command()中用new覆盖它,失去对str的引用。
  • 您在每次循环迭代时都分配了一个新字符串,而没有释放前一个字符串
  • 您没有释放使用strdup()创建的字符串

此外,您正在释放cmd_info ,它是在堆栈上静态分配的缓冲区。

这是我的版本:

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

typedef struct
{
    char *command;
    char *value;
} string;

string *allocate_memory();
void split_command(char* cmd_info, string *s);

int main(void) {
    char cmd[255];
    string *str = allocate_memory();
    memset(cmd, 0, 255);
    do {
        fgets(cmd, 255, stdin);
        cmd[strcspn(cmd, "\n")] = '\0';

        split_command(cmd, str);

        if(!strcmp(str->command, "start"))
            printf("Starting...\n");

        free(str->command);
        free(str->value);
    } while(strcmp(cmd, "exit"));
    free(str);
    printf("Exiting the command line.");
    return 0;
}

string *allocate_memory() {
    string *p;
    if( (p = (string *) malloc(sizeof(string))) == NULL ) {
    printf("Memory allocation failed\n");
    exit(1);
    }
    return p;
}

void split_command(char* cmd_info, string *s) {
    char *token = strsep(&cmd_info, " ");

    s->command = strdup(token);
    token = strsep(&cmd_info, " ");
    if (token)
        s->value = strdup(token);
    else
        s->value = NULL;
}

请记住,将NULL传递给puts()会导致问题:始终检查NULL

我试了一下,但是如果你输入的字符串多于两个空格,你一定要修改这段代码。

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

typedef struct
{
    char *command;
    char *value;
} string;
string *split_command(char *cmd);

int main()
{
    char cmd[255];
    while (1)
    {
        fgets(cmd, 255, stdin);
        if (!strcmp(cmd, "exit\n"))
        {
            break;
        }
        cmd[strcspn(cmd, "\n")] = '\0';

        string *str = split_command(cmd);
        puts(str->command);
        puts(str->value);
    }
    return 0;
}

string *split_command(char *cmd)
{
    string *new_string = (string *)malloc(sizeof(string));
    if(new_string == NULL) {
        printf("MEMORY_ALLOCATION_FAILED\n");
        exit(-1);
    }
    char *token = strtok(cmd, " ");
    new_string->command = token;
    token = strtok(NULL, " ");
    new_string->value = token;
    return new_string;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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