How do I assign an element of a 2-dimensional array? [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 months ago.
Improve this question
I have a two-dimensional char array (an array of strings). When I try to assign a string to an element, an error occurs saying "array type 'char *[8]' is not assignable".
This is my code:
int main() {
char array[4][8];
array[0] = "test";
}
How would I properly assign an element of a 2-D array?

I have a two-dimensional char array (an array of strings).
This is my code: char *array[4][8];
That is not a two-dimensinal char array. It's a two-dimentional array of char pointers.
To get a two-dimentional char array that can be used as an array of strings do
char array[4][8]; // i.e. without *
Now you can save 4 strings with max length 7.
C has no way to assign a string using =. In C you can use strcpy to copy a string into your variable like:
strcpy(array[0], "test");
However, you can initialize the array with strings using = like:
char array[4][8] ={"test", "hello", "world", "done"};
and for instance print them like:
for (int i=0; i < 4; ++i) puts(array[i]);
The output will be:
test
hello
world
done
The second dimension of the array can be used to access the individual characters of the strings. For instance:
printf("%c", array[1][4]);
will print the o from hello

Maybe by using 2 dimensions of the 2D array. array[0][0] = "test;"
Though please note that in your case this is a 2D array of pointers to string literals. And since string literals are read-only, it should be declared as const char *array[4][8];. If you want read/write memory then you should assign the pointers to dynamically allocated memory instead.

int main() {
char *array[4][8];
array[0] = "test";
}
In the above code you first create a two-dimensional array of char*. The mistake occures on the second line. You are trying to assign a value to array[0], but since array is a two dimensional array array[0] doesn't point to a char*, instead it points to an array of char*. The correct way of doing this would be:
array[0][0] = "test";
This would assign the first element in the first array to "test".

You need to use the correct array subscript. The type of array[0] is char *[8] but you need array[0][0] which is of type char *. Then you want to allocate a writable string with for example strdup():
#include <string.h>
// ...
char *array[4][8];
array[0][0] = strdup("test");
free(array[0][0]);
You could also change the type to const as you cannot change that string literal:
const char *array2[4][8];
array2[0][0] = "test";
Or perhaps you meant to copy the data into an an array:
#include <string.h>
//...
char array3[4][8];
strcpy(array3[0], "test");

the error is may be beacuse you trspecifing row and not column of the array(remeber you are using 2D array).
Try this:
int main() {
char *array[4][8];
array[0][0] = "test";
}

Related

String with Variables Concatenation Issue [duplicate]

This question already has answers here:
How can I correctly assign a new string value?
(4 answers)
Closed 1 year ago.
#include<stdio.h>
int main() {
char R_FPD[] = "+00393E33mm/go";
char R_FPH[] = "+00393E33mm/go";
char R_Vel[] = "+00393E33mm/go";
char R_Tot[] = "+00393E33mm/go";
char str_msg[] = "{"+"flow_rate_per_day"+":"+R_FPD+","+"flow_rate_per_hour"+":"+R_FPH+","+"velocity"+":"+R_Vel+","+"totalizer"+":"+R_Tot+"}";
printf("%s", str_msg);
return 0;
}
i want to make it like a json object but its not working
Arrays in C decay to pointers to their first elements and adding pointers is not defined in C standard.
The simplest way to concatenate string like this is using sprintf function. It works like printf but it prints into a C-string.
In your case the pattern could be following:
char str_msg[BIG_ENOUGH];
sprintf(str_msg, "{flow_rate_per_day:%s,flow_rate_per_hour:%s,velocity:%s,totalizer:%s}", R_FPD,R_FPH,R_Vel,R_Tot);
BIG_ENOUGH should be larger then the longest string that can be formed. 256 should be enough in your case.
Alternatively you can use asprintf function that will automatically allocated a buffer of the right size. Remember to use free when the buffer is no longer needed.
char *str_msg;
asprintf(&str_msg, "{flow_rate_per_day:%s,flow_rate_per_hour:%s,velocity:%s,totalizer:%s}", R_FPD,R_FPH,R_Vel,R_Tot);
... use str_msg
free(str_msg);

Receive an array of strings from a function and find out it's length [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I have this code:
char** SplitToWords(char* str);
int main()
{
char** wordarr;
char str[] = "This is a sentence";
wordarr = SplitToWords(str);
return 0;
}
After the main comes the function implementation.
I am not sure the following does what I want it to do (i.e. receive an array of strings from a function):
wordarr = SplitToWords(str);
I somehow managed to convince the compiler that it's ok, but I assume it just does something else.
If it does, how do I find out the length of the array (the number of strings in it).
Thanks
I'll try to quickly visit all aspects you might not yet fully understand:
A string in C is described as a contiguous sequence of chars, ending with a char of value 0 (as a literal: '\0'). It is not a first class object, therefore hasn't its own type. So what you use to hold a string is an array of char. Therefore, taking your question by the word, "receive an array of strings from a function" is not possible.
An array is a contiguous sequence of objects of the same type. In C, the identifier of an array doesn't have a value itself; when it's evaluated, it decays as a pointer to the array's first element instead. This is especially important when passing arrays to functions or returning them from functions -- you can't actually pass the array, you always pass a pointer
e.g. you could write:
char x[] = "foo"; // initialize a char array from a string literal
char *xp = x; // here, x evaluates as a pointer to the first element of the array
You already use pointer types for your function's argument and return value, I just think it's quite important to understand what happens entirely.
You write char** SplitToWords(char* str); and ask whether this returns an "array of strings" -- well, sort of, as you should understand after reading 1. and 2. -- What it does is returning a pointer to char *. This pointer could be a pointer to the first element of an array. So in this case, it would return a pointer to an array of char * pointers. Each of these pointers could itself be a pointer to an array of chars, therefore point to a string. But what's very important is to understand you never return an array, you always return a pointer to it. It's so important because:
You might get the idea to do something like this:
char** SplitToWords(char* str)
{
char *words[16];
// code to fill `words` with pointers to the actual words
return words; // WRONG!
}
Here, because you're not returning the array words but a pointer to it (see point 2), you return a pointer to an object that no longer exists. words is in the scope of your function and has automatic storage duration, that means it only lives as long as the execution is inside of the function. One solution would be to declare words with the static storage class specifier. This way, it lives for the entire execution time of the program. But be aware that this also means there's only a single instance ever, it's always the same object. This will be a major headache for threaded programs, for example. The other way around is to dynamically allocate words using malloc(). But then, the caller of the function must free() it later.
As for your second question, how to let the caller know the number of words -- it's in the comments already, but just for completeness, a typical approach to solve this is to append another entry that is a NULL pointer. So the caller can iterate over the pointers until it finds NULL.
Regarding your comment, of course you can create the array outside the function and pass a pointer to the function, so the function only fills it. This is a common idiom in C (e.g. think about fgets(), which takes a pointer to the char array that's filled with a string by the function).
Functions working this way will need an additional size_t parameter, so they know the size of the array they should fill through the pointer, otherwise you'd have the risk of buffer overflows (this is why gets() was finally removed from the C standard). If you decide that the caller provides the storage, your function should have this prototype:
// returns the number of words found, up to `nwords`
size_t SplitToTwords(char **words, size_t nwords, char *str);
It should be called e.g. like this:
char *words[16];
size_t nwords = SplitToWords(words, 16, "the quick brown fox"); // returns 4
Remember that the strings holding the words themselves need storage as well. You can either manipulate the bytes in str to insert a '\0' after each word, overwriting the first whitespace character (this is what strtok() does) or you can copy the words to new strings, but then you would have to malloc() each of them again and the caller has to free() them later.
Yes, you could solve it by using a function with return value char **. However, there's no way to find out how many words there are afterwards.
You can solve this by allocating one more element for the return pointer and set it to NULL. Then you can get the number of words with this code:
wordarr = SplitToWords(str);
char **ptr=wordarr;
int noWords=0;
while(!*(ptr+noWords))
noWords++;
But if you want to return multiple data in C, you either need to define a return struct or using return arguments. In this case, it could look like this for the first option:
typedef struct wordList {
char **wordarr;
int noWords;
}
wordList SplitToWords(char* str);
And the second:
char** SplitToWords(char* str, int *noWords);
or
void SplitToWords(char* str, char*** wordarr, int *noWords);
Note that there's three *. That's because we want it to be a pointer to char **
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSTRINGS 5000
int main(int argc, char *argv[]) {
char *stringTable[MAXSTRINGS];
char sentence[] = "This is a sentence";
char *token = NULL;
int i = 0;
while ((token = strtok(token == NULL ? sentence : NULL, " ")) != NULL)
{
printf("%s\n\r", token);
stringTable[i] = (char *)malloc(strlen(token) + 1); //have no "plain" C compiler - VS C++ used so cast needed :)
strcpy(stringTable[i++], token);
}
stringTable[i] = NULL; // if you need to iterate through later
printf("%d tokens found\n\r", i);
for (int y = 0; y < i; y++)
free(stringTable[y]);
}

Building char array from a string (C)

I am writing a simple function in C that should build a char array from string "abc" – so it should build {'a','b','c'} – and return a pointer to that array. Here is my code for this function:
char * makeArr()
{
static char arr[3];
sprintf(arr, "%s\n", "abc");
return arr;
}
Problems occur when I call this method in main:
int main(int argc, char *argv[])
{
char *arr[3];
arr = makeArr();
return 0;
}
The compiler is complaining about casting / conflicting types. I've been playing with pointers, casting and dereferencing for quite a while now, but can't seem to get it to work. Please let me know where my logic is wrong.
Hmm ... there are several errors in this code. Let's start with the most obvious your compiler complains about:
char *arr[3];
This line declares arr to be an array of three pointers to char. What you return from your function is a single pointer to a char -> doesn't match.
Next:
static char arr[3];
sprintf(arr, "%s\n", "abc")
Here you reserve 3 chars. the sprintf() will write 5 chars. %s is replaced by the 3 characters in your string literal "abc". You add a newline character and then a 0 is added as the marker for the end of the "string". Makes 5. This btw is undefined behavior. You write past the end of your array. Code like this can be compiled, but there's no guarantee at all about what will happen at runtime.
Doing a cut here. You should read about arrays and pointers in C. If the text you're reading claims they are the same ... stop right there and find a better text. They aren't.
I'll try to explain this here briefly, so it's suitable for the Q&A style.
An array in C indeed is a contiguous space of several values. char arr[3] means a variable that holds 3 chars.
On the other hand, a char * is just a pointer pointing to a char -- this could be the first element of an array.
In C, you can't pass arrays as function parameters, and you can't return arrays from a function. Trying to do so leads to an implicit conversion: What is actually passed is a pointer to the first element of that array.
I think the last bit of information missing is what a string literal in C is: it's an array (anonymous, e.g., it doesn't have a name) containing all the characters in the double quotes plus a 0 appended. The 0 marks the end of a "string" in C.
In an expression, a string literal evaluates to a pointer to the first element.
So, something like this:
char *foo = "bar";
will lead to foo pointing to the b of the array. It's like writing
static const char no_name_0[] = { 'b', 'a', 'r', 0 };
char *foo = &(no_name_0[0]);
Among other things, you confused:
char arr[3]; // array of 3 chars.
and,
char *arr[3]; // array of 3 pointers to char.
In main(), you should only write char *arr;
Firstly, char arr[3]; is too snall to store "abc\n". It must have at least 5 elements including terminating null-character.
Then, char *arr[3]; is a 3-element array of char*.
You should assign makeArr()'s return value (it has char* type) to arr[0] or another element, or you should change the type of arr in main function to char*, which is the same type as makeArr()'s return value.
Moreover, this makeArr() doesn't make any array and returns (a pointer to) the existing array. Yoy should use malloc() to "make an array".
UPDATE:
Assigning a value of char* to the array char arr[10]; seems invalid in C.
You should use strcpy() or strncpy() (safer than strcpy()) to copy the string stored in the array between arrays.
Pass the array as an argument and modify it in the called function, would be easier. If you're statically creating the array and there's no need to allocate memory, don't, just pass around your pointers to the functions to be modified by reference
void makeArr(char arr[]){
sprintf(arr, "%s\n", "abc");
}
Simply pass the existing declared array to the makeArr function...
int main(int argc, char *argv[]) {
char arr[10];
makeArr(arr);
return 0;
}
You couldn't assign the result of makeArr to arr. I guess that's your casting error. Oversimplifying, arr points to the place on the stack where the array of 10 characters is allocated. So, I'd pass in arr to makeArr as a char*. So, you'd end up with something like this:
#include <stdio.h>
char * makeArr(char *arr)
{
sprintf(arr, "%s\n", "abc");
return arr;
}
int main(int argc, char *argv[])
{
char arr[10];
makeArr(arr);
printf("%s\n", arr);
return 0;
}

Assigning a String value to a row

I'm thinking how can I assign a string value to a row in a 2*2 character array in C?
this can be done in java like this:
char [][] array = new char[10][10];
array[1] = "foo".toCharArray();
In C, you can't "assign" to an array. You can, however, copy a string literal (or any string) into the array. You just need to make sure that you don't cause buffer overflows:
char arr[10][10];
const char *str = "foo";
if (strlen(str) < sizeof(arr[1])) {
strcpy(arr[1], str);
}
Alternatively, you can assign to a pointer (which is a member of an array of pointers):
const char *arr[10];
arr[1] = "foo";
One can't really tell which one you need to use unless you provide more context as to what you want to use the array for.

C struct array assignment problems

I'm new to C and I am working with a struct array. I'm having trouble assigning values to it. here is my struct..
struct student{
char firstname[30];
char surname[30];
int streetNo;
char streetName[30];
char suburb[30];
char state[4];
int postCode;
char DOB[10];
int studentNo;
char gender;
char courseNo[4];
char active;
int WAM;
};
struct student person[1000];
here is me assigning a value to the struct
person[100].firstname = "dan";
and this is my error
assignment type mismatch: array[30] of char "=" pointer to char
You can only initialize array like that at the time of declaration only, else you need to use
strcpy(person[100].firstname,"dan");
you can't even do like that with a simple char array
char a[30];
a="dan";
the complier will tell :
incompatible types when assigning to type ‘char[30]’ from type ‘char *’
because "dan" is a string literal that is being held by a pointer which can't be assigned like this to an array.
Although you can initialize an array of characters from a string literal like this
char str[] = "dan";
you cannot assign a string literal to an array of characters the way you are trying to do.
You need to copy your string into the character array using one of the string copy functions:
strcpy(person[100].firstname, "dan");
If yo would like to copy "dan" into the first four elements and pad the remaining elements of firstname with zeros, use strncpy:
strncpy(person[100].firstname, "dan", 30);
It is worth pointing out that you could make firstname a pointer, and either allocate memory for your strings dynamically, or assign it directly:
struct student{
char *firstname;
char *surname;
/* and so on... */
};
student[100].firstname = "dan";
student[100].surname = "brown";
In C, a string like this is implemented using a character array. A character array is exactly what you have defined, but it is not possible to assign a string directly like this in C. You will have to use string functions for that. The function to use is strcpy(). You have to assign like:-
strcpy(person[100].firstname, "dan");
Arrays are not pointers, and this is one example of it.
Arrays cannot be assigned to, only array elements can be assigned to.
You could do
person[100].firstname[0] = 'd';
person[100].firstname[1] = 'a';
person[100].firstname[2] = 'n';
person[100].firstname[3] = '\0'; /* Pretty tedious... */
or, if you know that you don't copy more than 30 bytes,
strcpy (person[100].firstname, "dan");
An array name itself gives array base address.. And an array base address cannot be a left side value.
person[100].firstname =
gives you error since you are assigning some other value to array base address which is not allowed.
You can initialize
char stringArray[] = "some string";
but you can't assign value to already declared array
char stringArray[100];
stringArray = "some string"; <== error
You alternative is to use strcpy
strcpy(stringArray, "sometext");
The specific problem is that you are attempting to assign a string to an array of bytes.
What you need to do in that particular case is to copy the contents of the string you want into the array, like so:
strncpy(person[100].firstname, "dan", 30);
A more general problem is what you are doing is terrible. For student records like this, the only sensible thing to do is to use a proper database; in your case using SQLite is probably appropriate. Using a database for a simple learning exercise like so might seem like overkill, but it is experience that'll help you out a lot later.
You can strcpy() for assigning value to char array.
strcpy(person[100].firstname,"Dan");
You can't assign like this to an array. Even without a struct. That is
char name[10];
name = "ert";
is an error.
(You can do it only in initialization char name[10] = "ert";)
The correct way to do it is
strcpy(person[100].firstname, "dan");
Safer to use a variation of strcpy that requires a max size of string.

Resources