В настоящее время я создаю простую оболочку для домашней работы, и у меня возникла проблема. Вот фрагмент кода с фрагментами, относящимися к проблеме (возможно, я забыл некоторые фрагменты, пожалуйста, скажите мне, если вы видите что-то не хватает):fgets и chdir действуют странно вместе в C
eatWrd возвращает первое слово из строки и извлекает это слово из Струна.
wrdCount, как подразумевается, возвращает количество слов в строке.
Если какой-либо из этих кодов необходим для ответа, я могу опубликовать их, просто скажите, я почти на 100% уверен, что они не являются причиной проблемы.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 100
int main(void)
{
char input[MAX];
char *argm[MAX];
memset(input, 0, sizeof(input));
memset(argm, 0, sizeof(argm));
while(1){
printf("cmd:\n");
fgets(input, MAX-1, stdin);
for(i=0;i < wrdCount(input); i++){
argm[i] = eatWrd(input);
}
argm[i] = NULL;
if (!strncmp(argm[0],"cd" , 2)){
chdir(argm[1]);
}
if (!strncmp(argm[0],"exit", 4)){
exit(0);
}
memset(input, 0, sizeof(input));
memset(argm, 0, sizeof(argm));
}
}
В любом случае, этот цикл работает для многих других команд, использующих execvp, (например, кошки, LS, и т.д.), когда я использую компакт-диск, он работает, как и ожидалось, за исключением того, когда я пытаюсь выйти из оболочки, для того, чтобы фактически выйти, требуется несколько вызовов выхода. (как оказалось, количество вызовов выхода в точности равно числу раз, когда я вызываю cd). Он принимает только один вызов выхода, когда я не использую cd во время сеанса. Я не совсем уверен, что происходит, любая помощь приветствуется, спасибо.
Вот eatWrd:
char* eatWrd(char * cmd)
{
int i = 0; // i keeps track of position in cmd
int count = 0; // count keeps track of position of second word
char rest[MAX_LINE]; // rest will hold cmd without the first word
char * word = (char *) malloc(MAX_LINE); //word will hold the first word
sscanf(cmd, "%s", word); //scan the first word into word
// iterate through white spaces, then first word, then the following white spaces
while(cmd[i] == ' ' || cmd[i] == '\t'){
i++;
count++;
}
while(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '\n' && cmd[i] != '\0'){
i++;
count++;
}
while(cmd[i] == ' ' || cmd[i] == '\t'){
i++;
count++;
}
// copy the rest of cmd into rest
while(cmd[i] != '\n' && cmd[i] != '\0'){
rest[i-count] = cmd[i];
i++;
}
rest[i-count] = '\0';
memset(cmd, 0, MAX_LINE);
strcpy(cmd, rest); //move rest into cmd
return word; //return word
}
А вот wrdCount:
int wrdCount(char *sent)
{
char *i = sent;
int words = 0;
//keep iterating through the string,
//increasing the count if a word and white spaces are passed,
// until the string is finished.
while(1){
while(*i == ' ' || *i == '\t') i++;
if(*i == '\n' || *i == '\0') break;
words++;
while(*i != ' ' && *i != '\t' && *i != '\n' && *i != '\0') i++;
}
return words;
}
Вы получаете какие-либо дополнительные/отсутствующие подсказки 'cmd:'? И попробуйте использовать отладчик. Он сразу укажет на вашу проблему. –
и что говорит gdb: heppening – pm100
Вы не показываете 'wrdCount' или' eatWrd'. Я определенно буду с подозрением относиться к этим в этот момент. – lurker