C将字符串拆分成数组只输出第一个标记

时间:2017-11-23 22:09:28

标签: c arrays string

我正在写一个微壳程序作为我大学的家庭作业。 一切顺利,除了一个不完全符合我希望的功能。

我对C编程很陌生,总是使用更高级别的语言。 事实上,我与C合作的唯一一次是在摆弄Arduino。

所以我在提示中输入了一行用户输入内容。我试图将它分成由空格分隔的字符串数组。 我用

初始化了一个数组
    char **args = NULL;
    args = malloc(sizeof(char *) * LINE_LENGTH);

我将它发送到函数parse_line(line,args)

该功能如下所示:

bool parse_line(char *line, char **arr) {
    size_t i = 0;
    char *point;
    point = strtok(line, " ");
    while (point != NULL) {
        arr[i] = malloc(strlen(point) + 1);
        strcpy(arr[i], point);
        point = strtok(NULL, " ");
        i++;
    }
    arr[i] = NULL;

    if (!arr)
        return false;
    return true;
}

事情是,之后在arr中仅存在来自分割线的第一个令牌。 我正在调试它,虽然可变'指向'得到正确的值,它们不会被复制到我的数组中。为什么?我不知道。

哦..而且这一行是一系列字符,一个是动态的。

char * line = NULL;
line = read_input_line();
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>

#define LINE_LENGTH 50

void clear_screen();
void display_prompt(bool clearscr);
char * read_input_line();
void print_line(char *line);
bool parse_line(char *line, char **arr);

int main() {
    bool initialRun = true;

    while (true) {
        // display prompt on the screen
        display_prompt(initialRun);
        if (initialRun)
            initialRun = false;

        // read input line from terminal
        char * line = NULL;
        line = read_input_line();

        // basic commands
        if (line == NULL)
            continue;
        if (strcmp(line, "exit") == 0) {
            free(line);
            exit(EXIT_SUCCESS);
        } else if (strcmp(line, "clear") == 0) {
            clear_screen();
            continue;
        }

        // parse line into array
        char **args = NULL;
        args = malloc(sizeof(char *) * LINE_LENGTH);
        if (!parse_line(line, args)) {
            printf("Error during parsing command \n");
            continue;
        }
    }

    return 0;
}

void clear_screen() {
    printf("\e[2J\e[H");
}

void display_prompt(bool clearscr) {
    if (clearscr)
        clear_screen();
    printf(" >  ");
}

char * read_input_line() {
    char * line = (char *)malloc(sizeof(char) * LINE_LENGTH);
    if (!fgets(line, LINE_LENGTH, stdin))
        return NULL;
    size_t len = strlen(line);
    if (len > 0 && line[len-1] == '\n') {
        line[--len] = '\0';
    }
    return line;
}

void print_line(char *line) {
    printf("%s \n", line);
}

bool parse_line(char *line, char **arr) {
    size_t i = 0;
    char *point;
    point = strtok(line, " ");
    while (point != NULL) {
        arr[i] = (char *)malloc(strlen(point) + 1);
        strcpy(arr[i], point);
        point = strtok(NULL, " ");
        i++;
    }
    arr[i] = NULL;

    for (int j=0; j<i; j++) {
        printf("%s\n", arr[i]);
    }

    if (!arr)
        return false;
    return true;
}

输入:

ls -l -h

1 个答案:

答案 0 :(得分:-1)

arr[i] = NULL;
for (int j=0; j<i; j++) {
    printf("%s\n", arr[i]);
}

您没有使用j作为索引,因此您将NULL发送给printf()。这是未定义的行为。

我建议你一个实现的例子(仍然不是最好的,但初学者就足够了):

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

#define LINE_LENGTH 50

char **parse_line(char *line, size_t *n);

int main(void) {
    while (true) {
        // display prompt on the screen
        printf(" >  ");

        // read input line from terminal
        char line[LINE_LENGTH];
        if (!fgets(line, sizeof line, stdin)) {
            return 1;
        }
        line[strcspn(line, "\n")] = '\0';

        if (strcmp(line, "exit") == 0) {
            exit(EXIT_SUCCESS);
        } else if (strcmp(line, "clear") == 0) {
            printf("\e[2J\e[H");
            continue;
        }

        // parse line into array
        size_t n;
        char **args = parse_line(line, &n);
        if (!args) {
            printf("Error during parsing command \n");
            continue;
        }

        for (size_t i = 0; i < n; i++) {
            printf("%s\n", args[i]);
        }
    }
}

char **parse_line(char *line, size_t *n) {
    char **arr = malloc(sizeof *arr);
    size_t i = 0;
    for (char *token = strtok(line, " "); token != NULL; token = strtok(NULL, " ")) {
        char **tmp = realloc(arr, sizeof *tmp * (i + 2));
        if (tmp == NULL) {
            for (size_t j = 0; j < i; j++) {
                free(arr[j]);
            }
            free(arr);
            return NULL;
        }
        arr = tmp;
        arr[i] = malloc(strlen(token) + 1);
        if (arr[i] == NULL) {
            for (size_t j = 0; j < i; j++) {
                free(arr[j]);
            }
            free(arr);
            return NULL;
        }
        strcpy(arr[i], token);
        i++;
    }
    arr[i] = NULL;
    *n = i;
    return arr;
}