Как очистить этот указатель массива в C?
Я пытаюсь сделать базовый bash с использованием системных вызовов, но у меня есть небольшие проблемы с массивом указателей.
Чтобы возобновить мой код, я читаю команды из stdin с read() в буфер, затем использую strsep() для отделения команды от аргументов и всех аргументов в массив. Затем я создаю новый процесс с помощью fork() и выполняю эту команду со связанными аргументами с помощью execvp().
Все это идет в бесконечный цикл до тех пор, пока пользователь не введет "выход" (еще не закодирован). Проблема в том, что после первой итерации мне нужно, чтобы * pArgs был пустым для следующей команды и аргументов. И я не знаю, как это сделать...
Вот мой код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr;
int aCount;
pid_t pid;
while(1) {
write(1, "\e[1;31mmyBash \e[1;32m# \e[0m", 27);
read(0, bBuffer, BUFSIZ);
sPtr = bBuffer;
aCount = 0;
do {
aPtr = strsep(&sPtr, " ");
pArgs[aCount++] = aPtr;
} while(aPtr);
pArgs[aCount-2][strlen(pArgs[aCount-2])-1] = '\0';
// Debug code to output pArgs content
write(1, "|>", 2);
write(1, pArgs[0], strlen(pArgs[0]));
write(1, "<|", 2);
if(strlen(pArgs[0]) > 1) {
pid = fork();
if(pid == -1) {
perror("fork");
exit(1);
}
if(pid == 0) {
execvp(pArgs[0], pArgs);
exit(0);
}
}
}
return 0;
}
PS: Извините, но я не могу предоставить входной и выходной тестовый пример. Надеюсь, это не так сложно понять и исправить, что вам, ребята, это не нужно. Я отправлю это позже, если это будет необходимо...
Просто чтобы прояснить ситуацию:
Я знаю, я спросил, как очистить массив, и я получил ответ на это. Но теперь мне кажется очевидным, что моя проблема была не в этом, а в мусоре, который собирал буфер, как указано в litb. Логичнее завершать строку нулевым символом, чем очищать массив. Вот почему я отмечаю ответ Литба как правильный.
2 ответа
Ваша проблема в том, что вы не добавляете нулевой символ после чтения данных. Итак strsep
звонки не знают, где остановиться. В C строки должны заканчиваться нулевым символом (это называется завершающим нулевым символом).
// don't forget to add error handling at some point (s == -1)
ssize_t s = read(0, bBuffer, BUFSIZ-1);
bBuffer[s] = '\0';
Имея это в виду, я не вижу, какой массив должен быть очищен сейчас, так как execvp
будет читать аргументы до первого нулевого указателя. do
Цикл, тем не менее, добавляет этот нулевой указатель, который является нулевым указателем, возвращаемым последним вызовом strsep
,
Эта проблема, конечно, также может быть решена просто очисткой bBuffer (данные где *pArgs
указывает на после сканирования первой команды). Обратите внимание, что вы должны сделать это также перед первым сканированием, так как вы не можете использовать символы в bBuffer
массив инициализируется для любых разумных значений.
memset(bBuffer, 0, sizeof bBuffer);
Поместите это как раз перед read
вызов (но в любом случае, читать только максимально BUFSIZE-1
, потому что завершающий нулевой символ тоже должен иметь пробел!).
Но, как я показал выше, вам не нужен этот вызов memset. Просто добавьте завершающий нулевой символ вручную.