I'm trying to understand what is wrong here.
void longestConsec(char* strarr[], int n) {
for(int i=0; i<n; i++)
{
printf("%s\n",strarr[i]);
}
}
int main()
{
char string[8][14] = {"zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"};
longestConsec(string, 8);
return 0;
}
I want to print every single word, and for some reason it doesn't work. What I think of is that strarr is array of pointer to char, so in every cell there should be a word, right? But when i tried to debug the code i saw that strarr and strarr[0] have different memory locations. Why?
strarr is an array of pointers to char, but string is not an array of pointers but an array of 14-element array of chars.
Pointers and 14-element array of chars may have different size, so your code won't work well.
How about using array of pointers like this?
#include <stdio.h>
void longestConsec(const char* strarr[], int n) {
for(int i=0; i<n; i++)
{
printf("%s\n",strarr[i]);
}
}
int main()
{
const char* string[8] = {"zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"};
longestConsec(string, 8);
return 0;
}
Your compiler should have given you a warning that gives a good hint.
k.c:12:19: warning: passing argument 1 of ‘longestConsec’ from incompatible pointer type [-Wincompatible-pointer-types]
12 | longestConsec(string, 8);
| ^~~~~~
| |
| char (*)[14]
k.c:2:26: note: expected ‘char **’ but argument is of type ‘char (*)[14]’
2 | void longestConsec(char* strarr[], int n) {
| ~~~~~~^~~~~~~~
string is an array of arrays, char[8][14] and strarr is a pointer to pointer to char, char **. When string is passed to the function it decays to pointer to array of 14 char, char (*)[14]. Passing multidimensional arrays to functions can be tricky, but this works:
// size_t is better than int in this case
void longestConsec(size_t len, char strarr[][len], size_t n)
{
for(int i=0; i<n; i++)
printf("%s\n",strarr[i]);
}
And then call it with:
longestConsec(sizeof string[0]/sizeof string[0][0], // 14
string,
sizeof string/sizeof string[0] // 8
);
Note that you can write sizeof string[0] instead of sizeof string[0]/sizeof string[0][0] but that's because sizeof char is always 1.
Understanding these declarations can be a bit tricky. Just to give a type example of how they are declared:
char (*arr)[10]; // arr is a pointer to array of char of size 10
char *arr[10]; // arr is an array of 10 pointers to char
Related: arrays are not pointers and pointers are not arrays
Related
I am writing a program to check if a string is inside an array of strings.
I predefined an array of words before the main method
const char *items[] = {"a","b","c","d"};
then I have a function like
bool isInside(const char *array[], char *s1){
//which will try to compare all strings from the input array with s1
int len = sizeof(array)/sizeof(array[0]);
for (int i =0; i< len ; i++){
//do string comparasion}
}
It worked before but not sure where I messed up the code now I got two errors and the function is only able to check the first string of the array with s1.
I found out the problem is that now len = 1 always.
one of the errors is
`warning: ‘sizeof’ on array function parameter ‘array’ will return size of ‘const char **’ [-Wsizeof-array-argument]` and the other one is
isInside(items, words[i]))
| ^~~~~~~~~
| |
| const char **
code.c:63:21: note: expected ‘char *’ but argument is of type ‘const char **’
How can I fix this or call this function so the length is correct and no type warning?
Thanks a lot.
Arrays in C will degrade to pointers when passed as arguments to functions. When they become pointers, their length cannot be retrieved by sizeof.
You should pass the length of arrays as an additional argument to the function.
Maybe your function can be modified as:
bool isInside(const char **array, int arrayLength, char *s1){
for (int i =0; i< arrayLength; i++){
const char* str = array[i];
if(strcmp(str, s1) == 0){
return 1;
}
}
return 0;
}
I am trying to add strings to the stack. Please tell me what's wrong in the program.
In this program, I am trying to implement the stack as a data structure. I know how to add numbers to the stack and / or remove them, but I don't know how to add character input. Right now I want to do something like a list of items and then print the whole list.
//Array implementation of the stack
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 11
char A[MAX_SIZE];
int top = -1;
void Push(char x[])
{
if (top == MAX_SIZE - 1) {
printf("Error! Array size: %d exceeded\n", MAX_SIZE);
return;
}
A[++top] = x;
}
void Pop() {
if (top == -1) {
printf("Error! No element to pop\n");
return;
}
top--;
}
char Top()
{
return A[top];
}
void Print()
{
int i;
printf("Stack: ");
for (i = 0; i <= top; i++)
printf("%s ", A[i]);
printf("\n");
}
int main()
{
char name1[10] = "Pablo";
Push(name1);
char name2[10] = "Robert";
Push(name2);
Print();
}
invalid conversion from 'char' to 'char' [-fpermissive]
16 | A[++top] = x;
| ^
| |
| char*
The elements of the array
char A[MAX_SIZE];
are char, which can store only one character.
On the other hand, the argument x is char* (char x[] has the same meaning as char* x in function arguments). Therefore type mismatch occurs.
Changing the array to
char* A[MAX_SIZE];
and the function Top to
char* Top()
will make your program work.
Note that then the pointers will be directly stored instead of copying strings, so be careful not to dereferenced pointers to vanished object. (This won't be problem in this code)
Your stack A is declared as an array of char, so it can only hold a single string (or an array of characters). In the line in question, you're attempting to assign a char * to a single char.
You should instead define A as an array of char *:
char *A[MAX_SIZE];
I get the warning Return from incompatible pointer type in line where I return sarray, why though? I have been trying to figure out for a while now.. I also get a warning for incompatible pointer type in line
( *iarray )[CHARACTER_LIMIT] = scanCode();
but I think if I fixed the first part, this would be easier to fix this one.
#include <stdio.h>
#define MAX_WORDS 9054 //Scope variables
#define CHARACTER_LIMIT 6
#define MAX_TRIPLETS 3018
char** scanCode(void)
{
FILE *in_file;
int i = 0;
static char sarray[MAX_WORDS][CHARACTER_LIMIT];
in_file = fopen("message.txt", "r");
for(i=0; i<WORD_COUNT_MAX; i++) {
fscanf(in_file,"%s", sarray[i]);
}
return sarray;
fclose(in_file);
}
int main(void)
{
char ( *iarray )[CHARACTER_LIMIT] = scanCode();
while(1);
return 0;
}
sarray is an array or arrays, which can decay to pointer to array, but not pointer to pointer. Converting sarray to char** should be an error.
Besides that, scanCode() returns a pointer to pointer to char. iarray is a pointer to array of char with length CHARACTER_LIMIT. These are not the same type, and the compiler is warning you about this.
You need to change either the return type of the function:
char (*scanCode(void))[CHARACTER_LIMIT] {
....
return sarray;
}
Here, sarray decays to a pointer to array of length CHARACTER_LIMIT.
I've been trying to assign char words[x][y] to a char* pointer[x]. But compiler is giving me a error
array type 'char *[5]' is not assignable
pointer = &words[0]
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(){
char words[5][10]={"Apple", "Ball", "Cat", "Dog", "Elephant"};
char *pointer[5];
pointer = &words[0];
char **dp;
dp = &pointer[0];
int n;
for(n=0; n<5; n++){
printf("%s\n", *(dp+n));
}
return 0;
}
But the code works while
char *pointer[5]={"Apple", "Ball", "Cat", "Dog", "Elephant"};
char **dp;
dp = &pointer[0];
all I need is to correctly assign the 2D array into pointer array!!
Unfortunately, you can't do it the way you want. char words[5][10] doesn't store the pointers themselves anywhere, it is effectively an array of 50 chars. sizeof(words) == 50
In memory, it looks something like:
'A','p','p','l','e','\0',x,x,x,x,'B','a'...
There are no addresses here. When you do words[3] that is just (words + 3), or (char *)words + 30
On the other hand, char *pointer[5] is an array of five pointers, sizeof(pointer) == 5*sizeof(char*).
So, you need to manually populate your pointer array by calculating the offsets. Something like this:
for (int i = 0; i < 5; i++) pointer[i] = words[i];
The error on pointer = &words[0]; happens because you are taking an 'array of pointers' and make it point to the first array of characters, since pointer points to a char this makes no sense. Try something like:
char *pointer[5];
pointer[0] = &words[0][0];
pointer[1] = &words[1][0];
//...
This will make your pointers to point at the first char of your strings (which I assume is the desired behavior?)
main() {
char names [5][20] = {
"rmaesh",
"ram",
"suresh",
"sam"
"ramu"
};
char *t;
t = names[2];
names[2] = names[3];
names[3] = t;
printf(" the array elemsnt are \n");
int i = 0;
for (i = 0; i < 5; i ++)
printf("\n%s", names[i]);
}
i am getting below error while compiling this program
stringarrary.c: In function ‘main’:
stringarrary.c:12:11: error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’
names[2] = names[3];
^
stringarrary.c:13:11: error: incompatible types when assigning to type ‘char[20]’ from type ‘char *’
names[3] = t;
It is illegal to try and assign to an array. In this case you should use the strcpy function. Note that your char *t; idea does not work either if you intend to swap the two arrays, because it only points at one of your existing strings; as soon as you write over names[2], that data is gone.
char t[20];
strcpy(t, names[2]);
strcpy(names[2], names[3]);
strcpy(names[3], t);
Also, "\n%s" should be "%s\n" - you want the newline to come after what you printed. And don't forget to #include <stdio.h> and #include <string.h>.
The error on line 13 is easiest to understand: names[3] is an array of char; you can't just assign a pointer to it. On line 12, the compiler is converting names[3] to a pointer and trying to assign it to the array names[2], which is likewise can't do.
Try copying the strings instead. In C, you can't copy arrays using the = operator; use the functions from memcpy or strcpy families.
The names array is a two-dimensional array of characters. As the other answers have pointed out, when you want to copy an array of characters, you need to use memcpy or strcpy.
The alternative solution is to make names a one-dimensional array of pointers. The resulting code would look like this.
int main( void )
{
char *names[5] = {
"rmaesh",
"ram",
"suresh",
"sam",
"ramu"
};
char *t;
t = names[2];
names[2] = names[3];
names[3] = t;
printf(" the array elemsnt are \n");
int i = 0;
for (i = 0; i < 5; i ++)
printf("\n%s", names[i]);
}
The advantage to this method is that it allows you to manipulate the pointers the way you wanted to. The disadvantage is that the strings are read-only. Attempting to modify the strings will result in undefined behavior.
Try this
#include<stdio.h>
#include <string.h>
main() {
char names [5][20] = {
"rmaesh",
"ram",
"suresh",
"sam", //<----- You are missing this (,) at the end
"ramu"
};
char *t;
strcpy( t, names[2]); // And also use this syntax
strcpy(names[2] , names[3]);
strcpy(names[3], t);
printf(" the array elemsnt are \n");
int i = 0;
for (i = 0; i < 5; i ++)
printf("\n%s", names[i]);
}