Interface with variable argument list function, by using function pointers - c

I am trying to use an interface of another program, where I have to use the following method:
void iterate_over_entries(Table* table, Func_ptr f, ... )
so the function is designed to call on each table entry the function f() which is user-defined.
The function pointer is defined as:
typedef size_t (*Func_ptr) (char* example, va_list args);
So that means that I have to write a function which is of type Func_ptr in order to manipulate the entries of the table?
So lets say for example I want to whatever - set all strings which have a length below a given one to be "a". Is it then, that I have to put the length into this va_list?
size_t my_method(char* example, va_list args) {
int length = va_arg(args, int);
if (strlen(example) < length) strncpy(example, "a\0", 2);
return 1;
}
So If I did everything so far correct, I only need to call the function, but I have no idea how to do that.. Lets say I want that the command line input sets me the length I allow...
int main(int argc, char** argv){
Table* table; //this is set somehow..
int length = atoi(argv[1]);
size_t (*method)(char* example, va_list list);
method = &my_method;
}
So how do I now tell the program to call iterate_over_entries with with my_method, where the length to my input... :S

Just call it:
int main(int argc, char** argv){
Table* table; //this is set somehow..
int length = atoi(argv[1]);
Func_ptr method;
method = &my_method;
iterate_over_entries(table, method, length);
}
There's no need to assign my_method to another variable, you can just pass it directly.
iterate_over_entries(table, my_method, length);

Related

Iterating through pointer character array

The function readFile(filename) reads the contents of the file and stores it in heap using malloc, it returns char* datatype. I want to store the content in an array in main so that I can count the words. How do I do so? This is the code:
int main()
{
char *char1;
char1 = readFile("test1.txt");
printf("%s", char1[0]); //This does not print anything
CountWords(*char1, &Alpha, &SentChk, &punct, &Words, &totalSents, &onlyVowel_e);
/*function header of CountWords: void CountWords(char ch, int *Alpha, int *SentChk, int *punct,
int *Words, int *totalSents, int *onlyVowel_e);*/
printf("%d", Words);
printf("%d", totalSents);
return 0;
}
When you call "Countwords", your arguments cant be seen by the main as they arent defined there. Even if you use them in your other funtion - this is a different scope. Maybe you could return a char*[] holding these paramaters you want to return. Or better yet, define all of those arguments in main, have your first function pass them "by reference". This way you have the values put in a place where you can access them later for your "Counwords"

Return unsigned char array to main function

Background: My original main() is:
int main(int argc, char *argv[])
{
unsigned char output[16] = {0x00}; // copied from code
// .... (some steps to calculate output[i])
for (i = 0; i < 16; i++)
{
printf("%02X ", output[i]); // output[i] is an array of 16-byte hex values
}
return 0;
}
The original program (e.g., calculate.c) is run by command line:
./calculate $(echo "this_is_input"|xxd -p)
Now I want to modify main() as a call function only, e.g., named run(). And write a new main() to call run() function.
The input (equivalent to above command line) is hardcoded in new main(). main() will pass the input value to run() function (instead of using above command line).
run(int argc, char *argv[])
{
....
return output[i];
}
then run() returns the same output[i] to main()
int main()
{
input_char = **equivalent to $(echo "this_is_input"|xxd -p)** // how to define?
unsigned char returned_output[16] = {0x00};
returned_output = run(X, input_char);
print(returned_output);
}
Question:
How to present the hex dump value of $(echo "this_is_input"|xxd -p)** in the main()?
How to modify run() and main() in order to return unsigned char array to main()?
How to present the hex dump value of $(echo "this_is_input"|xxd -p)** in the main()?
You can represent it as an array of characters, or for example an array of arrays of characters - tokenised by whitespace. Latter is the representation that the command line arguments are already in argv.
How to modify run() and main() in order to return unsigned char array to main()?
You must declare the return type of the function. It is not possible to return an array directly in C, and it is undesirable to copy arrays around. A typical solution is to let the caller (main) create the array, and let the called function modify the content of the array:
void run(int argc, char *argv[], unsigned char output[16])
main has a problem. It attempts to assign an array. Arrays are not assignable. Given that arrays cannot be returned from functions either, this makes little sense.
This is how to call run that I've suggested:
unsigned char output[16] = {0x00};
run(argc, argv, output);

assign pointer from argv in function

I am trying to assign a pointer correctly from the programs **argv. When I assign data in the main function it works fine, but when I attempt to place that logic into a separate function it does not.
What am I doing wrong here?
void parse_args(char *argv[ ], unsigned char *data, *data_len, *nprocs){
data = (unsigned char *)argv[1];
*data_len = strlen(argv[1]);
*nprocs = atoi(argv[2]);
}
int main(int argc, char **argv) {
unsigned char *data;
int data_len;
int nprocs;
// this doesnt work (for data)
parse_args(argv, data, &data_len, &nprocs)
// this works (for data)
data = (unsigned char *)argv[1];
}
This line
data = (unsigned char *)argv[1];
modifies a local copy of main's local data, because all parameters, including pointers, are passed by value. If you would like to modify data inside main, pass it by pointer (i.e. you need a pointer to pointer now):
void parse_args(char *argv[ ], unsigned char **data_ptr, int *nprocs) {
...
*(data_ptr) = (unsigned char *)argv[1];
...
}
your function needs to be passed a char * [] (which is equivalent to a char** in an argument specification). You shouldn't specify the type when calling a function, that should have given you a compiler error (char * is not to be used here!)
// this doesnt work (for data)
parse_args(char *argv, data, &data_len)
must be replaced by
parse_args(argv, data, &data_len)
So, next, you pass a pointer data , but you pass that pointer by value, i.e. your parse_args gets a nice copy of that pointer (which, technically, is just an address stored in a variable), and then you modify that copy. You might want to pass it like data_len:
void parse_args(char *argv[ ], unsigned char **data, *data_len, *nprocs){
..
parse_args(argv, &data, &data_len, &nprocs)
All in all, this doesn't seem to be a great attempt at argument parsing. There's lots of libraries out there to do that for you, and if you want to stay old-school, I'd recommend using gengetopt, which generates all the parsing code you need and has nice documentation.

how to use cmd passed arguments in other function?

we declare main() as
int main(int argc, char *argv[])
and pass some argument by command line and use it
as argv[1], argv[2] in main() function definition but what if i want to use that in some other function's definition ?
one things i can do it always pass that pointer char** argv from main() to that function by argument. But is there any other way to do so?
Just pass the pointer?
int main(int argc, char** argv) {
do_something_with_params(argv);
}
void do_something_with_params(char** argv) {
// do something
}
Or if you mean passing single arguments:
int main(int argc, char** argv) {
do_something_with_argv1(argv[1]);
do_something_with_argv2(argv[2]);
}
void do_something_with_argv1(char* arg) {
// do something
}
void do_something_with_argv2(char* arg) {
// do something
}
In order to make data available to other functions, you need to pass it as a parameter, or make it available through a global (not recommended) or a static variable.
static char** args cmd_args;
static int cmd_arg_count;
int main(int argc, char** argv) {
cmd_arg_count = argc;
cmd_args = argv;
do_work();
return 0;
}
void do_work() {
if (cmd_args > 1) {
printf("'%s'\n", cmd_args[1]);
}
}
The best approach is to make a function that parses command line parameters, and stores the results in a struct that you define specifically for the purpose of representing command line arguments. You could then pass that structure around, or make it available statically or globally (again, using globals is almost universally a bad idea).
one things i can do it always pass this value from main() to that function by argument. But is there any other way to do so?
No. Passing the argc and argv to other functions is perfectly valid.
int main(int argc, char *argv[])
{
typedef struct _cmdline_arg_struct {
// all your command line arguments go here
}cmdline_arg_struct;
/* command line arguments - parsed */
cmdline_arg_struct *pc = (cmdline_arg_struct *) malloc(sizeof(cmdline_arg_struct));
if (parse_cmdline_args(&pc, argc, argv) == PARSE_FAILURE) {
usage();
return 0;
}
/* Now go through the structure and do what ever you wanted to do.. *?
}
You could have code in main() to store the values in non-local variables, and then refer to those variables from other functions.
If you really need to, store them in globals.
but what if i want to use that in some other function's definition?
You mean have another set of parameters for main? That's not possible, because main is defined in the C standard as either
int main();
or
int main(int, char*[]);
And it makes sense: The first parameter tells you the number of parameters given on the command line, the second contains the array of pointers to those parameters.
It's your responsibility to make sense of those parameters and pass them to other functions. Use string conversion functions if you need to make them numbers.

How to access argv[] from outside the main() function?

I happen to have several functions which access different arguments of the program through the argv[] array. Right now, those functions are nested inside the main() function because of a language extension the compiler provides to allow such structures.
I would like to get rid of the nested functions so that interoperability is possible without depending on a language extension.
First of all I thought of an array pointer which I would point to argv[] once the program starts, this variable would be outside of the main() function and declared before the functions so that it could be used by them.
So I declared such a pointer as follows:
char *(*name)[];
Which should be a pointer to an array of pointers to characters. However, when I try to point it to argv[] I get a warning on an assignment from an incompatible pointer type:
name = &argv;
What could be the problem? Do you think of another way to access the argv[] array from outside the main() function?
char ** name;
...
name = argv;
will do the trick :)
you see char *(*name) [] is a pointer to array of pointers to char. Whereas your function argument argv has type pointer to pointer to char, and therefore &argv has type pointer to pointer to pointer to char. Why? Because when you declare a function to take an array it is the same for the compiler as a function taking a pointer. That is,
void f(char* a[]);
void f(char** a);
void f(char* a[4]);
are absolutely identical equivalent declarations. Not that an array is a pointer, but as a function argument it is
HTH
This should work,
char **global_argv;
int f(){
printf("%s\n", global_argv[0]);
}
int main(int argc, char *argv[]){
global_argv = argv;
f();
}
#include <stdio.h>
int foo(int pArgc, char **pArgv);
int foo(int pArgc, char **pArgv) {
int argIdx;
/* do stuff with pArgv[] elements, e.g. */
for (argIdx = 0; argIdx < pArgc; argIdx++)
fprintf(stderr, "%s\n", pArgv[argIdx]);
return 0;
}
int main(int argc, char **argv) {
foo(argc, argv);
}

Resources