I need to make a server that:
1) compiles a c++ file and saves the errors in a file if they exist;
2) if there are no errors i must run the a.out file and extract the output in another file.
The problem resides in the first one.
In order to compile and extract errors i used more methods:
1) system("g++ file.cpp &> err.txt") - not working: it prints the errors in the console but the file remains empty
2) popen - Reference link: C: Run a System Command and Get Output? : the only difference is that i opened another file and instead of printing in the console i used fprintf to write in file.
I forgot to add that the first method works if written as command in console but inside the server is problematic.
// This code is to show what i have already tried and if you find any
// syntax errors like ; or ' pls ignore them as i couldn't copy the code
// from the docker console. Thank you very much!
//1
system("g++ file.cpp &> err.txt");
if( access( "a.out", F_OK ) != -1 ) {
system("./a.out > output.txt");
//2
FILE *f;
char buff[200];
f = popen("g++ file.cpp", "r");
if (f == NULL) {
printf("Failed to run command\n" );
exit(1);
}
FILE *o;
o = fopen("err.txt", "w");
while (fgets(buff, sizeof(buff)-1, f) != NULL) {
fprintf(o, "%s", buff);
}
fclose(o);
fclose(f);
I expected the errors to be written in the err.txt not to be printed in console and in all the above examples it prints in the console and err.txt remains empty.
You can accomplish it the old-school way:
fork() and in the child:
Open a file for storing standard output and another one for errors.
Use dup2(oldfd, newfd) to duplicate the two files' descriptors to stdout, and stderr respectively.
Invoke execlp with gcc and its arguments.
In the parent process you can add waitpid call to wait for the child to finish.
Ok so in the end apparently this one was pretty close: system("g++ file.cpp &> err.txt");
The solution is: system("g++ file.cpp > err.txt 2>&1");
Related
friends. I am using Debian Linux (Raspberry Pi), I want to autostart a program after linux startup.
It's a C program, it can printf on Terminal and fprintf on a text file, I have compiled it and got exe file(file name is test) Path is /home/username/try/test ,the program can run successfully, printf and fprintf can work. After I got exe file, I run command
sudo chmod +x /home/usernane/try/test
Then I create a new folder "autostart" in /home/username/.config Then I run command
cd /home/username/.config/autostart
sudo nano test.desktop
I continue to write desktop file:
[Desktop Entry]
Name=test
exec=lxterminal -e "/home/username/try/test"
Type=Application
After this, I reboot. the program can autostart, but when the program start to fprintf, the program quit. I delete fprintf in code, redo everything, Program can run successful and can printf results.
so problem is fprintf(I want to output results to a txt file)! I tried many ways and can't solved. I need your suggestions, thanks!
I did fprintf as the following: (I run the program normally (Not Autostart), it can work.If autostart, program will quit)
FILE *fp;
char results[50]
/* check if file could be opened */
if((fp=fopen("xy.txt", "w")) == NULL) { // or use "a" instead of "w" to create the file if it doesn't exist
printf("Cannot open file.\n");
exit(1);
}
/* put your results into results[] */
....
/* afterwards writing to file */
fprintf(fp, "%s", results);
fclose(fp);
Have you tried to do it like this?:
FILE *fp;
char results[50]
/* check if file could be opened */
if((fp=fopen("test.txt", "w")) == NULL) { // or use "a" instead of "w" to create the file if it doesn't exist
printf("Cannot open file.\n");
exit(1);
}
/* put your results into results[] */
....
/* afterwards writing to file */
fprintf(fp, "%s", results);
fclose(fp);
I want to execute some executable files from inside a C program using system(). I want to ensure that the command executed completely; after that, I want to use the output of the previously executed command. For example:
{
...
...
sprintf(cmd, "./a1.out > temp.txt");
system(cmd);
fp = fopen("temp.txt", "r");
...
...
}
In this example, it is not ensured that cmd executed completely after that the file is opened for reading. And, I want to ensure that. Any help?
You can use popen() to execute the command and read its output directly.
fp = popen("./a1.out", "r");
if (fp) {
...
r = pclose(fp);
if (r < 0) {
/*...command exited abnormally */
}
} else {
/*...fork or pipe error */
}
You can choose to write the data to a file if that is what is required.
I don't know about the os you are using but under Linux the manual says
system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.
Moreover Posix says
The system() function shall not return until the child process has terminated.
So you are sure that the command is completed.
When an error occurs, I would like my C code to store the error before exiting the program. Is it advised to store the stderr to a file (e.g., /home/logs.txt) or would it be advised to use a different method to keep the logs/error report (considering the programming environment is Linux). E.g., for the code below, how I could apply the method to store the logs/error message on /home/log.txt or /home/log
FILE *fp1;
fp1 = fopen("/sys/class/gpio/export","w");
if(fp1 == NULL){
fprintf(stderr, "errno:%s - opening GPIO136 failed - line 739\n ", strerror(errno));
close(fp1);
exit(1);
}
Thank you.
If stderr is always used to print out all your error message, so, you can redirect output to a specific file.
$ program 2>~/logs.txt
For a better logging tool, you can use:
syslog standard function.
log4c library.
If you want to store the error, stderr is probably not a good choice because you'll need to pipe stderr to a file every time you run the program.
If you want to write to /home/log.txt, open a FILE pointer to it and write with fprintf the same way you tried to open /sys/class/gpio/export and write to that instead of stderr. Also be sure to open the log file with append mode.
FILE *fp1;
fp1 = fopen("/sys/class/gpio/export","w");
if(fp1 == NULL){
FILE *fpErr = fopen("/home/log.txt", "a");
if(fpErr != NULL)
fprintf(fpErr, "errno:%s - opening GPIO136 failed - line 739\n ", strerror(errno));
close(fpErr);
close(fp1);
exit(1);
}
I'm trying to execute a bash command from c and retrieve and show the result.
I've tried with system but it doesn't work.
My code looks like:
char command[200];
sprintf(command,"lsof -iTCP:%d | cut -d\"\" -f1 | tail -1",port);
printf("Port %d is open\n and is listened by %s",port,system(command));
Please help. I need this .
Edit aside from the actual question, I'd be using
sudo netstat -tlpn
(shows the processes that are listening on TCP ports, not resolving the ports/addresses)
Perhaps combine it with a bit of grep:
sudo netstat -tlpn | grep :7761
to find where port :7761 is being listened?
You can use popen.
With popen you get the benefit that you receive the process output asynchronously (you will be able to stop processing if the answer is on the first line of output without having to wait for the subprocess to complete; simply pclose and the subprocess will die with SIGPIPE)
A sample straight from the Standards Documentation:
The following example demonstrates the use of popen() and pclose() to execute the command ls * in order to obtain a list of files in the current directory:
#include <stdio.h>
...
FILE *fp;
int status;
char path[PATH_MAX];
fp = popen("ls *", "r");
if (fp == NULL)
/* Handle error */;
while (fgets(path, PATH_MAX, fp) != NULL)
printf("%s", path);
status = pclose(fp);
if (status == -1) {
/* Error reported by pclose() */
...
} else {
/* Use macros described under wait() to inspect `status' in order
to determine success/failure of command executed by popen() */
...
}
system(command) returns the return code of the command, not its output.
If you want to read the output of a command, you should use popen
This returns a file descriptor to the output, which you can read from just like a normal file.
I'm trying to open a simple .rtf file called test in C. I'm using Xcode. My code is:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
FILE *filePtr;
filePtr = fopen("test.rtf", "r");
if (filePtr == NULL) {
fprintf(stderr, "Can't open \"test\"\n");
exit(EXIT_FAILURE);
}
else {
printf("File open successful\n");
int x;
/* read one character at a time until EOF is reached */
while ((x = fgetc(filePtr)) != EOF) {
printf("%c", x);
}
}
fclose(filePtr);
return 0;
}
I have the test.rtf file in the same directory as my Xcode.proj directory. My output is "File open successful", however I do not get anything read from the file. Am I doing this right? Thanks.
There's nothing wrong with that code at all. I tested it (albeit not in Xcode) with a file and the transcript was:
pax> echo hello >test.rtf
pax> ./qq.exe
File open successful
hello
So the obvious think to ask is what happens when you examine test.rtf? Does it actually have any content? Because, when I do:
pax> rm test.rtf ; touch test.rtf
pax> ./qq.exe
File open successful
I get the same behaviour you observe.
Also try renaming it to test2.rtf temporarily and make sure you get the error. It's possible it may be opening a different copy of the file than what you think (this often happens in Visual C since the directory the program runs in is not always what developers think at first).
It looks right.
As for the lack of output, two possibilities:
Are you sure the file has some content? Maybe ls -l test.rtf or dir test.rft
Possibly it has some control characters which cause the terminal to which it is written to suppress output.
Try moving test.rtf to your build directory. If your project is named MyProject, move it to MyProject/build/Debug/.
I can think of two things that could cause this problem. Either there is an error when calling fgetc, or you are getting output that you don't recognize.
fgetc() will return EOF when the end of the file is reached, or an error occurs. To determine if it's an error, just after your while loop try:
if (ferror(filePtr) != 0) printf("error: %d.\n", errno);
A .rtf file is not a plain text file. It likely contains a bunch of formatting information. You are expecting to see "Hello . . . ". but what you may actually see is something like:
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf250
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040
\f0\fs24 \cf0 Hello . . .
And you are just assuming that is GDB output, not your program's output.
Based upon your recent comments, I think you have an empty file test.rtf in the directory your program is run in, and your real test.rtf file is in some other directory. Maybe your fopen() call at some point was fopen("test.rtf", "w"); instead of fopen("test.rtf", "r");, and you later modified it.
To see the directory your program is running in, add the following to your program after the FILE *filePtr; line:
char pwd[512];
if (getcwd(pwd, sizeof pwd) != -1)
printf("In directory %s\n", pwd);
else
fprintf(stderr, "Need bigger buffer, change '512' above\n");
Then, you can open a terminal, do cd <directory>, and test for yourself if the file you want is the file your program is opening.
You probably want this file to be plain text, not rich text. Rich text has a lot of formatting encoded into the file.