How do I pass the address of the first char of a string to a function write to it?
The problem is this: I made a function that takes the output of a certain command from the OS and stores it in a string. The idea now would be to declare a string of just one char in my main function using malloc
, call my function by passing the command I want to pick up the output and also passing the address of the byte that was allocated to my char. From that, I would go expanding my string from initially 1 char using the realloc
inside the other function to store the values that the fscanf
return directly in these spaces.
How could this be done?
Code example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <stdint.h>
int SystemGetOut_char();
int main()
{
char *teste = malloc(1);
char command[] = "ls";
SystemGetOut_char(command, &teste);
return 0;
}
int SystemGetOut_char(char *command, char *output)
{
int chunk = 1;
FILE *fp = popen(command, "r");
int charnumber = 0;
while(fscanf(fp, "%c", &output[charnumber]) != EOF)
{
chunk++;
output = realloc(output, chunk);
charnumber++;
}
pclose(fp);
return 0;
}
Note: I know the code won't work, it's just to get an idea of the structure.
1 answers
In fact the code you have is very close to working, needing only a few adjustments.
You are already passing the address from string
to the function SystemGetOut_char
:
SystemGetOut_char(command, &teste);
// ----^
Which will allow you to change the string
within the function, however the type specified in the function parameter is not correct:
int SystemGetOut_char(char *command, char *output)
// --------^
Can think in generic terms. If you have a char*
and pass your address, then you get a char**
that should be exactly the type of the second parameter. This means that your function has to deal with a double pointer, and with the changes that this entails in the rest of the operations.
Your function with these changes looks like this:
int SystemGetOut_char(char *command, char **output){
// agora duplo ponteiro --------^
int chunk = 1;
FILE *fp = popen(command, "r");
int charnumber = 0;
//aqui a posição de memoria onde guarda o char é dada por *output + charnumber
while(fscanf(fp, "%c", *output + charnumber) == 1)
{
chunk++;
*output = realloc(*output, chunk); //aqui com *output para ser o apontado
charnumber++;
}
(*output)[charnumber] = '\0'; //coloca o terminador no fim
pclose(fp);
return 0;
}
Note that I changed the condition in while
to while (fscanf(...) == 1)
. O fscanf
returns the amount of elements you can assign, and when in this case you can't assign 1
means that it has come to an end and must stop.
I also didn't have to save space for the Terminator because the string already came with an available space, so it always has 1 more than it needs, and this character can be used more for the Terminator.
Since the string
has been changed already inside the function, just show normally in main
:
int main()
{
char *teste = malloc(1);
char command[] = "ls";
SystemGetOut_char(command, &teste);
printf("%s", teste); // <----
return 0;
}
Execution example for the ls
command you have in the code, on my machine: