我正在嘗試為學校制定一個專案,而且我已經很接近了。目標是使用終端進行模擬,本質上是使用管道輸入一系列命令并讓它們正確執行。
下面列出了我當前的代碼和輸出,但主要的要點是到目前為止我已經能夠分離命令和引數,但是當嘗試在第 83 行使用 strcat 時,我覺得遇到了分段錯誤。
我試圖添加的行是:
strcat (allargs, print);
}
printf("\n %s -- ALLARGS\n ", allargs);
提取所有引數的字串的最佳方法是什么?當我希望使用 execvp 或 execlp 時,是否有更好的方法來解決這個問題?
謝謝!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <wait.h>
#include <sys/types.h>
#include <unistd.h>
// count number of "|" in string
int count_cmds(char *str)
{
int count = 1; // always will be 1 cmd
for (int i = 0; i < strlen(str); i )
{
if (str[i] == '|')
{
count ;
}
}
return count;
}
char *get_token_at(char *command, size_t n, char *delimiter)
{
size_t position = 0;
char *copy = strdup(command);
char *token = strtok(copy, delimiter);
char *output = NULL;
while (token && position < n)
{
token = strtok(NULL, delimiter);
position ;
}
if (token && position == n)
output = strdup(token);
free(copy);
return output;
}
// trim whitespace
char *trimwhitespace(char *str)
{
char *end;
while (isspace(*str))
str ;
if (*str == 0)
return str;
end = str strlen(str) - 1;
while (end > str && isspace(*end))
end--;
// new end of string
*(end 1) = 0;
return str;
}
// count spaces in a string
int count_spaces(char *str)
{
int count = 0;
for (int i = 0; i < strlen(str); i )
{
if (str[i] == ' ')
{
count ;
}
}
return count;
}
int fd[2];
int x;
int execc(char *command, int i)
{
printf("--- NEW CALL TO EXECC ---------------- COMMAND PASSED: %s \t\t\t\t\t\t ---- NUMBER PASSED: %d\n", command, i);
char *text = trimwhitespace((get_token_at(command, i - 1, "|")));
char *textargs = text;
char *allargs = " ";
for (int k = 0; k < count_spaces(textargs); k )
{
char *print = trimwhitespace((get_token_at(textargs, k 1, " ")));
printf("\n %s -- TEXTARG\n ", print);
}
char *cmd_only = get_token_at(text, 0, " ");
printf("\n %s -- cmd only\n ", cmd_only);
int x = fork();
if (x < 0)
{
perror("fork error");
exit(1);
}
// parent
if (x > 0)
{
printf("IN PARTENT -- wait for child\n");
wait(&x);
return x;
}
// child
if (x == 0)
{
printf("NEW CHILD -- exec or call next \n");
dup2(fd[0], STDIN_FILENO);
if (i == 1)
{
dup2(fd[1], STDOUT_FILENO);
}
close(fd[0]);
close(fd[1]);
if (i == 1)
{
char *z1 = trimwhitespace((get_token_at(command, i - 1, "|")));
printf(" i=1 ---------------- \n%s\n %s \n %s ", z1, z1, trimwhitespace((get_token_at(command, i - 1, " "), NULL)));
// execlp(z1,z1, (trimwhitespace(get_token_at(command, i, " ")), NULL)); // if last command, exec
}
else
{
execc(command, --i); // if not last command, recurse
char *z2 = trimwhitespace(get_token_at(command, i - 1, "|"));
printf("i!=1 --------------------\n%s\n %s \n %s ", z2, z2, trimwhitespace((get_token_at(command, i - 1, " "), NULL)));
// execlp(z2,z2, trimwhitespace((get_token_at(command, i, " "), NULL)));
}
// char* z3 = trimwhitespace(get_token_at(command, i-1, "|"));
// printf("%s\n %s \n %s \n",z3,z3, trimwhitespace((get_token_at(command, i-1, " "), NULL)));
// execlp(z3,z3, trimwhitespace((get_token_at(command, i, " "), NULL)));
}
}
int main(int argc, char *argv[])
{
printf(" Enter Command>");
char cmd[50];
fgets(cmd, 50, stdin);
int num_cmds = count_cmds(cmd);
printf("\n");
printf("Command count: %d\n", num_cmds);
execc(cmd, num_cmds);
pipe(fd);
if (pipe(fd) == -1)
{
printf("Error pipe\n");
exit(1);
}
}
./current 輸入命令>ls -l | 排序-r | grep -h
命令計數:3 --- 新呼叫 EXECC ---------------- 命令已通過:ls -l | 排序-r | grep -h ---- 通過數:3
-h -- TEXTARG
grep -- cmd only IN PARTENT NEW CHILD --- NEW CALL TO EXECC ---------------- COMMAND PASSED: ls -l | sort -r | grep -h ---- NUMBER PASSED: 2
-r -- TEXTARG
sort -- cmd only IN PARTENT NEW CHILD --- NEW CALL TO EXECC ---------------- COMMAND PASSED: ls -l | sort -r | grep -h ---- NUMBER PASSED: 1
-l -- TEXTARG
ls -- cmd only IN PARTENT NEW CHILD
uj5u.com熱心網友回復:
應該定義allargs為 char 陣列,而不是指標,
像這樣:
char allargs[64] = {0};
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/455476.html
標籤:c linux segmentation-fault exec
下一篇:從C中的字串中讀取元素
