C 如何用指向存储在另一个数组中的字符串的指针填充字符指针数组?
我正在尝试创建一个shell,但在尝试用用户输入填充*argv[]数组时遇到问题。我调用parse函数,并将每个单词存储到一个2d数组中。我尝试了许多不同的方法将其直接存储到*argv[],但最终决定尝试使用2d数组。是否仍要使用指向2d数组中存储的字符串的指针来填充*argv[]?或者用指向字符串的指针填充*argv[],而不使用2d数组 我尝试了很多其他方法,但我目前的尝试是调用parse函数后的while循环C 如何用指向存储在另一个数组中的字符串的指针填充字符指针数组?,c,arrays,shell,pointers,C,Arrays,Shell,Pointers,我正在尝试创建一个shell,但在尝试用用户输入填充*argv[]数组时遇到问题。我调用parse函数,并将每个单词存储到一个2d数组中。我尝试了许多不同的方法将其直接存储到*argv[],但最终决定尝试使用2d数组。是否仍要使用指向2d数组中存储的字符串的指针来填充*argv[]?或者用指向字符串的指针填充*argv[],而不使用2d数组 我尝试了很多其他方法,但我目前的尝试是调用parse函数后的while循环 int main() { int status, fRedirect, i
int main() {
int status, fRedirect, i;
pid_t pid;
char s[STORAGE];
char p[MAXITEM][STORAGE];
char *argv[MAXITEM];
for(;;) {
printf("\2: ");
scanf("%s", s);
parse(s, p);
while(p[i] != '\0') {
args[i] = *p[i];
}
if(p[0] == EOF)
break;
if(p[0] == '\0')
continue;
pid = fork();
if(pid == 0) {
if(execvp(*p, p) == -1) {
printf("Execution failed!\n");
exit(9);
}
}
if(pid != 0) {
wait(-1, &status, 0);
}
else {
fRedirect = open("/dev/null", O_WRONLY);
dup2(fRedirect, STDOUT_FILENO);
}
}
/*killpg(getpid(), SIGTERM);*/
printf("p2 terminated. \n");
exit(0);
}
void parse(char *s, char p[][STORAGE]) {
int i, j = 0;
while(*s != EOF && *s != '&' && *s != '\n' && *s != ';' && *s != '\0') {
for(i=0; i < strlen(s); i++)
p[j][i] = s[i];
i = i+getword(s);
j++;
}
}
intmain(){
国际地位,FredDirect,i;
pid_t pid;
字符s[存储];
字符p[MAXITEM][STORAGE];
字符*argv[MAXITEM];
对于(;;){
printf(“\2:”);
scanf(“%s”,s);
解析(s,p);
而(p[i]!='\0'){
args[i]=*p[i];
}
if(p[0]==EOF)
打破
如果(p[0]='\0')
持续
pid=fork();
如果(pid==0){
如果(execvp(*p,p)=-1){
printf(“执行失败!\n”);
出口(9);
}
}
如果(pid!=0){
等待(-1,&状态,0);
}
否则{
fRedirect=open(“/dev/null”,仅限O_wr);
dup2(FredDirect,标准文件号);
}
}
/*killpg(getpid(),SIGTERM)*/
printf(“p2终止。\n”);
出口(0);
}
void解析(char*s,char p[][存储]){
int i,j=0;
而(*s!=EOF&&*s!='&'&'&&&*s!='\n'&&&&*s!=';'&&&*s!='\0'){
对于(i=0;i
我在您的代码中看到您包含了char*argv[MAXITEM]。这在传统上不是使用*argv[]
的方式。主函数定义中包含处理*argv[]
内存的代码。可以使用main()中的字符串解析和转换函数,以通常的方式将命令行参数解析为字符串、整数和浮点数。如果你感兴趣,这里有一篇文章解释了,并提供了更多的细节
对于一个简单的字符串参数示例(与您正在做的类似),请看下面它的使用方式,它可能会立即为您解决一些问题,例如简化获取和解析输入的方式
首先,您的问题的答案是:是否仍然可以使用指向存储在2d数组中的字符串的指针来填充*argv[]
?或者用指向字符串的指针填充*argv[]
,而不使用2d数组
没有
但是,您可以用字符串常量填充它。char*Argv[]本身就是一个变量,在main中使用时可以包含字符串数组(指向字符串数组的指针),如下所示:
#include <ansi_c.h>
int main(int argc, char *argv[]) //Note: the`[]` blank brackets allow any string length.
// the `*` allows multiple arguments
{
int i;
for(i=0;i<argc;i++) //argc contains the count of cmd line arguments
{
printf("%s\n", argv[i]); //*argv[] holds multiple string arguments
}
getchar(); //optional - pauses execution so I can see output
return 0;
}
#包括
int main(int argc,char*argv[])//注意:`[]`空括号允许任何字符串长度。
//`*`允许多个参数
{
int i;
对于(i=0;iOk),在对其进行了更多的研究并添加了更多的功能之后,以下是我目前正在使用的功能。据我所知,parse()命令现在使用从命令行中获取的单词填充*argv[]
int main() {
pid_t pid, child_pid;
int argc, inputRedirect;
char *devNull;
devNull = (char *) malloc(10);
strcpy(devNull, "/dev/null");
char *argv[MAXITEM];
char commandLine[STORAGE];
signal(SIGTERM, myhandler);
for (;;) {
printf("p2: ");
scanf("%s", commandLine);
if(commandLine == EOF)
break;
argc = parse(commandLine, argv);
if (argv[0] == '\0')
continue;
if(argv[0] = "cd")
changeDir(argv[1]);
child_pid = fork();
if (child_pid < 0) {
printf("Cannot fork! Terminating...");
exit(1);
} else if (child_pid == 0) {
CHK(inputRedirect = open(devNull, O_RDONLY));
CHK(dup2(inputRedirect, STDIN_FILENO));
CHK(close(inputRedirect));
CHK(execvp(*argv, argv));
}
else {
for(;;) {
CHK(pid = wait(NULL));
if(pid == child_pid)
break;
}
printf("Child's pid is %d\n", child_pid);
}
}
killpg(getpid(), SIGTERM);
printf("p2 Terminated.\n");
exit(0);
}
int parse(char *commandLine, char *argv[]) {
int argc = 0;
char *commandPointer = commandLine;
while (*commandPointer != '\0') {
*argv = commandPointer;
argc++;
getword(commandPointer);
}
*commandPointer = '\0';
*argv = '\0';
return argc;
}
intmain(){
pid_t pid,子pid;
int argc,inputRedirect;
char*devNull;
devNull=(char*)malloc(10);
strcpy(devNull,“/dev/null”);
字符*argv[MAXITEM];
字符命令行[存储];
信号(SIGTERM,myhandler);
对于(;;){
printf(“p2:”);
scanf(“%s”,命令行);
如果(命令行==EOF)
打破
argc=parse(命令行,argv);
如果(argv[0]=='\0')
持续
如果(argv[0]=“cd”)
changeDir(argv[1]);
child_pid=fork();
if(子项pid<0){
printf(“无法分叉!终止…”);
出口(1);
}else if(子项pid==0){
CHK(inputRedirect=open(devNull,仅限ordu));
CHK(dup2(inputRedirect,STDIN_FILENO));
CHK(close(inputRedirect));
CHK(execvp(*argv,argv));
}
否则{
对于(;;){
CHK(pid=wait(NULL));
如果(pid==子项\U pid)
打破
}
printf(“子pid为%d\n”,子pid);
}
}
killpg(getpid(),SIGTERM);
printf(“p2终止。\n”);
出口(0);
}
int解析(char*commandLine,char*argv[]){
int argc=0;
char*commandPointer=commandLine;
而(*commandPointer!='\0'){
*argv=命令指针;
argc++;
getword(命令指针);
}
*commandPointer='\0';
*argv='\0';
返回argc;
}
提示:您的解析函数应该从s填充argv,可能对每个条目使用strdup,那么您的execvp应该看起来像execvp(argv[0],argv);。请注意,从scanf扫描的字符串永远不会包含EOF。在上面的注释中,我应该说“strtok和strdup”不仅仅是strdupshould我的解析函数然后返回char**?还是它也在解析函数之外被填充?奇怪的是,这是要求您从主函数内部填充*argv[]
,还是可以从命令行与argc一起填充它?如果您需要在main()中填充它的话,那么我相信您首先需要进行一些内存分配。如果以传统方式使用,则在从命令行读取参数时,主函数定义会为您处理此问题。进行了彻底的检查,现在argv似乎充满了参数。我尝试发布更新的代码作为答案,但我无法再等待5小时我们的,因为我没有足够的声誉!我会在晚上把它发回。@Ryker我想用argv[]来执行命令,我现在正在做。我用你的for循环的想法来打印*argv[]的内容,似乎正按照我的要求工作