If you don't want to change the strings, then you could simply do
const char *a[2];
a[0] = "blah";
a[1] = "hmm";
When you do it like this you will allocate an array of two pointers to const char. These pointers will then be set to the addresses of the static strings "blah" and "hmm".
If you do want to be able to change the actual string content, the you have to do something like
char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");
This will allocate two consecutive arrays of 14 chars each, after which the content of the static strings will be copied into them.
suppose I have this line of code:
char myarr[10][0];
myarr[1][0] = "test";
printf("myarr: %c\n",myarr[1][0]);
Why does this give an error and how do I assign string to myarr?
If you don't want to change the strings, then you could simply do
const char *a[2];
a[0] = "blah";
a[1] = "hmm";
When you do it like this you will allocate an array of two pointers to const char. These pointers will then be set to the addresses of the static strings "blah" and "hmm".
If you do want to be able to change the actual string content, the you have to do something like
char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");
This will allocate two consecutive arrays of 14 chars each, after which the content of the static strings will be copied into them.
There are several ways to create an array of strings in C. If all the strings are going to be the same length (or at least have the same maximum length), you simply declare a 2-d array of char and assign as necessary:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");
You can add a list of initializers as well:
char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};
This assumes the size and number of strings in the initializer match up with your array dimensions. In this case, the contents of each string literal (which is itself a zero-terminated array of char) are copied to the memory allocated to strs. The problem with this approach is the possibility of internal fragmentation; if you have 99 strings that are 5 characters or less, but 1 string that's 20 characters long, 99 strings are going to have at least 15 unused characters; that's a waste of space.
Instead of using a 2-d array of char, you can store a 1-d array of pointers to char:
char *strs[NUMBER_OF_STRINGS];
Note that in this case, you've only allocated memory to hold the pointers to the strings; the memory for the strings themselves must be allocated elsewhere (either as static arrays or by using malloc() or calloc()). You can use the initializer list like the earlier example:
char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};
Instead of copying the contents of the string constants, you're simply storing the pointers to them. Note that string constants may not be writable; you can reassign the pointer, like so:
strs[i] = "bar";
strs[i] = "foo";
But you may not be able to change the string's contents; i.e.,
strs[i] = "bar";
strcpy(strs[i], "foo");
may not be allowed.
You can use malloc() to dynamically allocate the buffer for each string and copy to that buffer:
strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");
BTW,
char (*a[2])[14];
Declares a as a 2-element array of pointers to 14-element arrays of char.
Videos
In this line:
scanf("%s", &word[i]);
You need to make sure word[i] is pointing somewhere, and has enough space to occupy the string entered. Since word[i] is a char * pointer, you need to at some time allocate memory for this. Otherwise, it is just a dangling pointer not pointing anywhere.
If you want to stick with scanf(), then you can allocate some space beforehand with malloc.
malloc()allocates requested memory on the heap, then returns avoid*pointer at the end.
You can apply malloc() in your code like this:
size_t malloc_size = 100;
for (i = 0; i < 3; i++) {
word[i] = malloc(malloc_size * sizeof(char)); /* allocates 100 bytes */
printf("Enter word: ");
scanf("%99s", word[i]); /* Use %99s to avoid overflow */
/* No need to include & address, since word[i] is already a char* pointer */
}
Note: Must check return value of malloc(), because it can return NULL when unsuccessful.
Additionally, whenever you allocate memory with the use of malloc(), you must use free to deallocate requested memory at the end:
free(word[i]);
word[i] = NULL; /* safe to make sure pointer is no longer pointing anywhere */
Another approach without scanf
A more proper way to read strings should be with fgets.
char *fgets(char *str, int n, FILE *stream)reads a line from an input stream, and copies the bytes over tochar *str, which must be given a size ofnbytes as a threshold of space it can occupy.
Things to note about fgets:
- Appends
\ncharacter at the end of buffer. Can be removed easily. - On error, returns
NULL. If no characters are read, still returnsNULLat the end. - Buffer must be statically declared with a given size
n. - Reads specified stream. Either from
stdinorFILE *.
Here is an example of how it can be used to read a line of input from stdin:
char buffer[100]; /* statically declared buffer */
printf("Enter a string: ");
fgets(buffer, 100, stdin); /* read line of input into buffer. Needs error checking */
Example code with comments:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUMSTR 3
#define BUFFSIZE 100
int main(void) {
char *words[NUMSTR];
char buffer[BUFFSIZE];
size_t i, count = 0, slen; /* can replace size_t with int if you prefer */
/* loops only for three input strings */
for (i = 0; i < NUMSTR; i++) {
/* read input of one string, with error checking */
printf("Enter a word: ");
if (fgets(buffer, BUFFSIZE, stdin) == NULL) {
fprintf(stderr, "Error reading string into buffer.\n");
exit(EXIT_FAILURE);
}
/* removing newline from buffer, along with checking for overflow from buffer */
slen = strlen(buffer);
if (slen > 0) {
if (buffer[slen-1] == '\n') {
buffer[slen-1] = '\0';
} else {
printf("Exceeded buffer length of %d.\n", BUFFSIZE);
exit(EXIT_FAILURE);
}
}
/* checking if nothing was entered */
if (!*buffer) {
printf("No string entered.\n");
exit(EXIT_FAILURE);
}
/* allocate space for `words[i]` and null terminator */
words[count] = malloc(strlen(buffer)+1);
/* checking return of malloc, very good to do this */
if (!words[count]) {
printf("Cannot allocate memory for string.\n");
exit(EXIT_FAILURE);
}
/* if everything is fine, copy over into your array of pointers */
strcpy(words[count], buffer);
/* increment count, ready for next space in array */
count++;
}
/* reading input is finished, now time to print and free the strings */
printf("\nYour strings:\n");
for (i = 0; i < count; i++) {
printf("words[%zu] = %s\n", i, words[i]);
free(words[i]);
words[i] = NULL;
}
return 0;
}
Example input:
Enter a word: Hello
Enter a word: World
Enter a word: Woohoo
Output:
Your strings:
words[0] = Hello
words[1] = World
words[2] = Woohoo
There seems to be a bit of confusion in this area. Your primary problem is you are attempting to write each word to the address of each of pointers you declare with char *word[3];. (not to mention you have no storage allocated at the location pointed to by each pointer -- but you never get there as you attempt to write to the address of each pointer with &word[i] rather than to the pointer itself)
While you can use scanf you will quickly run into one of the many pitfalls with taking user input with scanf that plague all new C programmers (e.g. failing to handle the '\n' left in the input buffer, failing to handle whitespace in strings, failing to limit the number of characters read/written, failing to validate the read or handle EOF, etc...)
A better approach is to simply use fgets and then trim the '\n' that fgets read and includes in the buffer to which it stores the string. A simple example would be:
#include <stdio.h>
#include <string.h>
#define NWDS 3 /* declare a constant for the maximum number of words */
int main (void) {
int i, n = 0;
char word[NWDS][50] = { "" }; /* provide storage or allocate */
for (i = 0; i < NWDS; i++) { /* for a max of NWDS */
printf ("Enter word : "); /* prompt */
if (!fgets (word[i], sizeof word[i], stdin)) /* read/validate */
break; /* protect against EOF */
size_t len = strlen (word[i]); /* get length */
if (word[i][len-1] == '\n') /* check for trailing '\n' */
word[i][--len] = 0; /* overwrite with nulbyte */
}
n = i; /* store number of words read */
putchar ('\n'); /* make it pretty */
for (i = 0; i < n; i++) /* output each word read */
printf (" word[%d] : %s\n", i, word[i]);
#if (defined _WIN32 || defined _WIN64)
getchar(); /* keep terminal open until keypress if on windows */
#endif
return 0;
}
Go ahead and cancel input at any time by generating an EOF during input (ctrl + d on Linux or ctrl + z on windoze), you are covered.
Example Use/Output
$ ./bin/wordsread
Enter word : first word
Enter word : next word
Enter word : last word
word[0] : first word
word[1] : next word
word[2] : last word
Looks things over, consider the other answers, and let me know if you have further questions.
There are a bunch of misconceptions regarding strings. Your array temp needs to be big enough to also store the null-terminator, so it needs a size of at least 6 in this case:
char temp[6] = "begin"; // 5 chars plus the null terminator
To copy the string, use strcpy:
char temp_list[10];
strcpy(temp_list, temp);
To print it, pass temp_list, not temp_list[i], also you don't need that loop:
printf("%s\n", temp_list);
The final program could look like this:
int main()
{
char temp[6] = "begin";
char temp_list[10];
strcpy(temp_list, temp);
printf("%s\n", temp_list);
return 0;
}
You have three problems here. First, temp is not big enough to hold the string "begin". Strings in C are null terminated, so this string actually takes up 6 bytes, not 5. So make temp big enough to hold this string:
char temp[6] = "begin";
Or better yet:
char temp[] = "begin";
Which sizes the array exactly as needed for the string. The second problem is here:
temp_list[0] = temp;
You're assigning an array (actually a pointer to the array's first element) to the first element of another array. That's a type mismatch of assigning a char * to a char. Even if the types matched, that's not how strings are copied. For that, use the strcpy function:
strcpy(temp_list, temp);
Finally, you're not printing the result correctly:
for (int i = 0; i < strlen(temp_list); i++)
{
printf("Labels: %s,", temp_list[i]);
}
The %s format specifier expects a pointer to a char array in order to print a string, but you're passing in a single characters. Mismatching format specifiers invokes undefined behavior.
For printing single characters, use %c instead:
for (int i = 0; i < strlen(temp_list); i++)
{
printf("Labels: %c,", temp_list[i]);
}
Or you can get rid of the loop and just print the whole string using %s:
printf("Labels: %s", temp_list);
I know that strings are char arrays already and I was wondering if there's a way to store not strings in an array. It would be like storing arrays into an array and that sounds a bit weird.
As far as I know an array is a pointer so I'd tend to say no, but after all pointers are just storing numbers like any variable.
To maybe be clearer, what I'd want to do is have an array that's like that :
array[0] = BLUE
array[1] = RED
array [2] = YELLOW
etc
Hi, super new to C and working through some tutorials online. I'd like to get user input and add it to an array in location 0. I tried doing an integer and that works just fine but I can't get the string part to work. Here's my code:
#include <stdio.h>
int main()
{
int intArray[1];
int num = 5;
intArray[0] = num;
printf("I put %d into intArray[0] and everything is great!\n", intArray[0]);
char stringArray[1];
char name[20];
printf("What is your name?\n");
scanf("%s", name);
printf("This is what you entered for your name: %s\n", name);
stringArray[0] = name;
printf("%s should be stringArray[0] but it doesn't work!\n", stringArray[0]);
return 0;
}I get the following errors back when compiling:
/C Projects/arraysyay.c: In function ‘main’:
/C Projects/arraysyay.c:15:20: warning: assignment to ‘char’ from ‘char *’ makes integer from pointer without a cast [-Wint-conversion]
15 | stringArray[0] = name;
| ^
/C Projects/arraysyay.c:16:14: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
16 | printf("%s should be stringArray[0] but it doesn't work!\n", stringArray[0]);
| ~^ ~~~~~~~~~~~~~~
| | |
| char * int
| %dI've googled both of these warnings and read other people's code containing these warnings but I can't seem to adapt their solution to my problem. Can anyone please tell me where I'm going wrong and how I can fix it? Thanks!
You need a 2 dimensional character array to have an array of strings:
#include <stdio.h>
int main()
{
char strings[3][256];
scanf("%s %s %s", strings[0], strings[1], strings[2]);
printf("%s\n%s\n%s\n", strings[0], strings[1], strings[2]);
}
Use a 2-dimensional array char input[3][10];
or
an array of char pointers (like char *input[3];) which should be allocated memory dynamically before any value is saved at those locations.
First Case, take input values as scanf("%s", input[0]);, similarly for input[1] and input[2]. Remember you can store a string of max size 10 (including '\0' character) in each input[i].
In second case, get input the same way as above, but allocate memory to each pointer input[i] using malloc before. Here you have flexibility of size for each string.