int main(int argc, const char * argv[]) AND file input - c

I've never used,
int main(int argc, const char * argv[])
For most programs, I usually just compile in terminal (using mac) using two separate C files, example…
gcc functions.c main.c
But now I need to use int main(int argc, const char * argv[])… I just don't know if I'm using it correctly. Heres some code…
I compile in the command line doing…
gcc main.c input.txt
terminal tells me…
ld: file too small for architecture x86_64
collect2: ld returned 1 exit status
NOTE my functions work (i tested without using file input) and are in main.c also… i just didn't include them in this post. Also, node is just a basic node struct to a linked list.
int main(int argc, const char * argv[])
{
FILE *input;
input = fopen(argv[1], "r");
node *list = malloc(sizeof(node));
char *string = malloc(sizeof(char)*1023);
fscanf(input, "%s", string);
//convert a string to linked list
list= sTol(string);
//print the linked list
printList(list);
return 0;
} // end main()
Am i completely wrong? the input simply contains one line that says 'hello'. All I'm trying to do is read that into my program and print it just to verify I'm reading my input correctly.

This is not like a perl script or shell script, where you run
perl main.pl input.txt
With a compiled language like C, you first compile the program into an executable
gcc main.c -o myprogram
and then run the executable with the input file
./myprogram input.txt

Related

dynamic file compilation with gcc in c

I'm trying to find a method to, from a program, check the presence of one or more ".c" files and load one or more functions of it.
Basically, I would have a "main" program which will check if the "script.c" file exists, and will launch (if it exists) the main() function of this one.
Here is the content of my "main" program before compilation:
int main(int argc, char *argv[]){
...
if(argc == 1){
FILE *file;
if((file = fopen("script.c", "r"))){
printf("file script.c loaded.");
// to compile the script.c file and modify on it the "main()" function to "_main()" (in order to be able to recompile it with the main library) before restarting the program
int ret = system("gcc -c script.c && objcopy --redefine-sym main=_main script.o && gcc main script.o -o main && ./main -l script.o");
printf("ret(0)=%d\n", ret);
}
else{
int ret = system("./main -l");
printf("ret(1)=%d\n", ret);
}
}
else{
if(argc == 3 && strcmp(argv[2], "script.o") == 0){
_main(argc, argv);
}
else{
printf("no file found.\n");
}
}
...
}
He is the content of my "script.c" file:
int main(int argc, char *argv[]){
...
printf("main() function in script.c loaded.\n");
...
}
If the script.c file exists, running main should give:
file script.c loaded.
ret(0)=0
main() function in script.c loaded.
If the script.c file does not exist, running main should give:
file script.c loaded.
ret(1)=0
no file found.
Obviously, this does not work for several reasons.
It is impossible to use the "main" program to recompile the script.o file (especially since this is supposed to be in use)
It is impossible to compile my "main" program with a _main() function that does not exist (on the 1st launch, and potentially on the second too if script.c dont found)
Do you have an idea for me to achieve my goal ?
So from a single executable program (here "main") to be able to check the presence of an external file (here "script.c") and launch one or more functions from it...
PS: Having already seen it in other projects, I know it's possible, but I can't find the solution.
PS2: Only the executable file (main) and potentially the script.c file must be present (therefore no main.c...which therefore perhaps suggests that a "main" file should be merged with the "main.o" associated which would be unpacked and executed)
So from a single executable program (here "main") to be able to check the presence of an external file (here "script.c") and launch one or more functions from it...
I'm going to make an assumption that the main function you mentioned is not the most important and show how you can, from within your program, compile collections of functions into shared libraries that you load and then execute functions (other than main) in.
A simple driver could look like this:
// driver.c
#include <dlfcn.h> // to be able to dynamically load shared libraries
#include <stdio.h>
#include <stdlib.h>
// the signature of the `start` function you decide to have in all the files:
typedef void(*start_func_t)(void);
int main(int argc, char *argv[]){
char sys[1024];
for(int i = 1; i < argc; ++i) { // loop through all the arguments
// try to compile the argument into an object file
// (use a safer version than sprintf in real code)
sprintf(sys, "gcc -fPIC -c -o %s.o %s", argv[i], argv[i]);
if(system(sys)) {
printf("%d failed\n", sys);
exit(1);
}
// try to create a shared library from the object file
sprintf(sys, "gcc -shared -o libcurrent.so %s.o", argv[i]);
if(system(sys)) {
printf("%d failed\n", sys);
exit(1);
}
// load the shared library you just created
(void)dlerror();
void *handle = dlopen("./libcurrent.so", RTLD_NOW | RTLD_LOCAL);
if(!handle) {
puts(dlerror());
exit(1);
}
// lookup the "start" symbol in the shared library:
start_func_t start = dlsym(handle, "start");
if(!start) {
puts(dlerror());
exit(1);
}
// call the loaded function:
start();
dlclose(handle); // close the library
}
}
You need to link the above program with the dl library, so something like this should work:
gcc -o driver driver.c -ldl
Now, if you create some example files:
// t1.c
#include <stdio.h>
void start(void) { puts("Hello world"); }
// t2.c
#include <stdio.h>
void start(void) { puts("another file"); }
and then run:
./driver t1.c t2.c
It should produce this output if everything works out:
Hello world
another file
I also made a test to see how this works out if I put main in the library. That is, change the start_func_t signature to:
typedef int(*start_func_t)(int argc, char *argv[]);
and load and call main instead:
start_func_t start = dlsym(handle, "main");
if(!start) {
puts(dlerror());
exit(1);
}
// call the loaded function with some example arguments:
char *cargv[] = {
"foo", "hello", "world", NULL
};
start(3, cargv);
and change the test programs slightly:
// t1.c
#include <stdio.h>
int main(int argc, char *argv[]) {
for(int i = 0; i < argc; ++i) {
printf("t1: %s\n", argv[i]);
}
}
// t2.c
#include <stdio.h>
int main(int argc, char *argv[]) {
for(int i = 0; i < argc; ++i) {
printf("t2: %s\n", argv[i]);
}
}
and this worked fine too. However, main is a bit special and I'm not sure if this violates any rules.

multiple definition of main() function with gcc compilation in c

I'm looking for an efficient (fast and secure) method to communicate multiple scripts (and their associated main function ()) to each other. A bit like the principle of the G-WAN project which uses a launcher (./gwan) to read / load / compile different .c files which each contain (or not) a main() function.
Ideally, my launcher should be able to execute the main () functions of other scripts while sharing information through their argv variables.
But as you know, gcc -Wall script1.c script2.c script3.c -o test return me an error of multiple definition of function main(), and gcc -Wl,--allow-multiple-definition -Wall script1.c script2.c script3.c -o test interprets only the first script1.c main() function.
Maybe the solution would be to have a first script (script1.c) which compiles the other scripts (script2.c and script3.c) via a shared variable?
Thanks for your help and sorry for my limited english.
script1.c:
int main(int argc, char *argv[]){
...
int i = main(argc, argv); // main for script2.c
if(i == 0)
main(argc, argv); // main for script3.c
...
return(0);
}
script2.c:
int main(int argc, char *argv[]){
...
return(0);
}
script3.c:
int main(int argc, char *argv[]){
...
return(0);
}
You can't have multiple main function in c, it's simply not allowed, what you can do is have your main function in your first .c file, and whatever you want in your others .c files.
Then you can write :
#include "script2.c"
#include "script3.c"
on top of your script1.c file.
If you want to compute values inside a file and "send" it to main file, you can do it through functions, defined in your other files, since you include it !
Notice that there is no scripts in C !

What is ./nqt in C programming and how do i change file without changing them in the code

So i trying to input multiple files in the assigned program.
My input file code is as such:
int read_File(int *hp, int *d, int *s, char t[])
{
FILE *infile;
infile = fopen("input1.txt", "r");
if (!infile)
{
return 0;
}
else
{
fscanf(infile, "%d", hp);
fscanf(infile, "%d", d);
fscanf(infile, "%d", s);
fscanf(infile, "%s", t);
fclose(infile);
return 1;
}
i did
$>gcc assignedProgram.c -o nqt
$>./nqt input1.txt
but if i want to read input2.txt, i have to change from input1.txt to input2.txt in the codes. Is there anyway to bypass that and read input2.txt without changing from input1.txt to input2.txt in the codes
like when i tried ./nqt input1.txt => it's normal
BUT ./nqt input2.txt it's segmentation fault:11
I tried:
to change "input1.txt" in the codes to "nqt" but that was a dumb idea
and BTW: what is ./nqt
Please help me!
You must write main() as one of the equivalent forms below
int main(int argc, char **argv) { /*...*/ }
int main(int argc, char *argv[]) { /*...*/ }
so that argc and argv are set up by your environment to proper values.
For example
$ ./nqt input.txt
^^^^^ ^^^^^^^^^ --> 1
\\\\\-------------> 0
Translates in your program to
argc == 2
argv[0] ==> pointer to "./nqt"
argv[1] ==> pointer to "input.txt"
argv[2] ==> NULL
When it comes to nqt, it is the name of the program you specified with -o flag when compiling: gcc assignedProgram.c -o nqt. In order to run the program, you need to use ./ prefix, thus ./nqt means "run the program called nqt".
If you want to pass the name of the file as an argument, you should tell main function to accept command line arguments: int argc and char* argv[] (you can read about it here). Then the name of the file you will pass by running ./nqt <filename> would be stored in argv[1], which you should pass to read_File function as an argument.

Execute hello.c file by using file handlers in C

I'm trying my luck with C lately and I came across to this question where I'm stuck.
I've a hello.c file
CODE 1
#include<stdio.h>
#include<stdlib.h>
int main(){
printf("Hello World");
return 0;
}
I open this file and display the content using the following C program (CODE 2)
CODE 2
#include<fcntl.h>
#include<stdio.h>
int main() {
FILE *fd;
char ch;
fd = fopen("/home/hello.c","r");
if( fd != NULL ) {
while((ch = getc( fd )) != EOF){
putchar(ch);
}
}
return 0;
}
However, I want the output of this code to be Hello World, i.e output of the hello.c file which is read.
How can that be done?
In order to run a c file, first you need to compile it into machine code then execute it.
To compile it: run gcc source-file -o executable-file
To run, execute: executable-file
In order to to the same things in C, use system() function from <stdlib.h>
const char* tempFile = "./tempfile";
const char* sourceFile = "hello.c";
const char compileCommand[255];
sprintf(compileCommand, "gcc %s -o %s", sourceFile, tempFile);
system(compileCommand);
system(tempFile);
This code hasn't been tested.
Currently, in the second program, you are reading hello.c file. So the output of CODE2 will be the contents of hello.c. i.e. #include<stdio.h>...
For what you need, in CODE1, you need to write the output of the program into a separate file (say a.txt) and then read a.txt in CODE2.
Hope this is a sufficient hint for you to solve further.
Your "CODE 2" would have to invoke a C-compiler to compile "CODE 1" and then run it using system() or a function provided by your operating system.
BTW: It is either int main(void) or int main(int argc, char** argv), NOT int main().
As general solution, you may try also to have a look to a C interpreter, like Cling, and try to include it in your project.

Extern undefined symbol

I am building a user defined shell where the shell dynamically links libraries
I have the following snippet from the main file that contains the global variable declarations...
char *prompt = "upsh";
int main()
{ ...
then I have a shared library as follows...
extern char *prompt;
int setprompt(char *argv[]) {
prompt = argv[1];
return 0;
}
my problem is that when I link the library from the main program I get the error
./setprompt.so: undefined symbol: prompt
...maybe this is a compilation issue?
As Naveem Kumar commented, you should provide compilation steps. Does the following reproduce what you meant? This worked in my laptop.
Makefile
all: main
libsetprompt.so: setprompt.c
gcc -fPIC -DPIC -shared setprompt.c -o libsetprompt.so
main: main.c libsetprompt.so
gcc main.c -o main -L. -lsetprompt
clean:
rm main libsetprompt.so
main.c
char *prompt = "upsh";
int main(int argc, char *argv[])
{ return 0; }
setprompt.c
extern char *prompt;
int setprompt(char *argv[])
{
prompt = argv[1];
return 0;
}
I do not think it is a comilation issue. If i get it right, you have a console application, which means that argc and argv must be passed to the main function in order to use them, but they are not passed. I guess your problem is that you call int setprompt(char *argv[]) without actually passing argv[]. But i may be wrong, more code would help to tell for sure.
But probably instead of int main() there should be int main(int argc, char **argv)

Resources