I want to change the contents of a constant-character-array(const array[64]).
Below is my code.
My Question is, why does the constant character array doesn't change(not reflected back), when passed to the function as constant character pointer(const char *append)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int function(char *d,const char *append)
{
append = d; //changing the location of append.
printf ("%s\n",append); //displays as sachintendulkar.
}
int main()
{
char *d = NULL;
const char append[]={'s','a','c','h','i','n'};
d = calloc(sizeof(char),sizeof(append));
strcpy(d,append);
strcat(d,"tendulkar"); //appending
function(d,append);
printf ("%s\n",append); //Its displays as sachin instead of sachintendulkar???
}
Function arguments are passed by value, when you assign a new value to the pointer append inside function(), nothing happens that is noted outside the function.
It's not very clear what you're trying to do ... The point of constant data is, of course, that you're not supposed to change it.
It is just a coincidence that the names of the parameters are the same as the variables in main. There is no connection between the names.
Your function works the same as if it was
int function(char *x, const char *y)
{
y = x; //changing the location of y.
printf ("%s\n", y); //displays as sachintendulkar.
}
You wouldn't expect that function to change the values inside main.
Related
This question already has answers here:
How to access a local variable from a different function using pointers?
(10 answers)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
Wrote the following code that takes the time input from a struct and prints it all together into a string:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct time
{
int hour;
int minute;
char am_pm [3];
char (*standard_time)(struct time *self);
};
char standard_time_format(struct time *self)
{
char standard_format[8], conversion[3];
int length;
length = snprintf(NULL, 0, "%d", self->hour);
snprintf(conversion, length + 1, "%d", self->hour);
strcpy(standard_format, conversion);
strcat(standard_format, ":");
length = snprintf(NULL, 0, "%d", self->minute);
snprintf(conversion, length + 1, "%d", self->minute);
strcat(standard_format, conversion);
strcat(standard_format, self->am_pm);
return(standard_format);
}
int main()
{
struct time start;
char standard_format[8];
start.hour = 2;
start.minute = 34;
strcpy(start.am_pm, "am");
start.standard_time = standard_time_format;
strcpy(standard_format, start.standard_time(&start));
printf("%s\n", standard_format);
return 0;
}
However, it is unable to print out the result as the return type doesn't seem to be compatible.
Changing types to pointers didn't fix it either:
in the struct:
char *(*standard_time)(struct time *self);
the function:
char *standard_time_format(struct time *self)
and in both routines creating a pointer to standard_format:
char *str = &standard_format;
and returning the pointer in the function:
return(str);
So what type exactly is being returned, and how can it be accessed properly to display it in the printf command?
EDIT
As suggested in the answers, I modified the code such that a string was passed as an argument to the function instead, which remedied the issue. The following is the updated code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct time
{
int hour;
int minute;
char am_pm [3];
void (*standard_time)(struct time *self, char standard_format[8]);
};
void standard_time_format(struct time *self, char standard_format[8])
{
char conversion[3];
snprintf(conversion, sizeof(conversion), "%d", self->hour);
strcpy(standard_format, conversion);
strcat(standard_format, ":");
snprintf(conversion, sizeof(conversion), "%d", self->minute);
strcat(standard_format, conversion);
strcat(standard_format, self->am_pm);
}
int main()
{
struct time start;
char standard_format[8];
start.hour = 2;
start.minute = 34;
strcpy(start.am_pm, "am");
start.standard_time = standard_time_format;
start.standard_time(&start, standard_format);
printf("%s\n", standard_format);
return 0;
}
In the standard_time_format function when you do
return(standard_format);
you attempt to return a pointer to the first element in the array standard_format (remember that arrays decays to pointers to its first element, i.e. &standard_format[0]). Its type is char *.
However this is very problematic since standard_format is a local variable inside the function, and it will go out of scope once the return statement have been executed, leaving you with a dangling pointer which you can't dereference (attempting to do so will lead to undefined behavior).
The simple and standard solution is to pass the string to be filled as an argument to the function.
return(standard_format);
Here you have returned pointer that points to local variable when standard_time_format returns its stack will be deallocated and eventually standard_format that you returned will become invalid
You should pass char array to standard_time_format and copy the string that you want to return in it, instead of returning local variable
I would like to be able to call a function with a 2D array named using const char*. In my program, I open up a CSV input, read the number of lines, create a 2D array of the appropriate size (copy over the data from the file-this step is not in the code for the sake of the question) and then want to print it (not in the main function though, to cut down on number of lines).
For this example we can ignore the CSV component so I've added a sample array just to try it out.
I know I'm getting lost in the pointers somewhere in the hand-off of the array between main() and show() since I'm getting the error "subscripted value is neither array nor pointer nor vector." I just don't know how to fix it. Any pointers on how to remedy this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define col 4
void show(const char* A){
int i, j;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
if(A[i][j])
printf("%s\t", A[i][j]);
else
printf("%s\t", "NULL");
}
printf("\n");
}
}
int main () {
FILE* t1count = fopen("input/t1_input.csv", "r");
t1row = countlines(t1count); // Where countlines is another function I have written but not relevant in this case
const char *strings[t1row][col]; //For this example we can use: = {{"4001","CA52","C14M731345","5"},{"4010","CA52","C14M731559","5"},{"4101","CA52","C14M731559","5"},{"4029","CA72","B15M731038","9"}};
show(strings);
}
Thanks!
There is type mismatch between your function parameter void show(const char* A) and the argument you are passing while calling show(strings);
change your function prototype to
void show(const char* A[][col])
I have a problem in C. I have this function :
int test(void *data);
I want to change data with this function but I don't want another prototype (not use void **). Actualy, data equals null out this function.
#include <stdio.h>
#include <stdlib.h>
int
test(void *data)
{
data = "toto";
return 1;
}
int
main()
{
void *d;
if (test(d) != 1) {
printf("erreur\n");
}
printf("résultat : %s\n", (char *) d); // displays "résultat : (null)"
return 0;
}
Help me please. ;)
In C arguments to function are passed by value. d is passed by value to function test. data is a local variable to function test and d is copied to data. The assignment
data = "toto";
makes pointer data to point to string literal toto, while d is unaffected of this assignment in main function. So, this assignment has no effect on d.
In main you are dereferencing an uninitialized pointer. This will result in undefined behavior.
In your test function, you change data, which doesn't affect d because data is just a local variable. If you really need to change d, then you need to let test return data and do d=test(d).
Moreover, in your test function, the value of data is never used. So what is the point to have data as a parameter of the function?
In printf("résultat : %s\n", (char *) d);, you try to cast d into pointer to char and then print the value of d. Although you don't dereference d, you are still printing a variable that hasn't been initialized, which is undefined behavior.
Any object pointer (i.e. non-function pointer) can be converted to a void * and back to the original type without altering the value. This means that you can pass any kind of (object) pointer to your test() function, it will be automatically converted to a void *, and you can then convert it back inside test().
#include <stdio.h>
int test(void *data)
{
char **s = data;
*s = "toto";
return 1;
}
int main()
{
char *res;
if (test(&res) != 1) {
printf("erreur\n");
}
printf("résultat : %s\n", res);
return 0;
}
You just need to make sure that the test() function knows what the original type was.
I am trying to update a variable using two different functions. I wrote a little C program to demonstrate:
#include <stdlib.h>
#include <stdio.h>
void updateHelper(int *x, int y) {
*x = y;
}
void update(int x, int y) {
updateHelper(&x, y);
}
int main(int argc, char *argv[]) {
int num = 0;
update(num, 1);
printf("%d\n", num);
return 0;
}
Why is this printing a 0 and not a 1? I can't wrap my head around this. The function that is actually updating the value is indeed passed a reference of the variable(!?). Can someone explain why this happens?
The arguments of update() can not be pointers. Are there any possible work-arounds for this?
You aren't updating the original variable. You're updating the copy of that variable that was passed to your update function. If you want to update the original variable, change update to take it's parameter as a pointer:
void update(int* x, int y) {
updateHelper(x, y);
}
and in main, pass the address:
update(&num, 1);
Edit: since you stated the arguments to update cannot be pointers, you will need to either have update return the new variable, or use a global variable, or ... In C, the only way to modify a reference to a variable in a function is by using pointers.
x in the call to update is just a local variable that happens to start with the same value as num in main. Therefore, even though its value is changed via the call to updateHelper, this has no effect on the value of num. That is, only the value of num, not it address, was passed to update, so nothing that happens subsequently during the call to update has any bearing on the value of num.
update(int x,..)
int x here is a argument by value. ie a copy (new address created) of num is created and the value is copied.
try instead:
#include <stdlib.h>
#include <stdio.h>
void updateHelper(int *x, int y) {
*x = y;
}
void update(int *x, int y) {
updateHelper(x, y);
}
int main(int argc, char *argv[]) {
int num = 0;
update(&num, 1);
printf("%d\n", num);
return 0;
}
Your initial call to the update function is a normal call-by-value, which means that int num gets copied, not referenced. Thus, when you later call updateHelper with a reference to the parameter x, all that gets modified is the copied value of num, local to the update function.
So, your call stack ends up looking like this (read from bottom to top):
main()
| num: 0
|
update() < But `update's` x is a copy, does not point to anything
| x: 1 .
| \
updateHelper() | < Points to `update's` x
| /
| *x: 1 ^
If your update function's interface can't take a pointer, then the only other options it has is to either return the modified value (which will also require a change to the interface), or to use a (possibly static) global variable.
char *test = "hello";
test = change_test("world");
printf("%s",test);
char* change_test(char *n){
printf("change: %s",n);
return n;
}
im trying to pass a 'string' back to a char pointer using a function but get the following error:
assignment makes pointer from integer without a cast
what am i doing wrong?
A function used without forward declaration will be considered having signature int (...). You should either forward-declare it:
char* change_test(char*);
...
char* test = "hello";
// etc.
or just move the definition change_test before where you call it.
printf() prints the text to the console but does not change n. Use this code instead:
char *change_test(char *n) {
char *result = new char[256];
sprintf(result, "change: %s", n);
return result;
}
// Do not forget to call delete[] on the value returned from change_test
Also add the declaration of change_test() before calling it:
char *change_test(char *n);
You're converting an integer to a pointer somewhere. Your code is incomplete, but at a guess I'd say it's that you're not defining change_test() before you use it, so the C compiler guesses at its type (and assumes it returns an integer.) Declare change_test() before calling it, like so:
char *change_test(char *n);
thanks a bunch guys! didnt think i would have this problem solved by lunch. here is the final test class
/* standard libraries */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* change_test(char*);
int main(){
char *test = "hello";
test = change_test("world");
printf("%s",test);
return (EXIT_SUCCESS);
}
char* change_test(char *n){
return n;
}