gpt4 book ai didi

c - 为什么我的 var 在 while 循环中被改变了?

转载 作者:太空狗 更新时间:2023-10-29 11:38:46 25 4
gpt4 key购买 nike

我需要制作一个程序,接受一些系统命令,如 lsdate 等,并检查是否有包含此命令(文件)的路径。我有变量 commandandparameters 在最后一个 while 循环中开始改变,我不知道为什么。

我放了 puts(commandandparameters); 来表明如果你想运行它输出不好。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
char *arr[5];//for the command and his parameter
char command[10];
int i,j;
char *path=NULL,*tempath,*finalpath,*commandandparameters;
do
{
i=0;
printf("enter new command:");
gets(command);
arr[i]=strtok(command," ");
while(arr[i]!=NULL)//save the command and also the parametrs
{
i++;
arr[i]=strtok(NULL," ");
}
strcpy(commandandparameters,arr[0]);//add first command
for(j=1;j<i;j++)//add the parameters
{
strcat(commandandparameters," ");
strcat(commandandparameters,arr[j]);
}
//now we check if the command in every path
path = getenv("PATH");
tempath = strtok(path,":");
while (tempath != NULL)
{
strcpy(finalpath,tempath);//get the current path
puts(commandandparameters);
strcat(finalpath,"/");//we add '/'
execl(finalpath,commandandparameters,NULL);
tempath = strtok(NULL, ":");//get next path
}
}while(command!="leave");
}

最佳答案

你还没有定义commandandparameters指向的空间:

char *path=NULL,*tempath,*finalpath,*commandandparameters;
...
strcpy(commandandparameters,arr[0]);

你有一个指向随机空间的指针;你复制那个随机空间。你会得到有趣的结果。如果幸运的话,程序会崩溃。如果你运气不好,它会行为不端。

finalpath 也有类似的问题:

    path = getenv("PATH");
tempath = strtok(path,":");
while (tempath != NULL)
{
strcpy(finalpath,tempath);

更糟糕的是,您也在破坏环境。 getenv() 返回的字符串应被视为只读,除非您打算修改 PATH 的值。事实上,在循环之后,您不会剩下太多 PATH(如果第一个元素是 :,则没有 PATH)。

确保您知道每个指针指向的位置。

您的代码有太多潜在的缓冲区溢出问题,令人毛骨悚然。永远不要使用 gets();假设它会把你的电脑炸成碎片。


如果您解决了这些问题,do { ... } while (command != "leave"); 循环就相当于一个无限循环。您不能像那样有用地比较字符串;你需要使用 strcmp()


I try to do a simple program and I see that execl() not work; can someone tell me why "ls" command don't work?

这是对评论中的代码稍作修改的版本。我在打印中添加了两个标题和换行符,但关键的变化是在 execl() 行中。你的原文在评论里;工作版本不是评论。我无法确定这是您的主要问题还是评论中的错字。修改后的代码编译并运行。

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

int main(void)
{
int pid, stat;

if ((pid = fork()) == 0)
{
execl("/bin/ls", "ls", NULL);
//execl("/bin/", "ls", NULL);
printf("1\n");
exit(1);
}
else
{
wait(&stat);
printf("2\n");
}
}

您程序中的代码破坏了 PATH;如果您执行第一个程序失败,此后,它只会在您的原始 PATH 上的第一个目录中查找。您正在尝试使用 execl() 来处理可变数量的参数;这是错误的工作工具。您必须使用 execv() 或其亲戚之一(例如,execvp() 会执行 PATH 搜索而不会弄乱 PATH)。原因是 execl() 需要一组由空指针终止的参数,但您只能在知道有多少参数时才能编写它。你可以这样写:

execl("/bin/ls", "ls", "-l", (char *)0);

但除非您强制每个命令最多有 4 个参数(给定 char *arr[5];)并使用如下模板:

execl(finalpath, arr[0], arr[1], arr[2], arr[3], arr[4]);

您不能使用 execl() 来执行命令。但这将用户限制为最多 N 个参数,这是 Not Acceptable 。 (例如,* 的 shell 扩展可以生成包含 30 个或更多参数的列表。

您的代码也没有将命令名称附加到路径部分; execl() 的第一个参数是程序可执行文件的路径。

因此,使用 execv()(或 execvp()execve(),甚至,如果有, execvpe())。如果找到您执行的命令,则对您的程序进行或多或少的最小修改可以正常工作;如果不是,那是一场小灾难。这是一发炮弹;它不像它应该的那样 fork()execv() — 如果你在修改路径之前 fork ,路径重整就不那么重要了,尽管进程运行会有一个最小到不存在的路径。

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

int main(void)
{
char *arr[5];//for the command and his parameter
char command[100]; // Not 10
int i;
int j;
char *path=NULL;
char *tempath;
char finalpath[200];
char commandandparameters[200];

do
{
i = 0;
printf("enter new command: ");
if (fgets(command, sizeof(command), stdin) == 0)
{
fprintf(stderr, "EOF or error\n");
break;
}
arr[i]=strtok(command, " ");
while (i < (5-1) && arr[i]!=NULL)//save the command and also the parameters
{
printf("arr[%d] = %s\n", i, arr[i]);
i++;
arr[i]=strtok(NULL, " \n");
}
arr[4] = 0;

strcpy(commandandparameters, arr[0]);//add first command
for (j=1;j<i;j++)//add the parameters
{
strcat(commandandparameters, " ");
strcat(commandandparameters, arr[j]);
}
printf("Cmd&Params: %s\n", commandandparameters);

//now we check if the command in every path
path = getenv("PATH");
tempath = strtok(path, ":");
while (tempath != NULL)
{
puts(commandandparameters);
strcpy(finalpath, tempath);//get the current path
strcat(finalpath, "/");//we add '/'
strcat(finalpath, arr[0]);
puts(finalpath);
execv(finalpath, arr);
tempath = strtok(NULL, ":");//get next path
}
} while (strcmp(command, "leave") != 0);
return(0);
}

关于c - 为什么我的 var 在 while 循环中被改变了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13606255/

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