-5

I'd like to insert the result of the command system("echo %username%"); in a string, but I can't figure out how I could do it in C. Can someone please help me?

Spikatrix
  • 20,225
  • 7
  • 37
  • 83

2 Answers2

1

Use the POSIX function popen:

#include <stdio.h>

#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])

int main(void)
{
    FILE *f;
    char s[32];
    const char *p;

    f = popen("echo august", "r");
    p = fgets(s, LEN(s), f);
    if (p == NULL) {
        s[0] = '\0';
    }
    pclose(f);

    puts(s);

    return 0;
}
August Karlstrom
  • 10,773
  • 7
  • 38
  • 60
1

Adapted from this C++ solution and a little bit more flexible than August Karlstroms answer you can do something like this:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define S_SIZE 128

char * exec(const char* cmd) 
{
  FILE* pipe = _popen(cmd, "r"); // open a pipe to the command
  if (!pipe) return NULL; // return on Error
  char buffer[S_SIZE];
  int size = S_SIZE;
  char * result = NULL;
  while (fgets(buffer, 128, pipe) != NULL)
  {
    result = realloc(result, size); // allocate or reallocate memory on the heap
    if (result && size != S_SIZE) // check if an error occured or if this is the first iteration 
      strcat(result, buffer);  
    else if (result) 
      strcpy(result, buffer); // copy in the first iteration
    else
    {
      _pclose(pipe);
      return NULL; // return since reallocation has failed!
    }

    size += 128;
  }
  _pclose(pipe);

  return result; // return a pointer to the result string
}

int main(void)
{
  char* result = exec("echo %username%");
  if (result) // check for errors
  {
    printf("%s", result); // print username
    free(result); // free allocated string!
  }
}
Community
  • 1
  • 1
muXXmit2X
  • 2,745
  • 3
  • 17
  • 34
  • Your code invokes Undefined Behavior. Think what the `strcat` would do in the first iteration. Also, why `S_SIZE + 1`? Shouldn't it be just `S_SIZE`? – Spikatrix Mar 31 '16 at 08:58
  • @CoolGuy Ohh. You're right. I did not thought about that when editing the code. But everything should be fine now. – muXXmit2X Mar 31 '16 at 09:18
  • `strlen(result)` results in UB in the first iteration now. Remember: The allocated memory segment is *uninitialized* meaning that it contains some "random" garbage! `strlen` counts the number of characters until a `'\0'`. The result is unpredictable since you access uninitialized memory locations. – Spikatrix Mar 31 '16 at 09:24
  • @CoolGuy I have removed `strlen`. But now there should be no UB anymore, right? – muXXmit2X Mar 31 '16 at 09:29
  • Now it seems to be fine… – Spikatrix Mar 31 '16 at 10:18