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?
Asked
Active
Viewed 63 times
-5

Spikatrix
- 20,225
- 7
- 37
- 83

Luca Morara
- 3
- 4
-
What is your target language? – bschlueter Mar 31 '16 at 06:45
-
@bschlueter ... C? – user253751 Mar 31 '16 at 06:45
-
Sounds like you're looking for `popen()`. – kichik Mar 31 '16 at 06:46
-
Yeah, sorry, I didn't mention it. – Luca Morara Mar 31 '16 at 06:47
-
5There is no standard way to do this. You have no edit your post with the tag for the target OS. – Lundin Mar 31 '16 at 06:48
-
2Discussed many times before: [link 1](http://stackoverflow.com/questions/478898/how-to-execute-a-command-and-get-output-of-command-within-c) [link 2](http://stackoverflow.com/questions/43116/how-can-i-run-an-external-program-from-c-and-parse-its-output) [link 3](http://stackoverflow.com/questions/125828/capturing-stdout-from-a-system-command-optimally) – Sujay Phadke Mar 31 '16 at 06:49
2 Answers
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
-
-
@CoolGuy I have added *pclose* (although the operating system will close the file when the program exits). – August Karlstrom Mar 31 '16 at 09:58
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!
}
}
-
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
-