This question already has answers here:
How can I correctly assign a new string value?
(4 answers)
Closed 1 year ago.
I'm learning how to use structures in C. But in the following code I couldn't print myArray "HELLO!" which is declared as a char array:
#include <stdio.h>
struct myStruct
{
int myInt;
float myFloat;
char myArray[40];
};
int main()
{
struct myStruct p1;
p1.myInt = 80;
p1.myFloat = 3.14;
printf("Integer: %d\n", p1.myInt);
printf("Float: %f\n", p1.myFloat);
p1.myArray = "HELLO!";
printf("Array: %s\n", p1.myArray);
return 0;
}
What is wrong in the above syntax that I don't get "HELLO!" as an output? Something wrong here:
p1.myArray = "HELLO!";
printf("Array: %s\n", p1.myArray);
Arrays are non-modifiable lvalues. So this attempt to assign a pointer (the string literal is implicitly converted to a pointer to its first element) to an array designator
p1.myArray = "HELLO!";
will not compile.
Either use the standard string function strcpy as for example
#include <string.h>
//...
strcpy( p1.myArray, "HELLO!" );
Or you could initialize the data member initially when the object of the structure type is defined as for example
struct myStruct p1 = { .myInt = 80, .myFloat = 3.14, .myArray = "HELLO!" };
or
struct myStruct p1 = { .myInt = 80, .myFloat = 3.14, .myArray = { "HELLO!" } };
or
struct myStruct p1 = { 80, 3.14, "HELLO!" };
or
struct myStruct p1 = { 80, 3.14, { "HELLO!" } };
Here is a demonstrative program.
#include <stdio.h>
#include <string.h>
struct myStruct
{
int myInt;
float myFloat;
char myArray[40];
};
int main( void )
{
struct myStruct p1 = { .myInt = 80, .myFloat = 3.14, .myArray = { "HELLO!" } };
printf("Integer: %d\n", p1.myInt);
printf("Float: %f\n", p1.myFloat);
printf("Array: %s\n", p1.myArray);
strcpy( p1.myArray, "BYE!" );
printf("\nArray: %s\n", p1.myArray);
return 0;
}
The program output is
Integer: 80
Float: 3.140000
Array: HELLO!
Array: BYE!
Related
In c I am trying to assign a char array inside a struct with a user provided value, here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct person
{
char name[20];
int age;
};
struct person *assign(char arr[], int age)
{
struct person *x = malloc(sizeof(struct person));
x->name[20] = arr[20];
x->age = 21;
return x;
}
int main()
{
char name[20] = "Arthur morgan";
int age = 34;
struct person* person1 = assign(name, age);
printf("name: %s\n", person1->name);
printf("age: %d\n", person1->age);
return 0;
}
The problem is that the name prints nothing for some reason, the age however prints as expected.
Why is the name not printing correctly?
x->name[20] = arr[20];
It does not copy the array
It copies 1 character and you are accessing array outside its bounds which is undefined behaviour (UB)
It is better to use objects not types in sizeof
Always check the result of malloc
You need to copy the string using strcpy function
struct person *assign(char arr[], int age)
{
struct person *x = malloc(sizeof(*x));
if(x)
{
strcpy(x->name,arr);
x->age = 21;
}
return x;
}
https://godbolt.org/z/vKddb4b9a
I have been having problem with this c code -
#include <stdio.h>
#include <string.h>
struct dict
{
char **inputs;
char *outputs;
};
int main(){
struct dict d;
d.inputs = {"hello","hi"};
d.outputs = "Hi!";
return 0;
}
when i run the code it shows this
main.c: In function 'main':
main.c:14:16: error: expected expression before '{' token
14 | d.inputs = {"hello","hi"};
| ^
why is this happening theres nothing wrong with this code?
The data member inputs
char **inputs;
is a scalar object. So it may be initialized using braces with only one expression.
And moreover you may not assign a braced list to an object as you are trying to do
d.inputs = {"hello","hi"};
Instead you could write for example
struct dict
{
char *inputs[2];
char *outputs;
};
int main( void ){
struct dict d = { .inputs = {"hello","hi"}, .outputs = "Hi!" };
return 0;
}
Another approach is the following
struct dict
{
char **inputs;
char *outputs;
};
int main( void ){
struct dict d;
char *s[] = {"hello","hi"};
d.inputs = s;
d.outputs = "Hi!";
return 0;
}
Or you could use a compound literal like
struct dict
{
char **inputs;
char *outputs;
};
int main( void ){
struct dict d;
d.inputs = ( char *[] ){"hello","hi"};
d.outputs = "Hi!";
return 0;
}
i'm trying to solve this problem but it's not working i think the statement inside 'if' is wrong and i don't know if i can put a pointer inside strcmp like this!!
#include <string.h>
#include <studio.h>
struct PersonCar {
char pname[20];
char cModel[20];
float price;
};
struct PersonCar pc[4];
float calculatePrice(struct PersonCar *p, char *name) {
p = malloc(sizeof(pc));
float s = 0;
for (int i = 0; i < 4; i++) {
if ((strcmp((p[i].pname), name)) == 0) //(p+i)->pname
s += (p + i)->price; //(p+i)->price; }
return s;
}
int main() {
// entering the element of the array from the user
char A[20];
printf("Enter a name : ");
fgets(A, sizeof(A), stdin);
printf("the total price of the registered cars for %s =%f\n", A,
calculatePrice(&pc, A));
}
First you need some data (I have included some statically initialized data in my version)
Second, you need to eliminate the malloc() statement at the beginning of the function, that modifies the passed pointer to the data and makes it to point to an uninitialized data, that is very unprobable that finds any register that matches.
You h ad better to know the size of the data array, and pass the number of entries on it.
You need to eliminate the last '\n' from the array read by fgets(). If you don't, it is comparing "smith" against "smith\n", which will never be equal. I suggest one way below, but you have to be careful and read the man page of strtok, as it modifies the source string, this can be not what you want (while in this case is preciselly what we want)
To illustrate, I have written this sample code (but a full program you can compile and execute) to see the logic.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct PersonCar {
char *pname;
char *cModel;
float price;
};
/* initialized data */
struct PersonCar pc[] = {
{ .pname = "smith",
.cModel = "foo",
.price = 10.50F,
}, {
.pname = "montgomery",
.cModel = "bar",
.price = 20.50F,
}, {
.pname = "mckormack",
.cModel = "blah",
.price = 35.50F,
}, {
.pname = "smith",
.cModel = "pong",
.price = 55.50F,
}, {
.pname = "phelps",
.cModel = "ping",
.price = 75.50F,
},
};
size_t pc_count = sizeof pc / sizeof pc[0];
float calculatePrice(
struct PersonCar *p,
size_t p_count,
char *name)
{
float total = 0.0;
for (int i = 0; i < p_count; i++) {
if (strcmp(p[i].pname, name) == 0)
total += p[i].price; /* found */
}
/* not found */
return total;
}
int main()
{
// entering the element of the array from the user
char A[80];
printf("Enter a name : ");
fgets(A, sizeof(A), stdin);
char *p = strtok(A, "\n"); /* chop the last \n if present */
printf("the total price of the registered cars for %s =%f\n",
p, calculatePrice(pc, pc_count, p));
}
I think you're looking for something like:
#include <string.h>
#include <stdio.h>
struct PersonCar {
char pname[20];
char cModel[20];
float price;
};
struct PersonCar pc[4] = {
{"abc", "", 1.0},
{"def", "", 2.0},
{"abc", "", 3.0},
{"jkl", "", 4.0},
};
float
calculatePrice(struct PersonCar *p, char *name)
{
float s = 0;
for( struct PersonCar *e = p + 4; p < e; p++ ){
if( strcmp((p->pname), name) == 0 ){
s += p->price;
}
}
return s;
}
int
main(void)
{
char A[20];
printf("Enter a name : ");
fgets(A, sizeof(A), stdin);
printf("the total price of the registered cars for %s =%f\n", A,
calculatePrice(pc, A));
}
One glaring issue here is that you're not dealing with the newline in the input, but since I don't know how you're actually initializing the data it's not clear how you want to deal with it.
I'm having trouble with a certain "program flow" that I'm trying to implement.
The output in the following MWE is supposed to say "Sum: 10" but it says "Sum: 0" because the function set_array_element does not set array elements. Why doesn't it?
#include <stdio.h>
#include <stdlib.h>
typedef struct example example;
struct example {
int nrOf;
double a[];
};
void initialize_example_array(example *e);
void set_array_element(double *el);
example new_example(int nrOf)
{
example *e = malloc(sizeof(example) + nrOf*sizeof(double));
e->nrOf = nrOf;
initialize_example_array(e);
return *e;
}
void initialize_example_array(example *e)
{
printf("%d\n", e->nrOf);
for(int i=0; i<e->nrOf; i++)
{
set_array_element(&e->a[i]);
}
}
void set_array_element(double *el)
{
*el = 1;
}
int main(int argc, const char * argv[]) {
example e = new_example(10);
printf("%d\n", e.nrOf);
int i, s=0;
for(i=0; i<e.nrOf; i++)
{
printf("%f\n", e.a[i]);
s+= e.a[i];
}
printf("Sum: %d\n", s);
return 0;
}
The flexible array member, this is the member a of struct example, is not a pointer. It's address is calculated using the address of the struct.
A struct with a flexible array member cannot be assigned using the simple assignment operator, like it is done in your example:
example e = new_example(10);
where the function returns:
return *e;
You will have to return the pointer:
example* new_example(int nrOf)
{
example *e = malloc(sizeof(example) + nrOf*sizeof(double));
e->nrOf = nrOf;
initialize_example_array(e);
return e;
}
example* e = new_example(10);
printf("%d\n", e->nrOf);
...
I am using below code in one file
file 1
//structure is global
struct abc
{
char var;
char *a[5];
}*p;
struct abc q;
int main()
{
char t[] = "sample"
p = &q;
p->a[0] = &t[0];
p->var = 10;
printf("var = %d, string = %s\n", p->var, p->a[0]);
func();
exit(0);
}
But if I try to access the structure member (a[]) in func() that is in another file I don't get the data that is assigned in another file (above).
file2
int fucn()
{
char var1;
var1 = p->var;
printf("var1 = %d\n", var1);
//since i am unable to copy p->a[0] to some other string i am trying to print the contents of p->a[0].
printf("a = %s\n", p->a[0]);
}
program crashes executing the second printf but I can print the content of p->var which is assigned in some other file.
Something like below is what you need.
An include file.
prompt> cat foo.h
struct abc {
char var;
char *a[5];
};
extern struct abc *p;
main function
prompt> cat main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "foo.h"
struct abc q, *p;
extern int func();
int
main()
{
p = &q;
/*
* Using strcpy after allocating memory.
*/
p->a[0] = malloc(strlen("zero") + 1);
strcpy(p->a[0], "zero");
/*
* strdup is equivalent to malloc and strcpy
*/
p->a[1] = strdup("one");
p->a[2] = "two";
p->a[3] = "three";
p->a[4] = "four"
p->var = 10;
printf("main var = %d, string = %s %s %s %s %s\n",
p->var, p->a[0], p->a[1], p->a[2], p->a[3], p->a[4]);
func();
return(0);
}
func function
prompt> cat func.c
#include <stdio.h>
#include "foo.h"
int
func()
{
int r;
r = printf("func var = %d, string = %s %s %s %s %s\n",
p->var, p->a[0], p->a[1], p->a[2], p->a[3], p->a[4]);
return(r);
}
Compile and run
prompt> gcc mainc.c func.c
prompt> a.out
main var = 10, string = zero one two three four
func var = 10, string = zero one two three four