Inserting an array inside another array in C - arrays

I am trying to make an array variable that, inside each position, it has another array in it. My case is the following:
int main() {
char foo[2];
char dummy[3] = {'F', 'O', 'X'};
foo[1] = dummy;
printf("%c", foo[1]);
/* This printf is like a way of saying "show me the 'dummy' list" */
return 0;
}
With this code, i would expect the console to show me the dummy list. Instead, i got a warning that says:
"warning: incompatible pointer to integer conversion assigning to
'char' from 'char [3]' [-Wint-
conversion]"
I dont know if my problem is well understood, but i would like to get an array position like foo[1] to contain another array like dummy, so when i call foo[1] i get that dummy array.
I hope you can help me and thank you in advance for taking your time to help me.

The variable foo that you have defined is a character array of length two but what you want is an array of character pointers. Note that the character array dummy is non-terminated; it is better to leave out the length and initialize it with a string literal instead. Also, to print a string you need to use %s in the call to printf. Try this:
#include <stdio.h>
int main(void)
{
char *foo[2];
char dummy[] = "FOX";
foo[1] = dummy;
printf("%s\n", foo[1]);
return 0;
}

Related

error: expected expression before ']' token when passing an array as an arguement in C

I am new to C. Was writing this so it takes the strings from the passed array and makes it a single sentence. But I got this error, I am not good with arrays in C. I can use some help from you guys. I did search an answer for this and couldn't find.
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char smash(char arr[20][20]) {
char tmp[sizeof(arr)/sizeof(arr[0])];
for (int i=0; i < sizeof(arr)/sizeof(arr[0]); i++) {
strcat(tmp, arr[i]);
strcat(tmp, " ");
}
return tmp;
}
int main(){
char list[][6] = {"hello", "world"};
printf("%s", smash(list[]));
}
Error
error: expected expression before ']' token
printf("%s", smash(list[]));
^
There are quite a number of errors in this small piece of code.
First, to address the compiler error: list[] is not a valid expression. If you want to pass list to the function, leave the braces out:
printf("%s", smash(list));
This will then bring up another error. The function is expecting a char [20][20] as it's argument, but that's not what you're passing in. Since arrays as parameters are converted to a pointer, the argument type is actually char (*)[20] i.e. a pointer to an array of char of size 20. Note also that this conversion only occurs for the outermost array dimension, not all.
Since you're passing in a char [2][6] which gets converted to a char (*)[6] this is a type mismatch. So change the parameter to char arr[][6].
Then you're attempting to get the size of the array parameter inside of the function:
sizeof(arr)/sizeof(arr[0])
Since arrays cannot be directly passed to a function due to the conversion mentioned earlier, arr is actually a pointer and not an array, so you won't get the result you expect from this. You'll need to pass the number of array elements as a separate parameter.
Then you're calling strcat on tmp. This function will only work if the destination already has a null terminated string in it. Since tmp was not initialized or written to prior to the first call to strcat, you end up reading uninitialized bytes and potentially past the end of the array which will trigger undefined behavior.
This can be fixed by setting the first byte of the array to 0 before the loop to make it an empty string:
tmp[0] = 0;
for ...
Then there's the problem with the return type. The function is declared to return a char but you're giving a char * to the return statement, and at the point the function is called it is passed to printf where the %s format specifier is expecting a char * parameter.
So change the return type of the function from char to char *.
Finally, you're returning a pointer to a local variable in the function. This variable's lifetime ends when the function returns, so the returned pointer is invalid and using it will also trigger undefined behavior.
You'll need change tmp to a pointer and dynamically allocate memory for it using malloc. This also means you'll need to save the return value of the function in a separate variable which you can then pass to printf to print and then pass to free to free the memory.
After making all this changes, the resulting code should look like this:
char *smash(char arr[][6], int len) {
// enough for len strings plus len spaces
char *tmp = malloc(sizeof(arr[0]) * len + len + 1);
tmp[0] = 0;
for (int i=0; i < len; i++) {
strcat(tmp, arr[i]);
strcat(tmp, " ");
}
return tmp;
}
int main(){
char list[][6] = {"hello", "world"};
char *result = smash(list, sizeof(list)/sizeof(list[0]));
printf("%s", result);
free(result);
return 0;
}

Find words with specific beginning letters in a array of words

following situation:
I have a list of words. For example:"Hello","Hey","Help","Shark".
I want to save those in the array apcWord (word-array.. more specific, a pointer-array).
And I have a pointer pcBeg to the beginning string "He"
I have to solve this with this function prototype:
void search (char *apcString[], char *pcBeg)
How can I filter the array of words and just printf the words which start with "He".
I'am totally confused.. I tried some things with strstr() but no result. The problem is the list of words and filter all words with this "He" beginning. if I just have one word and just want to know if its beginning with "He" or not its no problem.
I hope I made my problem as clear as possible.
Thanks for your Help!
I have a list of words ? probabaly you want to declare array of pointer variable of char type. for e.g
char *apcWord[4] = {"Hello","Hey","Help","Shark"};
And I have a pointer pcBeg to the beginning string "He" ? as you said declare a char pointer. for e.g
char *pcBeg = "Hi";
I have to solve this with this function prototype: ? You should learn how to pass array of pointers to function. If you are passing array of char pointers to a function, you need to catch with double pointer of char type. Here is the sample code
void search (char **apcString, char *pcBeg,int ele) {
/* logic */
}
How can I filter the array of words and just printf the words which start with "He". ? use strncmp() instead of strstr(). open man 3 strncmp and third argument of strncmp() is useful for your part of question quoting words which start with "He". Here is the sample code
void search (char **apcString, char *pcBeg,int ele) {
int count = 0;
for(int row = 0 ;row < ele ;row++) {
if(strncmp(apcString[row],pcBeg,strlen(pcBeg)) == 0) {
count++;
}
}
printf(" count of %s is : %d \n",pcBeg,count);
}
Finally how to call search() from main() function
int main(void) {
char *apcWord[5] = {"HelloHi","HiHey","Help","Hi","Shark"};
int ele = sizeof(apcWord)/sizeof(apcWord[0]);
char *pcBeg = "Hi";
search(apcWord,pcBeg,ele);/* 3rd arg :- pass the no of element in the array of pointer */
return 0;
}
I hope I made my problem as clear as possible. ? No you didn't. We don't know what code you tried, its advisable to put the code whatever you tried into your question so that you can get more help.
And finally suggest you to read some good C book about array, pointers etc concept & learn how to debug a small code using gdb https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ .

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;
}

String from a function in C

Currently in the process of learning a bit of c, but I'm having issues with strings.
I simply want to return a string using a function. This is to be part of a bigger program that's supposed to get the word from an external file, but I want a simple function like this just to get going.
PS. Yes the bigger program is for school. I don't want to simply copy code, i want to understand it. Just throwing that out there.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* teststring()
{
return (char*)"donald duck";
}
int main()
{
char word[20];
word = teststring();
return 0;
}
I've tried various variations of returning a string, but my problem is that I'm unsure what to use as return type for the function and how to return it.
This is the most common error i get.
[Error] incompatible types when assigning to type 'char[20]' from type 'char *'
I've tried with different return types, declaring and initializing a char array and return it, and my latest test type conversion.
Thanks in advance.
Arrays (more properly, expressions of array type) cannot be the target of an assignment; you cannot copy the contents of one array to another using the = operator.
For strings, you will need to use either the strcpy or strncpy functions:
strcpy( word, teststring() ); // assumes word is large enough to hold the
// returned string.
For other arrays, use memcpy.
You'd better add const modifier to the function teststring() as it returns a pointer to a const string. You cannot reassign word which is the address of char[20] to a pointer that points to a constant string. It must be copied.
#include<string.h>
#include<stdio.h>
const char* teststring()
{
return "donald duck";
}
int main()
{
char word[20];
strcpy(word, teststring());
printf("%s", word);
return 0;
}

Passing pointers to function

I have a doubt in my program
#include<stdio.h>
int myFunc(char **);
main()
{
char *a[2]={"Do","While"};
myFunc(a);
}
int myFunc(char **P)
{
/* Here I want to print the strings passed but I'm unable to
print the strings I just tried the below statement which
printed just the first letter which is 'D'*/
printf("%c",**P);
}
when i tried
printf("%s",**P);
I am getting run time error. so can anyone please help me out?
Thanks
Madhu
Put size as parameter to allow the function to know how many strings you have in your array. Then, you should iterate the array and print each one.
int myFunc( char** p, int size)
{
for( int i = 0; i < size; ++i)
{
printf("%s", p[i]);
}
}
Later edit (as requested :-) )
int main( int, char**)
{
char *a[2]={"Do","While"};
myFunc( a, 2); // Could be myFunc( a, sizeof(a)/sizeof(char*));
// ...
return 0;
}
Too many stars - try
printf("%s",*P);
And you need %s format specifier - %c is just for single character.
If you want to print all strings, you need to pass number of strings in array and then print these strings from the loop.
Check the code suggested by Cătălin Pitiș. To pass the number of strings, you call function like this:
myFunc(a, sizeof(a)/sizeof(a[0]));
for( int i = 0; i < 2; i++ ) {
char* string = P[i];
printf( "%s", string );
}
And you shoud use some way of passing size of array into the function - either pass it as an int parameter,
int myFunc(char **P, int size)
{
for( int i = 0; i < size; i++ ) {
//whatever here
}
}
or always append a zero value to the array and only loop until you find that zero value.
char* array[] = { "String1", "String2", 0 };
Otherwise you will have hard to maintain code.
I like objective-c style nil (0) terminated arrays:
void myFunc(char **P)
{
while (*P) // loop to iterate over all strings until 0
printf("%s\n",*P++); // print and move to next element in array
}
int main()
{
char *a[]={"Do","While",0}; // added 0 to null terminate array,
myFunc(a); // kind of like string
}
Output:
Do
While
First, the good news: the type of a is equivalent to char **, so you are passing a valid parameter to myFunc().
The first problem is that %c is a format specifier that means print a single character. Since **P is an expression that evaluates to a single character, your first version does exactly what you told it to do. That isn't what you want.
The second version is close to syntactically correct. It should read printf("%s", *P), where *P is an expression that evaluates to a pointer to a nul-terminated ASCII string. In this case, it evaluates to "Do". This version won't print both strings.
Although it is true that the name of an array is the same as a pointer to its first element, that is a kind of "lie to students". Passing an array to a function does not and cannot convey the length of the array. To do that, you need either a second argument containing the length, or a convention like the nul-terminator on a string to indicate the end of the array. With that change, you can modify myFunc() to use a loop over the elements passed and print each one.
The problem in your code is that you want to print a string (char*) but you're giving it a char. Remember that P is an array of char*. When you de-reference it once, you get a char*; when you do it a second time, you just get the char at the beginning of the char*.
When you try to use the char value with the %s specifier, it treats the value as a pointer, and tries to dereference that value. Hence, it will try to print the "string" at the memory location X, where X is the value of the char (i.e. a value from 0 to 255). This gives you an access violation/segmentation fault (the error you see at runtime).
The best workarounds for this, as noted by Cătălin Pitiș and RBerteig, are to either:
pass another parameter to specify the length of the array
add an additional null at the end of the array.
if you don't want to keep and pass around array size::
int myFunc(char **);
main()
{
char *a[2]={"Do","While", NULL};
myFunc(a);
}
int myFunc(char **P)
{
if( !P )
return 0;
while(*P != NULL)
{
printf("%s",*P);
P++;
}
}
Wrong Answer: I think you may have to dereference P when you print it, although I could be wrong.
EDIT: I'm tired, it's 3 am here but I don't feel like sleeping so I'm here trying to answer questions. After reading the criticism, I reread the question and noticed that he does dereference P, but as is stated in another answer, it's dereferenced too much. When one wants to print a char string, one wants to pass a pointer as the char string is really an array.
Another EDIT: I would also like to point out that the person who asked the question made an edit after I answered and that when I first answered it didn't read "printf("%s",**P);" it read "printf("%s", P);" and the last part was bold.

Resources