This content originally appeared on DEV Community and was authored by Ertugrul
Part 2: Parsing User Input in a Custom Shell (C Programming)
In this part of my custom shell project, I will explain how to parse user input dynamically in C. Parsing the input correctly is crucial in a shell environment, as commands often include multiple arguments. Instead of relying on fixed-size buffers, I implemented a dynamic memory allocation approach for better flexibility.
Understanding the parser Function
The function parser()
is responsible for:
✅ Splitting the user command into arguments dynamically
✅ Managing memory allocation and reallocation efficiently
✅ Returning an array of arguments for further processing
Breaking Down the Code
#ifndef PARSER_H
#define PARSER_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define arg_buffer_size 4
char **parser(char *command, int *argc);
void free_args(char **args, int argc);
#endif
-
Header Guard (
#ifndef PARSER_H
): Prevents multiple inclusions. -
Constant Definition (
arg_buffer_size
): Sets an initial buffer size for argument storage. -
Function Prototypes: Declares the
parser()
function for splitting the input andfree_args()
for memory cleanup.
Implementation of parser()
char **parser(char *command, int *argc)
{
int size = arg_buffer_size;
int length = 0;
char **args = malloc(size * sizeof(char *));
-
Memory Allocation (
malloc
): Allocates memory for an array of strings. -
Error Handling: Although not explicitly shown,
malloc
should be checked to prevent failures.
*argc = 0;
char *token = strtok(command, " ");
while (token)
{
if (*argc >= size)
{
size *= 2;
args = realloc(args, size * sizeof(char *));
}
args[*argc] = strdup(token);
(*argc)++;
token = strtok(NULL, " ");
}
args[*argc] = NULL;
return args;
}
-
Tokenizing the Input
- Uses
strtok()
to break the input into separate arguments. - Iterates over each token and stores it dynamically.
- Uses
-
Expanding Memory Dynamically (
realloc
)- If the argument count exceeds the allocated size, the buffer is doubled.
-
realloc()
attempts to resize the buffer safely.
-
Storing Arguments
- Each token is duplicated using
strdup()
to avoid memory corruption. - The last argument is set to
NULL
for proper command execution.
- Each token is duplicated using
Cleaning Up Memory
void free_args(char **args, int argc)
{
for (int i = 0; i < argc; i++)
{
free(args[i]);
}
free(args);
}
- Prevents Memory Leaks: Frees each argument and the overall array to ensure efficient memory management.
Integrating the Parser with the Shell
The parser()
function is integrated into the shell’s main loop, allowing commands to be properly processed.
int main(void)
{
Command commands[] = {
{"help", help_action},
{"clr", clear_action},
{"say", say_action},
{"exit", exit_action},
{"cwp", cwp_command},
{"date", date_command},
{"clone", clone_file_command},
{"cut", cut_file_command},
{"read", read_file_command},
{"del", delete_file_command},
{"open", open_program_command},
{"list", list_of_directory}};
int command_count = sizeof(commands) / sizeof(commands[0]);
while (1)
{
int argc;
printf("shell_of_mine => ");
char *command = read_command();
char **args = parser(command, &argc);
execute_command(args, argc, commands, command_count);
free_args(args, argc);
free(command);
}
return 0;
}
- Main Loop: Continuously reads, parses, and executes user commands.
- Dynamic Parsing: The parser extracts arguments dynamically, allowing flexible command handling.
-
Memory Cleanup:
free_args()
ensures allocated memory is released after execution.
Why This Approach?
📌 Handles Arbitrary Command Lengths: Unlike static arrays, dynamic allocation ensures flexibility.
📌 Efficient Memory Management: Uses realloc()
to optimize memory usage dynamically.
📌 Prevents Buffer Overflow: Eliminates fixed-size limitations that could lead to errors.
Next Part: Executing Commands 🚀
In the next part, I will explain how the shell executes parsed commands using system calls and function pointers. Stay tuned! 😊
📂 GitHub: https://github.com/Ertugrulmutlu/shell_of_mine
What do you think about this approach? Would you handle parsing differently? Let me know in the comments! 👇
This content originally appeared on DEV Community and was authored by Ertugrul

Ertugrul | Sciencx (2025-02-18T11:42:37+00:00) How I Built a Simple Shell in C – A Beginner’s Guide to System Programming (2/3). Retrieved from https://www.scien.cx/2025/02/18/how-i-built-a-simple-shell-in-c-a-beginners-guide-to-system-programming-2-3/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.