Hi I have a program that needs to compare a string array to a predefined string but when I use the variable args[0] it works in my function strcmp as below
int gash_execute(char **args){
int i;
if(args[0] == NULL){
return 1;
}
for(i = 0; i < gash_command_num(); i++){
if(strcmp(args[0], functions[i]) == 0){
return(*function_address[i])(args);
}
}
return gash_launch(args);
}
However when trying to strcmp args[i] such as below I get a seg fault. Can anyone help me find a solution to this problem?
int gash_execute(char **args){
int i;
if(args[0] == NULL){
return 1;
}
for(i = 0; i < gash_command_num(); i++){
if(strcmp(args[i], functions[i]) == 0){
return(*function_address[i])(args);
}
}
return gash_launch(args);
}
args[] is an array of strings that were previously separated by spaces, this program is for a custom shell, so pretend in my shell command line I input "cat echo ls" args[0] would be "cat" and so on. However now I need to implement i/o redirection. So i need to check every element of args to check if they represent the symbols "<" ">" "|" and if one of them is we can take it from there
Without seeing all the code, or a report from a tool such as valgrind , I can't say for sure. But I can tell you that this loop is full of potential problems.
for(i = 0; i < gash_command_num(); i++){
if(strcmp(args[i], functions[i]) == 0){
return(*function_address[i])(args);
}
}
It's iterating through three arrays ( args
, functions
, and function_address
) based on some function call which takes none of those as variables ( gash_command_num()
) which has an unknown relation to how many elements are actually in those arrays.
And it's using two global variables ( functions
and function_addresses
) which could contain anything.
If all those things are related, I would suggest making that explicit... but I suspect they're not. I suspect your loop logic is wrong. It's comparing args[i]
with functions[i]
. I suspect gash_command_num()
is actually the size of functions
and so the loop is walking off args
.
What I suspect you really want to do is to see if args[0]
matches any function name in functions
and then call the related function . If args[0]
is ls
then you want to check if there's a built in shell function for ls
and call it with all the arguments.
Rather than searching a list over and over again, and having to manage two parallel lists, this would be much better served with a hash table . The keys are the function names, the values are the function pointers. C doesn't have a hash table built in, but there's plenty of libraries for that. Gnome Lib is a solid choice for this and many other basic functionality that C is missing.
Using a hash table, and eliminating the globals, your code reduces to this:
/* For encapsulation */
typedef int(*shell_function_t)(char **);
int gash_execute(char **args, GHashTable *shell_functions){
int i;
if(args[0] == NULL){
return 1;
}
shell_function_t func = g_hash_table_lookup(shell_functions, args[0]);
if( func ) {
return(*func)(args);
}
else {
return gash_launch(args);
}
}
Scanning for pipes is now a separate problem. For that you do want to loop through args
looking for special characters. That is made much simpler if, when you create args
, you ensure it ends with a null pointer.
for(int i = 0; args[i] != NULL; i++) {
...check if args[i] is special...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.