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.

Author: Isac, 2018-06-20

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:

insert the description of the image here

 6
Author: Isac, 2018-06-21 10:51:16