How to run a C file from within another C file? - c

EDIT: The question is flagged for similarity, but it is different as the file is being run in windows and "system()" is giving errors, unlike in the other question asked.
So, What I am trying to achieve is to compile and run a C program from within my C program.
Why?
I have used used fopen to create a file output.c and using fprintf, entered a simple code snippet into it. For instance a simple code snippet looks like this.
#include <stdio.h>
int main()
{
int a,b;
a=10;
scanf("%d", &b);
for(int i=0; i< 10 ; i=i+1)
{
b++;
}
printf("%d", b);
return 0;
}
This is an output file that is being generated, Now i want to run this code from within my original C code.
Is it possible? It Yes, How?
I have tried using
system("gcc output.c -o output.out");
system("./output.out");
but it's giving me an error -->
undefined reference to `WinMain#16' collect2.exe: error: ld returned 1 exit status
For more context, What I am trying to do is open a file, convert it into C and find it's value, So, My approach so far has been to copy paste the content of the file into another file which I have created using:
followed by series of fprint.
Now, I am trying to execute that C file created!
I am open to alternative method too!
Thank You
Edit: This is the initial file
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *output;
output = fopen("experi.c", "w+");
fprintf(output, "#include <stdio.h>\n \n \nint main(){\n");
fprintf(output, "int a,b;\n");
fprintf(output, "a=10;\n");
fprintf(output, "scanf(");
fprintf(output, "\"%%");
fprintf(output, "d\"");
fprintf(output, ", &");
fprintf(output, "b");
fprintf(output, ");\n");
fprintf(output, "for(int i=0; i< 10 ; i=i+1)\n");
fprintf(output, "{\n");
fprintf(output, "b++;\n");
fprintf(output, "}\n");
fprintf(output, "printf(");
fprintf(output, "\"%%");
fprintf(output, "d\"");
fprintf(output, ", ");
fprintf(output, "b");
fprintf(output, ");\n");
fprintf(output, "return 0;\n");
fprintf(output, "}\n");
system("gcc experi.c -o a.out");
return 0;
}

Output written to C's stdio streams (such as output in your code) is, by design, buffered. At any given time some/all of the output may be sitting in an internal stream buffer, not yet written out to the file on disk.
But it's the file on disk that the C compiler is going to see when you invoke
system("gcc experi.c -o a.out");
So, before calling system, you need to call fclose to indicate that you're done writing the file. Among other things, this will cause the stdio package to properly flush all buffered output to the on-disk file:
fclose(output);
You can also force the output buffer to be written to disk by calling fflush, and this leaves the file stream open so that you can write more to it later, which is sometimes useful, though probably not what you want here.

Related

Why is my FILE pointer causing an undefined symbol error on mac?

I don't understand why is marking as identifier "FILE" is undefined. Firstly I thought it was because of the includes, but in my code I include <stdio.h>. Then I thought that it was just a "marking" squiggle, but when I execute in the terminal shows segmentation fault, so I don't know what I can do.
Here is my program:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
FILE *fp;
fp = fopen("taula.txt", "W");
for (double i = -0.001; i < 0.001; i += 0.00001) {
fprintf(fp, "%lf %.14lf \n", i, -pow(i,4)*1/(840)+(i*i)*1/(30)-1/3);
}
fclose(fp);
return 0;
}
I'm using Visual Studio Code 1.71.2 (Universal), clang as compiler and the OS I use is macOS Monterey 12.6 in MacBook Pro with M1 Pro.
I hope someone can solve my problem.
The error reported for FILE seems unwarranted. Check these possibilities:
maybe the compiler cannot find the standard header files, but it should report this as an error too.
is there is an empty file called stdio.h somewhere in your include path?
Note also these problems:
to open the file for writing, you should use "w", not "W".
you should test for fopen failure, which probably happens because of the above mistake.
the number of iterations in the loop may not be exactly 200 because of cumulative errors adding 0.00001, which cannot be represented exactly using binary floating point representation.
the expression -pow(i,4)*1/(840)+(i*i)*1/(30)-1/3 seems incorrect: 1/3 evaluates to 0 because it uses integer arithmetics.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
FILE *fp = fopen("taula.txt", "w");
if (fp == NULL) {
fprintf(stderr, "cannot open taula.txt: %s\n", strerror(errno));
return 1;
}
for (double j = -100; j < 100; j += 1) {
double i = j / 100000.;
double i2 = i * i;
fprintf(fp, "%f %.14f\n", i, -i2*i2/840. + i2/30. - 1./3.);
}
fclose(fp);
return 0;
}
I cannot say why it claims that FILE is undefined — on that front, your code looks fine to me, and it compiles without issues (and since you can run it, I assume it must have compiled for you too, which it wouldn't have if FILE was indeed undefined).
It does, however, segfault. I strongly recommend that you check that the return value of fopen isn’t NULL, and, when you have found out that it is, that you read the fopen manpage carefully, especially the section on what the legal values for the second argument are.
EDIT: And the comment about constants being ints is worth listening to, even if that’s unlikely to cause segfaults.

system() function doesn't produce expected output file

F
I'm using Graphviz to render .dot file as graphs, and typically I would write in my terminal :
dot -Tpng yourFile.dot -o yourOutput.png to produce a .png image representing my graph. (I'm using a Unix environment btw)
Now let's say I have the following C function:
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 255
typedef struct placeholder mystruct;
struct placeholder {
...
}
void outputGraph(mystruct str, char* outputName) {
char command[MAXSIZE];
char* tmpFile = "temp.dot";
char imageFile[MAXSIZE];
snprintf(imageFile, MAXSIZE, "%s.png", outputName);
FILE* file = fopen(tmpFile, "w");
writeStructToFile(str, file);
snprintf(command, MAXSIZE, "dot -Tpng %s -o %s", tmpFile, imageFile);
system(command);
snprintf(command, MAXSIZE, "rm %s", tmpFile);
system(command);
}
(my function WriteStructToFile is another one that I made and is working properly so the problem is somewhere else)
From what I understood about the system() function, it should produce the image output just the same as when I execute the same command myself.
Well, it does execute without any errors, but there is no image in the directory where I'm working.
At first, I thought, it's easy, system() doesn't start a new shell in the same working directory, so I tried to see the output of system(pwd); and it was my current working directory. So back to the starting point.
I also tried to check the value system(command) by doing int status = system(command); and then printf("status : %d\n", status); and, well, it printed 0.
Now I'm kinda clueless, I really don't see why it doesn't produce the image output.
I'd be very interested in any ideas or even solutions you have.
This is not the most elegant code, but it works & may help you debug your problem. It calls dot in three different ways. All three work as expected.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
char command[50];
int rc;
strcpy(command, "dot -Tdot this.gv" );
rc=system(command);
printf("\n\n+++ call #1 returned %d\n", rc);
strcpy(command, "dot -Tdot this.gv -oout1.dot" );
rc=system(command);
printf("\n\n+++ call #2 returned %d\n", rc);
strcpy(command, "dot -Tdot this.gv -o out2.dot" );
rc=system(command);
printf("\n\n+++ call #3 returned %d\n", rc);
return(0);
}
snprintf(command, MAXSIZE, "touch %s", tmpFile);
system(command);
Why do you code that?
You certainly don't need to use system(3) then touch(1). You could use appropriate syscalls(2) (open(2) and close(2) here) or at least fopen(3) followed by fclose(3).
You might in some cases consider using popen(3) with pclose(3)
Of course, after
snprintf(command, MAXSIZE, "dot -Tpng %s -o %s", tmpFile, imageFile);
int bad = system(command);
You need to first check that bad is 0 and you probably want to use stat(2) or access(2) to check that imageFile exists.
There could be many reasons why system with a dot command fails. For example, a bad $PATH variable. I suggest using popen(3) with pclose(3) and probably /usr/bin/dot in the command.
Compile your C code using GCC as gcc -Wall -Wextra -g and use GDB to debug your executable. Both strace(1) and ltrace(1) could help you understand the behavior of your program.
Consider reading Advanced Linux Programming and studying for inspiration the source code of some simple open source Linux shells, such as sash or (more complex) GNU bash.
Be aware that Graphviz could be used as a library.
I wasn't closing the temp.dot file in which I was writing. My mistake.
I shall now remember to always close files that I open!
A big thank you to everyone who helped on here.
(Whether it was for the problem or on how to use properly SO)

Using the system function to run another .cpp file [duplicate]

This question already has an answer here:
Compiling a source file using system(), 'main referenced from implicit entry/start for main executable [closed]
(1 answer)
Closed 6 years ago.
This program is a'grader' program, where I simply request the user to enter the name of a txt file and a .cpp source file which processes the txt file and gets its info. I then compile the source file along with the txt file, which outputs another text file. This new textile is then compared to the output expected(which I have been given as well.).
The system function allows users to run UNIX commands from a C program. When I am trying to compile the source file the user provides
I am getting an error saying that
"_main", referenced from: implicit entry/start for main executable.
clang: error: linker command failed with exit code 1 (use -v to see invocation)
sh: ./myProg: No such file or directory
The source file that I am compiling provided by my professor has one function which looks like this :
#include <stdio.h>
#include <stdlib.h>
#define MAX_VALUES 3
#define OUTPUT_LINES 5
int notmain(int argc, char **argv)
{
/*
* argv is just the file name
*/
//printf(argv[1]);
int values[MAX_VALUES];
int i, j;
FILE *inputFile;
char name [20]="input.txt"; // I have included this piece of code to see if there is a correct output from the source file provided by the user.
if ( (inputFile = fopen(name, "r") ) == NULL) {
printf("Error opening input file.\n\n");
exit(1);
}
for(i = 0; i < MAX_VALUES; i++)
fscanf(inputFile, "%d", &values[i]);
for(i = 0; i < OUTPUT_LINES; i++){
for (j=0; j < MAX_VALUES; j++)
printf("%d ", values[j]*(i+1) + j);
printf("\n");
}
return 0;
}
The code that I have written can be seen below: This code takes the information from the user and then compiles it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_LINES 5
int main(){
char srcfile[200];
char inpfile[200];
char resultfile[200];
printf("Please enter the name of the source file: \n");
scanf("%s",srcfile);
printf("Please enter the name of the input file: \n");
scanf("%s",inpfile);
printf("Please enter the name of the expected result file: \n");
scanf("%s",resultfile);
char test1 [100]="gcc -o myProg ";
char test2 [100]="./myProg ";
strcat(test2,inpfile);
strcat(test2," > ");
strcat(test2,resultfile);
strcat(test1,srcfile);
printf("%s\n",test1); //these are just tests
printf("%s",test2); //these are just tests
if (system(test1)) {
printf("There is an error compiling the program ");
}
if (system(test2)!= 0) {
printf("There is an error running the executable");
}
return 0;
}
If you are looking for the solution I have posted it in the answers
The file you're trying to compile doesn't have a main function, which is the entry point for C programs. This means that it's actually not possible to build that file alone into an executable.
If the name of the function is supposed to be notmain then you'll have to write another source file that has a main function and calls notmain. This second main would belong to the executable your program is compiling, not to your program. You would have three source files:
Your grader program, which handles compilation.
A sort of wrapper file that effectively does:
int main(int argc, char *argv[]) {
notmain(argc, argv);
}
And finally the program to be graded.
You'll also either need to extern the notmain function or provide a header to share it. Your grader program would then compile the wrapper main and the source file to be graded together.
The question: Can you run two c programs with 2 main functions? The answer: Yes . In order to do this you have to use the terminal to compile the program with the two main functions separately. However if they interact with one another Im afraid I don't have a solution to that Now in this specific case here is how I did it. I went to the terminal and wrote. In this case I run one program which runs another program using the system function
gcc -c main.c (this compiles the main function).
Then after that i wrote gcc -o Myprogram main.o
This will create an executable named Myprogram which you can run by writing
./Myprogram
In this case my main method is compiling another source file so I don't need to compile that program as well in the terminal. When i compiled this program it created an output.txt file in the same directory the executable and the source files are in.

input redirection on CMD

Well, I am learning programming in C, and I got an assignment to get 3 characters from an input text file into 3 variables and then print their ASCII values.
I wrote this code:
#include <stdio.h>
int main()
{
char a,b,c;
printf("Insert 3 characters:\n");
a=getch();
b=getch();
c=getch();
printf("%d, %d, %d",(int)a,(int)b,(int)c);
}
I opened a text file (input.txt) and wrote there: "abc".
I managed to compile the code with the MinGW compiler, and on the CMD window that I opened in the folder of the .exe file, I wrote: "Task.exe <input.txt".
The program ran normally. I mean, it waited for me to input 3 characters.
What have I done wrong in my work?
help me please :)
You are asked to read from an input text file.
Why don't you use fopen to open a file handle, and fgetc to read from it?
You could perhaps use fscanf. Don't forget to use the resulting count.
And of course, you should call fclose. Using perror is useful to handle error cases.
So start your code with something that checks that your program has an argument, then fopen it:
int main(int argc, char**argv) {
if (argc<2) { fprintf(stderr, "missing program argument\n");
exit(EXIT_FAILURE); };
FILE* fil = fopen(argv[1], "r");
if (!fil) { perror(argv[1]); exit(EXIT_FAILURE); };
Then run Task.exe input.txt in your console (no redirection needed!).
You should take the habit of reading the documentation of every function you are using, of testing failure cases, of compiling with all warnings & debug info (gcc -Wall -Wextra -std=c99 -g), and of using the debugger (gdb).

Beginner C programmer having problems with string functions

I'm a C noob, going back to school for my masters in CS so I'm taking some time to ramp up my skills. I wanted to see if anybody could lend some assistance on why I'm having problems compiling the following code. I've been following the videos on WiBit.net and develop on a 64 bit Linux environment (Ubuntu 13.10). I am using gedit and the gcc compiler no IDE.
This code runs on my Win 7 VM without errors, however when I try to execute it on my host Linux environment I'm getting errors:
Source Code: This example calls the strcmp and strcmpi functions
#include <stdio.h>
#include <string.h>
int main()
{
char str1[255];
char str2[255];
printf("str1: "); gets(str1);
printf("str2: "); gets(str2);
if(strcmp(str1, str2) == 0)
printf("Strings match exactly!");
else if(strcmpi(str1, str2) == 0)
printf("Strings match when ignoring case!");
return 0;
}
Error Message (Linux ONLY):
$gcc main.c -o demo -lm -pthread -lgmp -lreadline 2>&1
/tmp/ccwqdQMN.o: In function main':
main.c:(.text+0x25): warning: thegets' function is dangerous and should not be used.
main.c:(.text+0x8f): undefined reference to `strcmpi'
collect2: error: ld returned 1 exit status
Source Code 2: This example uses the strupr and strlwr functions
#include <stdio.h>
#include <string.h>
int main()
{
char str1[255];
char str2[255];
printf("str1: "); gets(str1);
printf("str2: "); gets(str2);
strlwr(str1);
strupr(str2);
puts (str1);
puts (str2);
return 0;
}
Error Message (Linux ONLY):
$gcc main.c -o demo -lm -pthread -lgmp -lreadline 2>&1
/tmp/ccWnIfnz.o: In function main':
main.c:(.text+0x25): warning: thegets' function is dangerous and should not be used.
main.c:(.text+0x57): undefined reference to strlwr'
main.c:(.text+0x6b): undefined reference tostrupr'
collect2: error: ld returned 1 exit status
I would love a detailed explanation if someone is willing to help and not tear me apart haha. I know that for best practices we shouldn't use gets due to buffer overflow (for example the user enters a 750 character string). Best practices would use fgets instead but my question is whether I'm getting these errors because these functions aren't part of ANSI C or what. They do show up in the man files on my machine which is throwing me through a loop.
Thanks in advance!
UPDATE:
You guys are awesome. Took all of your advice and comments and was able to revise and make a sample program for string comparison as well as conversion to upper/lower. Glad I was able to get it running on both OSes error free as well.
Sample code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char str[255];
printf("Enter a string: "); fgets(str,255, stdin);
printf("Here is your original string, my master: %s\n", str);
//Now let's loop through and convert this to all lowercase
int i;
for(i = 0; str[i]; i++)
{
str[i] = tolower(str[i]);
}
printf("Here is a lowercase version of your string, my master: %s\n", str);
//Now we'll loop through and convert the string to uppercase
int j;
for(j = 0; str[j]; j++)
{
str[j] = toupper(str[j]);
}
printf("Here is a uppercase version of your string, my master: %s\n", str);
return 0;
}
strcmpi problem: strcasecmp() is the posix standard and so is it in linux.
strupr and strlwr doesn't exist in glibc, although you can implement them with a single line of code, as this:
c - convert a mixed-case string to all lower case
In the compilation, first you can find a warning, because the gcc doesn't find the functions in the included header. In such cases it thinks they are declared as int funcname(void). But later, while linking, it can't find the exported symbols of this nonexistant functions, and thus it can't create the executable. This second error is what stops the compilation.
There are too many difference in the c apis, although the posix standard handles them, microsoft don't follow it.
As you noted, the gets function is unsafe because it does not perform any boundary checking: you have called it with a 255-character string buffer, but if another program wrote a line longer than 255 characters, it could write data into your process's stack, and thereby cause your process to execute malicious code (or at the very least produce a segmentation fault).
Use fgets instead:
printf("str1: "); fgets(str1, 255, stdin);
printf("str2: "); fgets(str2, 255, stdin);
If you read the error output from the compiler carefully, you'll note that it's not issuing an error on your use of gets but a warning. Your code should still compile and execute if you fix the strcmpi call.

Resources