LoadRunner - using a %d in lr_eval_string function - c

I need to create a string with multiple values of 'x'.
For instance I tried saving a string while referencing another variable as such:
lr_save_string("xyz", lr_eval_string("{x_%d}", intVar));
I've also have tried:
lr_save_string(lr_eval_string("{x_%d}", intVar), "xyz");
Is there any option/way to use %d and a int variable which always changes in the lr_eval_string function? or, how could this be performed?

You have to use sprintf function like below,
char *buffer = (char *)malloc(20); // allocate size as per your requirement
sprintf(buffer,"{x_%d}", intvar);
lr_save_string(lr_eval_string(buffer),"xyz");

Depending on the version of Loadrunner you may use the array functions:
lr_save_string(lr_paramarr_idx("x", intvar), "xyz");

Related

How to use gettext() with dynamic message id as an argument in C

I want to know how to use gettext in C with dynamic message id in the argument.
For example,
char *var = fun(); //where fun returns char * type.
char *val = gettext(var);
Your code is fine, but you will of course also need to make sure that fun() returns a static string, that's going to stick around. Also val should be const char *, you cannot change the strings owned by gettext.

How to return multiple values from a function in C

How come the pointer in main does not get updated to the string that starts with 'xavier' instead of returning to its initial value!
Here is my function:
char * getValue(char * tag, char * query)
{
char * end = strstr(query, "&");
while (* query != '=')
{
query++;
}
query++;
// print the query string after the pointer has been incremented through while loop
printf("%s \n", query);
// get the size of the substring I want
int size = strlen(query) - strlen(end);
printf("%d \n", size);
// allocate memory for it and link it to pointer 'value'
char * value = malloc(sizeof(char) * (size + 1));
memcpy(value, query, size);
value[size] = '\0';
printf("%s \n", value);
return value;
}
int main(int argc, char * argv[])
{
char * tag = "Username=";
char * query = "Username=Xavier&Password=Bachelor&Submit=+Create";
char * value = getValue(tag, query);
// Username=Xavier&Password=Bachelor&Submit=+Create This is the result after the f() of the printf
// Xavier&Password=Bachelor&Submit=+Create This is what I want...
printf("%s \n", query);
return EXIT_SUCCESS;
}
Have you try to use another object.
The Object with many properties. So when you return an object you can get or set many values
To modify parameters, you need to pass pointer to the value you want to modify.
Since you want to modify pointer, you need to pass pointer to pointer.
This is more a matter of opinion, but many programmers think that using out parameters is a bit ugly. It can lead to code which is harder to understand. To mitigate this, parameter name should reflect what it is, for example in the way shown below.
In general, always make any pointer parameters be pointers to const, unless you actually do need to modify what it points to. With strings it's especially important, because string literals are read-only, and usually pointers to string literals are made const. If you function takes pointer to non-const, then you should get compiler warning or error (depending on what exactly you do).
Since tag is unused at least in the question code, you should get compiler warning about that (and if you don't, you should turn up warnings!).
Fixing all this gives this function:
char * getValue(const char * tag, const char **query_in_out)
{
(void)tag; // remove compiler warning about unused parameter
char * end = strstr(*query_in_out, "&");
while (**query_in_out != '=')
{
(*query_in_out)++;
}
(*query_in_out)++;
// print the (*query_in_out) string after the pointer has been incremented through while loop
printf("%s \n", *query_in_out);
// get the size of the substring I want
int size = strlen(*query_in_out) - strlen(end);
printf("%d \n", size);
// allocate memory for it and link it to pointer 'value'
char * value = malloc(sizeof(char) * (size + 1));
memcpy(value, *query_in_out, size);
value[size] = '\0';
printf("%s \n", value);
return value;
}
Call by passing address of pointer you want to modify:
char * value = getValue(tag, &query);
PS. As I said above, C string literals are normally read-only, so you should really have this:
const char * tag = "Username=";
const char * query = "Username=Xavier&Password=Bachelor&Submit=+Create";
That way, you can modify these pointers to make them point to different things (like your getValue function doesw), but you can't accidentally modify the data they point to (which would crash the program in case of string literal, on a modern OS).
You are not capturing the return value from the function. You can do...
printf("%s \n", getValue(tag, query));
The C language has "pass by value" semantics for function parameters.
When the main function executes
getValue(tag, query)
the argument expressions tag and query are reduced to their values. These values are now dissociated from the variables from which they came: copies of these values travel into the function, where they are used to initialize the parameters tag and query:
char * getValue(char * tag, char * query) { ... }
these parameters have nothing to do with tag and query in the main function, even though they have the same names. These parameters are local variables of the getValue function, exactly like the value variable and the end variable. Like value and end, they are newly created when the function begins executing. Unlike value and end they are special: being parameters, they are initialized with the argument values received from main. When getValue returns, all of these local variables are destroyed (though not what they point to!).
When you increment the query pointer, you are only changing the local variable, which is gone when that function is done.
Your program also leaks memory: the getValue function allocates space and uses the value local variable to track this space and store some characters into it. It then returns that pointer via the return value statement. At that point, the getValue function stops executing and the value variable ceases to exist, but the memory from malloc continues to exist: the pointer value is returned out of the function. Then the previously suspended main function resumes executing but, alas, it ignores the value returned from the getValue call. That memory has become unreachable: the program has lost its last remaining copy of the pointer that it obtained from malloc, and has no way to refer to that memory at all, let alone free it with the free function. That situation is called a "memory leak".
In C++ you could use address of variable instead of variable in function defininion, like this
char * getValue(char * tag, char * &query)
In plain C you only can use pointer to pointer to achieve same functionality:
char * getValue(char * tag, char ** query)
Of course, in function budy you should then use dereference, i.g. using *query instead of query, and you should call this function like getValue(tag, &query)
If you want to return multiple values you have to define a structure and return an object of that type.
I think you make a confusion in your program. You probably want to do this in main.
query = getValue(tag, query);
If you don't capture the return value how do you expect anything to be updated?

how to assign a value to an array element in c language?

#include <malloc.h>
void main()
{
char **variable;
int count=0
variable=(char **)malloc(sizeof(char *)*100);
for(i=0;i<100;i++)
variable[i]=(char *)malloc(sizeof(char)*11);
scanf("%s",variable[count]);
}
Now I want to assign a value to the string present in variable[count]
for example: if variable[count] contains a string "abc" then i want to assign 20 to abc
and if i use printf("%d",abc) then it should print 20
Here
variable=(char **)malloc(sizeof(char)*100);
you want to allocate pointers, so specifiy the correct size of a pointer, that is char*, like so:
variable = malloc(100 * sizeof(char*));
or even better like this:
variable = malloc(100 * sizeof(*variable));
Btw: In C there is not need to cast the results of malloc/calloc/realloc, nor is it recommended.
Following the rules/advices above, this line
variable[i]=(char *)malloc(sizeof(char)*11);
should better look like this
variable[i] = malloc(11 * sizeof(*variable[i]));
Finally this call is dangerous:
scanf("%s",variable[count]);
as it tends to overflow variable[count], so make it save by telling scanf() how much so scan in as a maximum, by doing so:
scanf("%10s", variable[count]); /* Leave one (10=11-1) spare for the C-"string"'s 0-terminator. */
And it's
int main(void)
The type of variable is char **, then variable should point to a list of char *, not a list of char.
Therefore, variable=(char **)malloc(sizeof(char)*100); should be variable=(char **)malloc(sizeof(char *)*100);.
BTW, the type-casting before malloc() is unnecessary.
Now I want to assign a value to the string present in variable[count] for example: if variable[count] contains a string "abc" then i want to assign 20 to abc and if i use printf("%d",abc) then it should print 20
You want to treat the value of variable[count] to be a variable. Unfortunately, you cannot do that. C is a static programming language, which means you cannot create variable on run time, as you do in dynamic programming language.
But C is powerful enough to let you simulate this. You could create a look-up table, such as
typedef struct var {
char *name;
int val; /* or whatever type you want */
} var_t;
var_t variable[num_of_vars]; /* or whatever data structure that you can search */

Saving multiple chars in pointer C (dynamic memory)

I need to create mini social network in C. I made a struct for each person. And I'm storing each friend in a char pointer with id's. I thought I can manage it like this:
ptr_friends = id1,id2,id3,id4...
and when I need them I could just read those by using strtok.
But I couldn't manage to save it that way. It should be like this:
ptr_friends = ptr_friends + id + ","
but of course it doesn't work this why and I don't know how to do it.
How can I save and use this way? Or if you have another idea for a save method please tell.
I'd suggest that you make ptr_friends a pointer to multiple chars by using malloc(size_t) and then resizing the space with realloc(void *, size_t) everytime you want to add an ID to the friendlist. That way you can just get the numbers using ptr_friends[i].
For example :
int friends_size = 1;
char *ptr_friends = malloc((size_t)1);
ptr_friends[0] = john_id; // john_id is a fictional ID here
And when you want to add a friend :
ptr_friends = realloc(ptr_friends, ++friends_size);
ptr_friends[friends_size-1] = mary_id;
EDIT :
If you want to make a function to add a friend, for example addfriend(char *,int), doing the following is an error :
void addfriend(char *ptr_friends, int *friends_size, int id)
{
ptr_friends = realloc(ptr_friends, (size_t) ++(*friends_size));
ptr_friends[friends_size-1] = id;
}
ptr_friends here is getting reallocated, and since the pointer can move while being reallocated, we're storing it in ptr_friends. But, it's the ptr_friends from inside the function, that means that the pointer we give to the function will not get modified, since arguments to a function are copied elsewhere beforehand. That means that you have to give a pointer to the pointer, so you can modify the pointer in the main code.
I guess this will help you : https://stackoverflow.com/a/5901241/2549281
You should use something like :
strcat(ptr_friends, id);
strcat(ptr_friends, ",");
instead of ptr_friends + id + ","
Would not it be easier to you to do an array of ints with ids?
int max_friends = 50;
int friends_size = 0;
int friends* = malloc(sizeof(int) * MAX_FRIENDS);
friends[friens_size] = id;
friends_size++;
Another suggestion is instead of using a string or a simple array you can use a "generic" dynamic array (using void*). It's a simple code and you can find many examples.
take a look at that question: C dynamically growing array

C Beginner question: Pointer to a pointer / Can't access values from outside a function

I'm passing a pointer to a pointer (**resultSet) to my MySQL function.
Here's an excerpt on how I copy the MySQL data from within the function:
int
getItems(char * cmd, char **resultSet)
{
...
MYSQL initialisations and set-up
...
resultSet = malloc(sizeof(char)*(int)mysql_num_rows);
while((row = mysql_fetch_row(result)))
{
for (i=0 ; i < mysql_num_fields(result); i++)
{
printf("%i: \t", i);
resultSet[counter] = malloc(sizeof(char)*strlen(row[i])+1);
strcpy(resultSet[counter], row[i]);
printf("%s\n", resultSet[counter]);
}
printf("---------------------\n");
counter++;
}
...
MYSQL cleaning up
...
return 0;
}
Calling it in main with
getItems(cmd, resultSet);
From within my getItems function this
printf("%s\n", resultSet[0]);
seems to work.
However, if I try to access it from outside my function I get a segmentation fault. Why is this?
You probably want:
resultSet = malloc(sizeof(void *)*(int)mysql_num_rows);
Instead of:
resultSet = malloc(sizeof(void)*(int)mysql_num_rows);
as you need pointers not bytes.
If you want to use resultSet as a return parameter, you need to make the function signature
int getItems(char * cmd, char ***resultSet)
and use it in the function like
*resultSet = malloc(sizeof(char)*(int)mysql_num_rows)
The function call could look like
char** results;
nitems = getItems(somecmd, &results);
Better and simpler is probably to leave it as it is and make the allocation before the function call.
Two problems here:
As indicated the allocation of resultset is wrong.
Secondly, strlen(row[i]+1) will calculate the string length of the memory location referenced by row[i]+1. This length will be 1 less then the string length of row[i]. Since you're basically duplicating a null terminated string, use that function: resultSet[counter] = strdup((char *)row[i]);
No need to malloc and strcpy.
As far as I can see, you have an array of char arrays that you want to fill with your data. Your initial allocation should be changed to:
resultSet = malloc(sizeof(char*)*(int)mysql_num_rows);
To reflect this (notice char*).
Also:
resultSet[counter] = malloc(sizeof(char)*strlen(row[i])+1);
This row is technically correct, but you should change it to:
resultSet[counter] = malloc(sizeof(char) * (strlen(row[i])+1) );
To reflect what you actually want to do (the reason for this is the order that C performs arithmetics, and the first approach would yield wrong results if you tried to do it on any other datatype than char/unsigned char).
Finally, I expect that you want to return the value of the 2d-array somehow. There are two ways to do this:
Make the function return a char** (return NULL on failure). You don't need resultSet as an input parameter here.
int
getItems(char * cmd, char ***resultSet)
Notice that everything with resultSet in the function would have to change to *resultSet. The function can then be called with:
char **result;
int status = getItems(cmd, &result);
You probably just need to set the return value (or the parameter) to &resultSet. But we could know for sure if you showed the parameters to the function and the calling of the function.

Resources