如何创建锯齿状的字符串数组
How to create jagged array of array of strings
我正在编写一个接受命令行参数的程序,我想使用字符串分隔所有参数 "PIPE" 例如我可以写 ls -la PIPE wc.
我的代码
char **args = argv;
int pipes=0;
while(*args)
{
if(strcmp("PIPE",*args) == 0)
{
pipes++;
}
args++;
}
int *pipeIndexes = NULL;
if(pipes > 0)
{
pipeIndexes=(int *)malloc(pipes*sizeof(int));
args = argv;
pipeIndexes[pipes];
int counter=0,i=0;
while(*args)
{
if(strcmp("PIPE",*args) == 0)
{
pipeIndexes = (int *)realloc(pipeIndexes,sizeof(int)*(counter+1));
pipeIndexes[counter] = i;
counter++;
}
i++;
args++;
}
}
现在我想做的是创建另一个数组来存储每个程序的参数?例如。
programs = { {"ls","-la"},{"wc"}}
恭喜,您发现了 char ***
的用例。 C 中的锯齿状数组最好实现为指针数组,因此您需要一个(动态分配的)指针数组数组。
在下面的代码片段(未经测试)中,留作练习根据需要调用 realloc
来增加数组。
char ***programs = malloc(10 * sizeof(char **)); /* arbitrary small size */
int prog = 0, arg = 0;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "PIPE") == 0) {
programs[prog][arg] = NULL;
arg = 0;
prog++;
/* realloc programs if needed */
programs[prog] = malloc(20 * sizeof(char *));
} else {
programs[prog][arg++] = argv[i];
/* realloc programs[prog] if needed */
}
}
programs[prog][arg] = NULL;
/* realloc programs if needed */
programs[++prog] = NULL;
每个(子)数组以 NULL 结束以标记其结束的提议,因此例如 ls -la PIPE wc
产生 { {"ls","-la",NULL},{"wc",NULL},NULL}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
if (argc == 1) {
puts("at least an argument must be given");
return -1;
}
char *** commands = NULL;
size_t nCommands = 0;
do {
commands = realloc(commands, (nCommands + 2)*sizeof(char **));
char ** command = NULL;
size_t n = 0;
while ((*++argv != NULL) && strcmp(*argv, "PIPE")) {
command = realloc(command, (n + 2)*sizeof(char *));
command[n++] = *argv; /* may be strdup(*argv) */
}
if (n == 0)
puts("invalid PIPE");
else {
command[n] = NULL; /* marks the end */
commands[nCommands++] = command;
}
} while (*argv);
if (nCommands == 0)
puts("no command");
else {
commands[nCommands] = NULL; /* marks the end */
/* debug, print result, free ressources */
char *** pcommands = commands;
while (*pcommands) {
char ** pcommand = *pcommands;
while (*pcommand)
printf("%s ", *pcommand++);
putchar('\n');
free(*pcommands++);
}
free(commands);
}
}
编译和执行:
/tmp % gcc -g -pedantic -Wall -Wextra aa.c
/tmp % ./a.out ls -la PIPE wc
ls -la
wc
/tmp % ./a.out ls
ls
/tmp % ./a.out
at least an argument must be given
/tmp % ./a.out ls PIPE PIPE wc
invalid PIPE
ls
wc
vxl15036 /tmp % ./a.out ls PIPE
invalid PIPE
ls
在valgrind
下执行
/tmp % valgrind ./a.out ls -la PIPE wc
==9808== Memcheck, a memory error detector
==9808== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==9808== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==9808== Command: ./a.out ls -la PIPE wc
==9808==
ls -la
wc
==9808==
==9808== HEAP SUMMARY:
==9808== in use at exit: 0 bytes in 0 blocks
==9808== total heap usage: 5 allocs, 5 frees, 96 bytes allocated
==9808==
==9808== All heap blocks were freed -- no leaks are possible
==9808==
==9808== For counts of detected and suppressed errors, rerun with: -v
==9808== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
我正在编写一个接受命令行参数的程序,我想使用字符串分隔所有参数 "PIPE" 例如我可以写 ls -la PIPE wc. 我的代码
char **args = argv;
int pipes=0;
while(*args)
{
if(strcmp("PIPE",*args) == 0)
{
pipes++;
}
args++;
}
int *pipeIndexes = NULL;
if(pipes > 0)
{
pipeIndexes=(int *)malloc(pipes*sizeof(int));
args = argv;
pipeIndexes[pipes];
int counter=0,i=0;
while(*args)
{
if(strcmp("PIPE",*args) == 0)
{
pipeIndexes = (int *)realloc(pipeIndexes,sizeof(int)*(counter+1));
pipeIndexes[counter] = i;
counter++;
}
i++;
args++;
}
}
现在我想做的是创建另一个数组来存储每个程序的参数?例如。
programs = { {"ls","-la"},{"wc"}}
恭喜,您发现了 char ***
的用例。 C 中的锯齿状数组最好实现为指针数组,因此您需要一个(动态分配的)指针数组数组。
在下面的代码片段(未经测试)中,留作练习根据需要调用 realloc
来增加数组。
char ***programs = malloc(10 * sizeof(char **)); /* arbitrary small size */
int prog = 0, arg = 0;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "PIPE") == 0) {
programs[prog][arg] = NULL;
arg = 0;
prog++;
/* realloc programs if needed */
programs[prog] = malloc(20 * sizeof(char *));
} else {
programs[prog][arg++] = argv[i];
/* realloc programs[prog] if needed */
}
}
programs[prog][arg] = NULL;
/* realloc programs if needed */
programs[++prog] = NULL;
每个(子)数组以 NULL 结束以标记其结束的提议,因此例如 ls -la PIPE wc
产生 { {"ls","-la",NULL},{"wc",NULL},NULL}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
if (argc == 1) {
puts("at least an argument must be given");
return -1;
}
char *** commands = NULL;
size_t nCommands = 0;
do {
commands = realloc(commands, (nCommands + 2)*sizeof(char **));
char ** command = NULL;
size_t n = 0;
while ((*++argv != NULL) && strcmp(*argv, "PIPE")) {
command = realloc(command, (n + 2)*sizeof(char *));
command[n++] = *argv; /* may be strdup(*argv) */
}
if (n == 0)
puts("invalid PIPE");
else {
command[n] = NULL; /* marks the end */
commands[nCommands++] = command;
}
} while (*argv);
if (nCommands == 0)
puts("no command");
else {
commands[nCommands] = NULL; /* marks the end */
/* debug, print result, free ressources */
char *** pcommands = commands;
while (*pcommands) {
char ** pcommand = *pcommands;
while (*pcommand)
printf("%s ", *pcommand++);
putchar('\n');
free(*pcommands++);
}
free(commands);
}
}
编译和执行:
/tmp % gcc -g -pedantic -Wall -Wextra aa.c
/tmp % ./a.out ls -la PIPE wc
ls -la
wc
/tmp % ./a.out ls
ls
/tmp % ./a.out
at least an argument must be given
/tmp % ./a.out ls PIPE PIPE wc
invalid PIPE
ls
wc
vxl15036 /tmp % ./a.out ls PIPE
invalid PIPE
ls
在valgrind
下执行/tmp % valgrind ./a.out ls -la PIPE wc
==9808== Memcheck, a memory error detector
==9808== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==9808== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==9808== Command: ./a.out ls -la PIPE wc
==9808==
ls -la
wc
==9808==
==9808== HEAP SUMMARY:
==9808== in use at exit: 0 bytes in 0 blocks
==9808== total heap usage: 5 allocs, 5 frees, 96 bytes allocated
==9808==
==9808== All heap blocks were freed -- no leaks are possible
==9808==
==9808== For counts of detected and suppressed errors, rerun with: -v
==9808== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)