gpt4 book ai didi

c - 如何标记一个 char 数组两次以将其转换为 3D char 数组?

转载 作者:太空宇宙 更新时间:2023-11-04 06:47:25 24 4
gpt4 key购买 nike

我是 C 语言的新手,我需要帮助。我想将以下字符流标记化两次,第一次是在遇到“|”时然后(对于数组中的每个新元素)遇到空格时。

例如

input = "command arg | command arg2 | command arg3 arg4"

commands[0][0] = "command"
commands[0][1] = "arg"

commands[1][0] = "command"
commands[1][1] = "arg2"

commands[2][0] = "command"
commands[2][1] = "arg3"
commands[2][2] = "arg4"

我尝试了以下方法:

int _pipe(char* input){
char** commands[MAX_ARGS];
memcpy(commands, tokenize_pipe(input), sizeof(commands));
return 1;
}

char*** tokenize_pipe(char* input){

static char* args[MAX_ARGS];
static char** args2[MAX_ARGS];

int args_size = 0;
int args_size2 = 0;

char* token = NULL;

token = strtok(input, "|");

while(token != NULL) {
args[args_size] = token;
token = strtok(NULL, "|");
args_size++;
}

args[args_size] = NULL;

for(int i = 0; i < args_size; i++){

token = strtok(args[i], " ");

while(token != NULL) {
args2[i][args_size2] = token;
token = strtok(NULL, " ");
args_size2++;
}

args2[i][args_size2] = NULL;
args_size2 = 0;
}
return args2;
}

我不知道我可以解决这个问题还是要改变什么。我很感激我能得到的任何帮助。

最佳答案

tokenize_pipe 中你可以

 args2[i][args_size2] = token;  

没有初始化args2[i]

一种方法是在_pipe中替换

char** commands[MAX_ARGS];

通过

char* commands[MAX_ARGS][MAX_ARGS];

并在tokenize_pipe中替换

static char** args2[MAX_ARGS];

通过

static char* args2[MAX_ARGS][MAX_ARGS];

当然,这会使用大数组,考虑使用动态数组,使用 malloc 然后使用 realloc 来调整它们的大小。

这里有一个提案,其中 tokenize_pipe 返回一个分配了所有内容的 3D 数组,我还复制了标记。 NULL用于表示行和列结束

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

char*** tokenize_pipe(char* input)
{
char *** r = malloc(1);
size_t nCommands = 0;
char * savePtrCmds;
char * fullcmd = strtok_r(input, "|", &savePtrCmds);

while (fullcmd != NULL) {
char ** tokens = malloc(1);
size_t nTokens = 0;
char * token = strtok(fullcmd, " ");

while (token != 0) {
tokens = realloc(tokens, (nTokens + 2) * sizeof(char *));
tokens[nTokens++] = strdup(token); /* also duplicate the token to allows input to disapear */
token = strtok(NULL, " ");
}
tokens[nTokens] = NULL;

r = realloc(r, (nCommands + 2) * sizeof(char **));
r[nCommands++] = tokens;
fullcmd = strtok_r(NULL, "|", &savePtrCmds);
}

r[nCommands] = NULL;
return r;
}

int main()
{
char *** r;

{
char input[] = "command1 arg | command2 arg2 | command3 arg3 arg4";

r = tokenize_pipe(input);
}

/* here input does not exist anymore */

/* debug */
for (char *** pcmds = r; *pcmds; ++pcmds) {
for (char ** pcmd = *pcmds; *pcmd; ++pcmd)
printf("%s ", *pcmd);
putchar('\n');
}

/* free resources */
for (char *** pcmds = r; *pcmds; ++pcmds) {
for (char ** pcmd = *pcmds; *pcmd; ++pcmd)
free(*pcmd);
free(*pcmds);
}
free(r);

return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wall -Wextra t.c
pi@raspberrypi:/tmp $ ./a.out
command1 arg
command2 arg2
command3 arg3 arg4

valgrind 下执行:

==7301== Memcheck, a memory error detector
==7301== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7301== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==7301== Command: ./a.out
==7301==
command1 arg
command2 arg2
command3 arg3 arg4
==7301==
==7301== HEAP SUMMARY:
==7301== in use at exit: 0 bytes in 0 blocks
==7301== total heap usage: 22 allocs, 22 frees, 1,186 bytes allocated
==7301==
==7301== All heap blocks were freed -- no leaks are possible
==7301==
==7301== For counts of detected and suppressed errors, rerun with: -v
==7301== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

关于c - 如何标记一个 char 数组两次以将其转换为 3D char 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56173133/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com