You also mention "problems with designing your loops" I will address that topic first.
You repeat all the code again and again and just increment i in between. That is candidate #1 for creating your loop.
DISCLAIMER I assume you are using libft.
ft_split from libft indicates the end of the pointer array by array_of_paths[i]==NULL. Let's use that as condition for your loop.
char **ft_extract_and_delimit_path(char **envp)
{
char **array_of_paths;
int i;
int j;
array_of_paths = NULL;
i = 0;
while(ft_strnstr(envp[i], "PATH", 4) == 0)
i++;
array_of_paths = ft_split(envp[i] + 5, ':');
for (int i = 0; array_of_paths[i] != NULL; i++)
{
j = 0;
while (array_of_paths[i][j] != '\0')
j++;
array_of_paths[i][j] = ft_strjoin(array_of_paths[j], "/");
}
}
That is the loop about all the paths you have in that array.
Now we need to look at your inner loop.
You are using ft_strjoin which returns a pointer to a string holding both input strings concatenated. You try to assign this into a single character which cannot work.
The string you put into this function uses index j which you used for finding the length of the string but you use it as index into the array of pointers. That will likely cause out of bounds access.
You also don't free the pointer that you had stored there before, causing a memory leak.
It should be like this:
char *tmp = ft_strjoin(array_of_paths[j], "/");
if (tmp != NULL)
{
free(array_of_paths[i]);
array_of_paths[i] = tmp;
}
else
; // Do some error handling
Together your code could look like this (not tested):
char **ft_extract_and_delimit_path(char **envp)
{
char **array_of_paths = NULL;
int i = 0;
while(ft_strnstr(envp[i], "PATH", 4) == 0)
i++;
array_of_paths = ft_split(envp[i] + 5, ':');
for (int i = 0; array_of_paths[i] != NULL; i++)
{
char *tmp = ft_strjoin(array_of_paths[j], "/");
if (tmp != NULL)
{
free(array_of_paths[i]);
array_of_paths[i] = tmp;
}
else
; // Do some error handling
}
}
Finally, I did some improvements (use standard C lib functions, add = in search string as pointed out by Craig Estey,check if there is already a trailing '/' in the string, etc.) and created a complete example with extra printouts for better visibility:
#include <stdio.h>
#include <string.h>
#include "libft/libft.h"
char **ft_extract_and_delimit_path(char **envp)
{
char **array_of_paths = NULL;
int i = 0;
while(strncmp(envp[i], "PATH=", 5) != 0)
i++;
array_of_paths = ft_split(envp[i] + 5, ':');
printf("PATH entries as found in environment:\n");
for (int i = 0; array_of_paths[i] != NULL; i++)
{
printf("%02d: %s\n", i, array_of_paths[i]);
}
printf("\n\nAdd trailing '/' if not already present\n");
for (int i = 0; array_of_paths[i] != NULL; i++)
{
if (array_of_paths[i][strlen(array_of_paths[i])-1] != '/')
{
char *tmp = ft_strjoin(array_of_paths[i], "/");
if (tmp != NULL)
{
free(array_of_paths[i]);
array_of_paths[i] = tmp;
}
else
{
; // Do some error handling
}
}
else
{
printf("Skip %s as it already contains trailing /\n", array_of_paths[i]);
}
}
printf("\n\nPATH entries after adding '/':\n");
for (int i = 0; array_of_paths[i] != NULL; i++)
{
printf("%02d: %s\n", i, array_of_paths[i]);
}
return array_of_paths;
}
char *env[] =
{
"PATH=/usr/sbin:"
"/usr/bin:"
"/sbin:"
"/bin:"
"/mnt/c/Program Files/dotnet/:"
"/mnt/c/Users/X/AppData/Local/Programs/Python/Python39/",
NULL
};
int main(void)
{
(void)ft_extract_and_delimit_path(env);
return 0;
}
For demonstration I used a reduced environment replacement.
The output is:
PATH entries as found in environment:
00: /usr/sbin
01: /usr/bin
02: /sbin
03: /bin
04: /mnt/c/Program Files/dotnet/
05: /mnt/c/Users/X/AppData/Local/Programs/Python/Python39/
Add trailing '/' if not already present
Skip /mnt/c/Program Files/dotnet/ as it already contains trailing /
Skip /mnt/c/Users/X/AppData/Local/Programs/Python/Python39/ as it already contains trailing /
PATH entries after adding '/':
00: /usr/sbin/
01: /usr/bin/
02: /sbin/
03: /bin/
04: /mnt/c/Program Files/dotnet/
05: /mnt/c/Users/X/AppData/Local/Programs/Python/Python39/