我是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;
}
我不知道我可以解决这个问题或改变什么。感谢您能提供的任何帮助。
答案 0 :(得分:2)
在tokenize_pipe
中,您要做
args2[i][args_size2] = token;
无需初始化args2[i]
_pipe
中有一种替换方法
char** commands[MAX_ARGS];
作者
char* commands[MAX_ARGS][MAX_ARGS];
,并在tokenize_pipe
中替换
静态字符** 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)
答案 1 :(得分:1)
您没有分配args2
内存
args2[i][args_size2] = token;
应该是
for(...)
{
args2[i] = malloc(sizeof(char *)*Some_Length);
while(token != NULL) {
args2[i][args_size2] = token;
token = strtok(NULL, " ");
args_size2++;
}
}
也
如下进行指针分配不是一个好主意,因为input
字符串可能会在某个时间点改变。
args2[i][args_size2] = token;
代替
args2[i][args_size2] = strdup(token);