C - Count elements (bound check) - array [duplicate] - c

This question already has answers here:
How to test for the end of a pointer array?
(3 answers)
How can I find the number of elements in an array?
(16 answers)
C: finding the number of elements in an array[]
(12 answers)
Closed 4 years ago.
is there any way to count the elements in an array of pointers to strings? with elements im refering to every word or phrase in it, here is an example of an array with 3 elements (each phrase in this case).
char *s[] = {
"To err is human...",
"But to really mess things up...",
"One needs to know C!!",
};
So here the array has 3 positions (that would be 3 elements), each pointing to a memory address which is the beginning of a String but it was still difficut to determine whether the array reached the end or not, so I added a fourth element '\0', so at the end it would have 2 null characters and then implemented this function.
int cantidadElementos(char *arr){
int count=0;
while(*arr!='\0'){
while(*arr!='\0'){
arr++;
}
arr++;
if(*arr!='\0'){
count++;
}
}
return count;
}
What I try to do is bound checking, so I figured out that if I use the address of each pointer in the array I could then see the address of the string, and then see if the last value is '\0' (to check if the string reached the end), but that could not be possible since the next memory address of the array could contain garbage values, so I camed up with adding another null character at the end of the array, and then checking if there is a double '\0'.
I just find this solution horrible (works, but still horrible).
This could suit for a text processor, since it is just 2 bytes more of memory that I would use to determine whether the text has reached end or not.
So going back to my question, is there any way to count the elements in an array of pointers to string? I have been searching a lot and couldn't came up with a better solution.

Test this:
const char *s[] = {"To err is human...", "But to really mess things up...", "One needs to know C!!"};
printf("%d\n",sizeof(s)/sizeof(*s));

Unlike arrays, there is no length information in pointers (which is what an array decays to when it is passed as an argument to a function, as you are doing with cantidadElementos). This is precisely why scalar strings are terminated with a null character in C; so that library functions can determine the length of the string and where to stop processing it.
To achieve the same thing with a pointer to pointers to strings, you could use a sentinel value like NULL at the end. Incidentally, this is also how the standard arguments to the main function work:
C Standard, ยง5.1.2.2.1.2:
If they are declared, the parameters to the main function shall obey the
following constraints:
โ€” argv[argc] shall be a null pointer.

Related

Am I 'C'eriously going insane? [duplicate]

This question already has answers here:
Addresses of two char pointers to different string literals are same
(10 answers)
Closed 2 months ago.
Ok so here we are comparing the memory location of the pointer to the string literal name[10] or Michael (or something like that)
char name[10]="michael";
char name2[10]="michael";
if (name == name2) { printf("ok\n");
printf("OKAF\n");
}
And of course if will evaluate to false and nothing happens, however:
char* name="michael";
char* name2="michael";
if (name == name2) { printf("ok\n");
printf("OKAF\n");
}
}
~
3rd example: (this one works as well)
char name="michael";
char name2="michael";
if (name == name2) { printf("ok\n");
printf("OKAF\n");
}
Here we are also comparing the memory location except in this case it evaluates to true?
My question is and I apologize in advance for my vapidity I'm a little confused as to why one works over the other; I have also seen implementations comparing two strings without using strcmp or the likes. What am I missing here can someone explain this to me in a language perhaps I can understand?
I've tried all 3 of those and 2 of the 3 of them evaluate to true as expected but I am still really confused as to why == with the IF statement in C is suppose to compare memory locations why using pointers or poorly initialized and defined chars work if its only suppose to compare memory locations.
First example: You are allocating two arrays pointing at two different locations in code. Result: The pointers are not equal.
Second: You have two distinct pointers that point to the same string.
The compiler MAY optimize these two strings, since they are actually the same, to be stored in the same region of the text part of your program, resulting in the comparison to be successful.
Third: You are not comparing memory locations, you are comparing characters, which just happen to be the same. However you should be getting a warning that you are assigning a const char * to a char.

Can i use the following code or it's incorrect? [duplicate]

This question already has answers here:
Assigning strings to arrays of characters
(10 answers)
Closed 7 years ago.
Well first i'm using language c i still a beginner.
char S[20];
S ="ewer" ;
is that correct.
Arrays (including strings) can't be assigned in C. For strings you need strcpy, or preferably strncpy:
#include <string.h>
...
char S[20];
strcpy(S, "ewer"); // strcpy is fine for this example
strncpy(S, "ewer", sizeof(S)); // strncpy is safer in general and
// should be preferred over strcpy
No, that won't work.
The variable S is an array, and you can't assign to arrays like that in C. The string "ewer" is represented as an array of characters terminated by the character '\0'. To copy it into the array, you need to use a function:
strcpy(S, "ewer");
That's a good question. In fact, if you'd wrote char* S instead, the example would worked. You might be confused by the fact, that arrays and pointers have many alike things โ€” like [] operator.
But you must understand that array is different from a pointer. One of the main differences is that you couldn't increment an array, like ++myArr (this code okay for pointer, but not for an array). The other one you see in the question: you can not reassign an array variable to point another array. That is exactly what you're trying to do: you're assigning to the array variable S a pointer to a place with the text "ewer", that won't work.
Assuming that you wanted to assign to an array the text, you could do the following:
char S[] = "ewer";
Here you say to the compiler to allocate as much space on the stack, as the "ewer" text (plus the zero end character) holds, and copy that text there. Notice the empty braces [] โ€” you don't even need to manually count symbols, it would be done for you by a compiler.

how to loop through array using pointer without known the size of the array [duplicate]

This question already has answers here:
Length of array in function argument
(9 answers)
Closed 8 years ago.
I have a question about loop through array using pointer, for example:
bool loopArray(int* array)
{
/*for(){}*/
}
within this function, I need to loop through this array without known the size of the array, how to loop it?
You can't.
Errrm, that's it.
You either provide a size parameter:
bool loopArray(int* array,size_t sz)
{
for(size_t i=0;i<sz;++i){
//Do stuff with array[i]....
}
}
Or a pointer to the 'end' of the array. You're allowed to point to one past the end and convention is to pass one-past-the-end as end. That allows you to specify 'empty' when begin==end:
bool loopArray(int* array,int* end)
{
for(;array!=end;++array){
//Do stuff with *array....
}
}
Looking at the previous example you would have defined int* end=array+sz before calling.
The second is faster and has the added benefit that other C programmers will start to recognize you as one of their own! If you see that as a benefit....
PS: For completeness: You can ensure you have a 'sentinel'. A sentinel is some value that indicates 'end'. The C standard library uses '\0' as the sentinel in character strings. Mores the pity.
That trick can work particularly when you're dealing with arrays of pointers and use NULL as the sentinel.
However it's not something to recommend as a general answer. It's error-prone, has a big overhead if you need to know the size, it restricts your ability to access 'sub-arrays' without modifying them and forbids you from using the sentinel as a value and breaks programs that do so by accident.
Other than that it's great.
it is impossible. You need some kind of information about the size; otherwise you will inevitabilly go past its borders...
A pointer doesn't "contain" any information about the size of the array that was allocated; it only points to a place in memory.
EXCEPT
There might be a way around; if you know what is the last element in your array (which MUST always be present then). This is used for example in char arrays (where the last element is \0)
You can't.
But you could do something on the lines of how the C standard library models strings. Given a char*, or a const char*, functions like strlen stop once 0 is reached (known as the null terminator).
So (i) either reserve an int value which acts as your terminator, or (ii) pass the length.
Either way, pass a const int* if you don't intend to modify the contents.

How to find integer array length when array passed to another function from main? [duplicate]

This question already has answers here:
Length of array in function argument
(9 answers)
Closed 9 years ago.
How can I get arrayLength from user defined function?
int getArrayLength(int *arr){
//our logic
return result;
}
Simply: you cannot. You should pass it as another argument:
int getArrayLength(int *arr, int size){ ...
If you try with sizeof, it will return the size of the pointer. You can also use a special value to indicate the last element of your array (like 0 for strings), but adding a convention can make things more complicated.
You'll need to do one of two things:
Have the caller provide the length, or...
Agree on a sentinel value that lets you detect the end of the array.
In the general case, the right answer is option 1. You shouldn't write functions that take C arrays without also taking a length parameter.
In some specific cases, option 2 works pretty well. For example, \0 is used to mark the end of strings, which are just character arrays. If 0 isn't a valid value for the elements of array, that could work for cases other than strings. But generally, go with option 1.
Pass array length to the function too otherwise you can't. This is because sizeof(arr) will give you size of the pointer to int, not the size of entire array.

how test if char array is null?

I've been doing (in C)
char array[100];
if (array == NULL)
something;
which is very wrong (which I have finally learned since my program doesn't work). What is the equivalent where I could test a new array to see if nothing has been put in it yet?
Also, how do you make an array empty/clean it out?
I know there are other posts out on this topic out there, but I couldn't find a straightforward answer.
An array declared with
char array[100]
always has 100 characters in it.
By "cleaning out" you may mean assigning a particular character to each slot, such as the character '\0'. You can do this with a loop, or one of several library calls to clear memory or move memory blocks.
Look at memset -- it can "clear" or "reset" your array nicely.
If you are working with strings, with are special char arrays terminated with a zero, then in order to test for an empty array, see this SO question. Otherwise if you have a regular character array not intended to represent text, write a loop to make sure all entries in the array are your special blank character, whatever you choose it to be.
You can also declare your character array like so:
char* array = malloc(100);
or even
char* array = NULL;
but that is a little different. In this case the array being NULL means "no array has been allocated" which is different from "an array has been allocated but I have not put anything in it yet."

Resources