Do matrices work within structs in C? - c

I'm trying to make a struct that contains (in this example) the name of the item to buy in an array and in a matrix it's price and the weight of it I should buy. This is just an easy example of what i'm trying to do.
I use strcpy to declare the value just because I learned it this way, I don't if it's the best of the methods.
#include<stdio.h>
#include<string.h>
typedef struct Grocery_list{
char item_name[2];
double item_info[2][2];
}Grocery;
int main(){
Grocery market;
strcpy( market.item_name[0], "Apple");
strcpy( market.item_name[1], "Sugar");
strcpy( market.item_info[0][0],200); //apple weight
strcpy( market.item_info[1][0], 3); //apple price
strcpy( market.item_info[0][1], 300);
strcpy( market.item_info[1][1], 4);
printf("%f \n",martket.item_info[1][1]);
return 0;}
The errors are
teste.C: In function ‘int main()’:
teste.C:14:27: error: invalid conversion from ‘char’ to ‘char*’ [-fpermissive]
strcpy( market.item_name[0], "Apple");
^
In file included from teste.C:2:0:
/usr/include/string.h:129:14: error: initializing argument 1 of ‘char* strcpy(char*, const char*)’ [-fpermissive]
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^
teste.C:15:27: error: invalid conversion from ‘char’ to ‘char*’ [-fpermissive]
strcpy( market.item_name[1], "Sugar");
^
In file included from teste.C:2:0:
/usr/include/string.h:129:14: error: initializing argument 1 of ‘char* strcpy(char*, const char*)’ [-fpermissive]
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
^
teste.C:16:35: error: cannot convert ‘double’ to ‘char*’ for argument ‘1’ to ‘char* strcpy(char*, const char*)’
strcpy( market.item_info[0][0],200);
^
teste.C:17:34: error: cannot convert ‘double’ to ‘char*’ for argument ‘1’ to ‘char* strcpy(char*, const char*)’
strcpy( market.item_info[1][0], 3);
^
teste.C:18:36: error: cannot convert ‘double’ to ‘char*’ for argument ‘1’ to ‘char* strcpy(char*, const char*)’
strcpy( market.item_info[0][1], 300);
^
teste.C:19:34: error: cannot convert ‘double’ to ‘char*’ for argument ‘1’ to ‘char* strcpy(char*, const char*)’
strcpy( market.item_info[1][1], 4);
^
teste.C:21:16: error: ‘martket’ was not declared in this scope
printf("%f \n",martket.item_info[1][1]);
^
Obviously, I searched for answers and solutions on Google, but everything I tried just caused other errors or even the same. For I'm new in programming in general I don't know what those errors mean.
Thank you in advance

Three issues:
Your struct doesn't have an array of strings. It has an array of characters. You need to add an extra dimension to item_name to have such an array:
typedef struct Grocery_list{
char item_name[2][50];
double item_info[2][2];
}Grocery;
Also, you're using strcpy to attempt to copy numerical values. This function is used for copying strings. Instead of using this function, perform a simple assignment:
market.item_info[0][0] = 200; //apple weight
market.item_info[1][0] = 3; //apple price
market.item_info[0][1] = 300;
market.item_info[1][1] = 4;
Lastly, you have a typo in your printf statement:
printf("%f \n",martket.item_info[1][1]);
It should be:
printf("%f \n",market.item_info[1][1]);

The member item_name is an array of two characters, it's not an array of strings, it's just a single string (which can only hold a single character, remember that all strings have a special terminator character). You probably should make this an array of arrays of char, which means it's an array of strings:
char item_name[2][64]; // Two strings, each can hold 63 characters
The member item_info is an array of arrays of double. The strcpy function is for copying strings (arrays of char).
Remember that each element in an array is like a variable, which means you can just assign to it:
market.item_info[0][0] = 200; //apple weight
market.item_info[1][0] = 3; //apple price
market.item_info[0][1] = 300;
market.item_info[1][1] = 4;
And the last error is because you misspelled market.
All of this would be very obvious even to a beginner if you just read the error messages.

1 - your declaration of the item_name[2] is correct but you used in the wrong way. this is actually logical error. you need enough room for saving your data such as: apple, sugar and ... the last character of string is '\0'. indeed you just declaring one character for saving "apple" or "sugar".
2 - strcpy is for manipulating of string or array of characters, so you are not authorized to use this function with numerical variables.
3 you have misspelling in last line (before returning to OS).

Related

How store address of an array[] in a variable

This seems like a silly question. I have an array of chars and want to store the address of the array in another variable, but can't seem to declare the correct type for the array address (I'm using gcc):
IN:
int main(void){
char cha[] = "abcde";
char **arrayAddress = &cha;
}
OUT:
arrayaddress.c: In function ‘main’:
arrayaddress.c:3:25: warning: initialization of ‘char **’ from incompatible pointer type ‘char (*)[6]’ [-Wincompatible-pointer-types]
3 | char **arrayAddress = &cha;
| ^
This is expected, I have read elsewhere that the type of cha should be char(*)[6]. But when I try to declare arrayAddress with this type, my program fails:
IN:
int main(void){
char cha[] = "abcde";
char (*)[6]arrayAddress = &cha;
}
OUT:
arrayaddress.c: In function ‘main’:
arrayaddress.c:3:10: error: expected identifier or ‘(’ before ‘)’ token
3 | char (*)[6]arrayAddress = &cha;
| ^
make: *** [<builtin>: arrayaddress] Error 1
^
How do I define arrayAddress correctly?
It is written:
char (*arrayAddress)[6] = &cha;
Notice that the name of variable gets tucked in middle of the expression.
Arrays decay to pointers.
char cha[] = "abcde";
char *p1 = cha;
char (*arrayptr)[sizeof(cha)] = &cha;
cha, &cha[0] and &cha reference the same first element of the array cha, the only difference is the type.
cha and &cha[0] has type: pointer to char
&cha has type: pointer to array of 6 char elements.
If your compiler supports typeof extension (gcc does) then you can define the pointer as:
typeof(char (*)[6]) arrayAddress = &cha;
Or even cleaner as:
typeof(char[6]) * arrayAddress = &cha;

correct return type for C function?

I am using an array of strings inside my function declared like this
char (*array)[PATH_MAX] = malloc (1000 * sizeof *array);
Allocating 1000 char pointers of size PATH_MAX (1024).
I want the function to return that specific data structure, i.e. return the pointer array. But I can't manage to choose the correct return type.
warning: returning 'char (*)[1024]' from a function with return type 'int' makes integer from pointer without a cast [-Wint-conversion]
I get that I can't have int as return type, but char** doesn't work either.
warning: returning 'char (*)[1024]' from a function with incompatible return type 'char **' [-Wincompatible-pointer-types]
I've tried using char (*)[1024] as return type, but it gives me generic C error messages, leading me to believe that I am not using the correct syntax.
error: expected identifier or '(' before ')' token
38 | char (*)[1024] read_dir (char *path) {
| ^
Is there a correct syntax for achieving this or am I just doing it wrong?
You need to define the function as follows:
char (*read_dir(char *path))[PATH_MAX] {
This specifies the return type as a pointer to an array of size PATH_MAX of char *.
Time for typedef
typedef char arr1k_char[1000];
arr1k_char *foo(int n) {
arr1k_char *x = malloc(n * sizeof *x);
return x;
}
https://ideone.com/Cqxa61

Compiler claims pointer is const when it is not used

My compiler gives this warning:
inlinedata.h:9:6: note: expected ‘char *’ but argument is of type ‘const char *’
int inline_data_receive(char *data,int length);
I don't understand why it claims 'data' is a const pointer when it is not written as a const char*.
It's saying that the argument (the data that you are passing in) is const. It might be a string literal, for example. So instead of doing this:
ret = inline_data_receive("hello", len);
do this
char str[] = "hello";
ret = inline_data_receive(str, len);
You need to do it this way since the function is not guaranteeing that it won't modify the input string.
The compiler is complaining that you are passing a const char* value to a value that is labeled as char*. Essentially the following
const char* c = ...;
inline_data_receive(c, strlen(c));
The compiler is complaining that c is const char* but needs to be char* to line up with the argument data

expected ‘const char *’ but argument is of type ‘char **’ in C

I am trying to write a function which searches the array looking for the specified key.The argument n specifies the effective size of the array,which must be sorted according to the lexicographic order imposed by strcmp.If the key if found,the function returns the index in the array at which that key appears.So ,it can return the index of the substring.However,it come two errors which I can't fix with.Please help.
jiebin#jiebin-ThinkPad-Edge-E530:~/Program_C/programming_abstractions_in_c/FindStringInSortedArray$ gcc FindStringInSortedArray.c -o FindStringInSortedArray
FindStringInSortedArray.c: In function ‘FindStringInSortedArray’:
FindStringInSortedArray.c:7:3: warning: passing argument 1 of ‘strlen’ from incompatible pointer type [enabled by default]
/usr/include/string.h:399:15: note: expected ‘const char *’ but argument is of type ‘char **’
jiebin#jiebin-ThinkPad-Edge-E530:~/Program_C/programming_abstractions_in_c/FindStringInSortedArray$
This is my code:
#include<stdio.h>
#include<string.h>
int FindStringInSortedArray(char *key,char *array[],int n)
{
int mid,cmp;
int low=strlen(array)-n;
int high=n;
if(low > high) return(-1);
mid = (low+high)/2;
cmp = strcmp(key,array[mid]);
if(cmp==0) return(mid);
if(cmp<0){
return(FindStringInSortedArray(key,array,n/2));
}else{
return(FindStringInSortedArray(key,array+n/2,n));
}
}
int main()
{
char key[2]="ab";
char *array[10]={"ab","bc","cd","de","ef","fg","gh","hi","ij","jk"};
int test=FindStringInSortedArray(key,array,10);
printf("Result:%d\n",test);
return 0;
}
int low=strlen(array)-n; is wrong. Pass the array size as different parameter like:
int FindStringInSortedArray(char *key,char *array[],int n, int arraysize)
Since arrays decay into pointers in functions. Declaration of strlen is of the form
strlen (const char*)
And you are passing *array[] whose type decays to char * *.
In C99 there are three fundamental cases where array name doesn't decay into pointers to first elements:
when it's the argument of the & (address-of) operator.
when it's the argument of the sizeof operator.
When it's a string literal of type char [N + 1] or a wide string literal of type wchar_t [N + 1] (N is the length of the string) which is used to initialize an array, as in char str[] = "foo"; or wchar_t wstr[] = L"foo";.
In C11, the newly introduced alignof operator doesn't let its array argument decay into a pointer either.
When you call strlen, it is expecting a char* (i.e. a string) as an argument, but you provide it with array which is a char** (i.e. an array of strings).
What you want is the size of the array, i guess. There is no way to know it, in C. The only way is to pass the size of the array as an argument :
int FindStringInSortedArray(char *key,char *array[],int n, int len)

atoi from string to Integer using char pointer

Here is the code I have written which splits a string in c and then I want to return the first integer value pointed by the char pointer.
#include<stdio.h>
void main(){
int month[12]={0};
char buf[]="1853 was the year";
char *ptr;
ptr = strtok(buf," ");
printf("%s\n",ptr);
int value = atoi(*ptr);
printf("%s",value);
}
EDIT:It gives me segmentation fault.
The problem is it is printing 1853 as the year, But I want to convert this into integer format.How can i retrieve that value as an integer using the pointer?
you are here trying to use an integer as a string:
printf("%s",value);
you should do
printf("%d",value);
Edit: yes, and also do int value = atoi(ptr); as added in another answer.
main should also be int, not void.
Also, what compiler are you using? With gcc 4.6 I got these errors and warnings when trying to compile your code (after adding some includes):
ptrbla.C:5:11: error: ‘::main’ must return ‘int’
ptrbla.C: In function ‘int main()’:
ptrbla.C:11:30: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
/usr/include/stdlib.h:148:12: error: initializing argument 1 of ‘int atoi(const char*)’ [-fpermissive]
ptrbla.C:12:26: warning: format ‘%s’ expects argument of type ‘char*’, but argument 2 has type ‘int’ [-Wformat]
I'd think you could get at least some of these from most compilers.
int value = atoi(ptr);
No need to dereference, atoi() expects a const char*, not a char.
printf("%d",value);
And you print an integer using %d or %i. %s is for string only.
BTW, maybe you would like to use strtol instead
char buf[]="1853 was the year";
char* next;
long year = strtol(buf, &next, 10);
printf("'%ld' ~ '%s'\n", year, next);
// 'year' is 1853
// 'next' is " was the year"
Use:
int value = atoi(ptr);
atoi should get a character pointer, which is what ptr is. *ptr is the first character - 1 in this case, and anyway isn't a pointer, so it's unusable for atoi.

Resources