Counting the number of elements in an array - C - c

I am trying to count the number of elements in an array using C. I tried out the following code. But it just returns 83 every time I run the program. What I mean by to count the number of elements is that I need to know the number of elements that we have entered and not the size of the array.
#include<stdio.h>
#include<stdlib.h>
main(){
int a[100], j = 0, i;
a[0] = '0';
a[1] = '1';
a[2] = '2';
a[3] = '3';
a[4] = '4';
a[5] = '5';
for(i=0; i<100; i++){
if(a[i] == '\0'){
}
else
j = j + 1;
}
printf("%d", j);
system("pause");
}

Arrays in C are a fixed size. They do not expand. Your array has two entries; writing to array[2], array[3], etc. invokes undefined behaviour. In other words, it's invalid code.
If you want to be able to insert an arbitrary number of elements, you will need to use dynamically-allocated memory, manually track how many elements you've inserted, and use realloc when you need to resize.

Since the OP amended his code, here is a more correct reply:
This code works 'by chance', since you didn't initialize the array previously.
It's just 'luck', that somewhere in there, the value 0 comes up.
The declaration of an array does NOT zero it.
Use:
memset(a, 0, 100);
For that. That way, the first 'not overwritten' byte will return '0'.
Reference: http://www.cplusplus.com/reference/clibrary/cstring/memset/
Alternatively, you have to set the 'delimited' manually by adding a[x] = 0;
Now, I know you specifically asked for a 'C' solution, but if you would like to consider using a C++-Compiler, I suggest looking at the stl of C++.
Here's a link to get you started: http://www.cplusplus.com/reference/stl/list/
It's initialized as:
list<char>List;
List.push_back(1);
List.push_back(2);
List.push_back('a');
int j = List.size(); //Returns '3'

do this instead:
main(){
int a[100] = {0};
int j = 0;
int i = 0;
// other stuff

Update based on new code:
In general, you will need a way to identify the end of your array in order to do a correct count. For strings the '\0' is used generally. For other data types you have to come up with your own value to check.
For your specific code example above:
You need to insert a \0 yourself into your array in the last position so that your count will work. (When you create a string like "hello", the '\0' gets automatically put in for you at the end of the string, but not if you create a string character by character).
Alternatively, check for the character '5' to find the end of your current array of characters.
Also, you should break out of the loop once you found the last character, otherwise you are going past the end of the array and will most likely crash (again, if you don't it's sheer luck). I.e., something like:
if(a[i] == '\0'){
break;
}
will work if you do:
a[6] = '\0';
before.
Since C doesn't check array bounds, it might appear that with your current code you seemingly get away with this, but it's sheer luck that the program doesn't crash and may change from run to run. In other words, this is undefined behavior.
Finally, you can of course also use strlen() if you are dealing with strings.

Related

Why is my for loop increasing the size of my array in C?

I'm trying to make a binary number calculator in c and I'm running into issues of my for loops doubling the size of my second array and adding the first array onto the end. I'm really confused because I thought you couldn't increase the size after already declaring it. It is happening in my equation reading function as well but in this ones complement function it's a bit simpler to see. Any ideas of how to fix this?the codethe output
welcome to stack-overflow. From next time please use inline code editor to put your code instead of images. I have taken effort put your code in the answer itself to explain the problem. Please consider this as courtesy. Its very unusual to do it. But as you are a new member, I'm doing it.
// Cole carson's original code from image:
char * onescomp(char x[16], char y[16]){
int i;
for(i=0;i<=15;i++){
if(x[i] == '0'){
y[i] = '1';
continue;
}
else if(x[i] == '1'){
y[i] = '0';
continue;
}
}
return y;
}
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[16];
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}
Answer:
You don't need continue; in if-else blocks.
You need to add '\0' in the last cell of cb3n array. so puts() knows when string ends & stop printing.
so to quickly fix this issue you can create array with extra cell and assign all values as '\0'. so after copying fifteen 1's there will be '\0' in the end. I think in your case those extra zeros being printed might be garbage values. It looks like array is doubling but it isn't, its just printing values beyond allocated memory because '\0' has not been provided.
//Quick fix
int main()
{
char b3n[16]={'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char cb3n[17]={'\0'}; // <--- quick fix
puts(b3n);
onescomp(b3n,cb3n);
puts(cb3n);
return 0;
}

How do I find the number of element of an array which have their size previously undefined

I'm trying to make an array which have it's element coming from a user input. This array would first have it's size undefined since we don't know how much int would the user input, but then I'm not able to find the amount of element in the array like this unless I put a counter on the loop function.
Here is the code that I've made:
int cross[] = {0};
int k;
for (k = 0; k >= 0; k++){
scanf("%d", &cross[k]);
if (cross[k] == -1){
break; //stop the user from inputing numbers if user input -1
}
int p = sizeof(cross) / sizeof(cross[0]);
If I were to do printf("%d", p), it would always give me 1 as a result. I'm wondering if there is any other way of doing this other than putting a counter on the for loop.
Thanks!!
This phrase from your question is both wrong and dangerous: "This array would first have it's size undefined".
The following line of code defines a fixed-size array that has exactly one element:
int cross[] = {0};
The compiler knows it's one element because you supplied one initializer value {0}. If you supplied this {0, 5, 2}, it would allocate 3 integers, and so on.
This means when you store into cross[k] and k is larger than zero, you're actually exceeding the bounds of your allocated array, which C doesn't catch at compile time, but could cause nasty problems at run time.

Creating multiple random strings in C

I have written a code which creates multiple random strings. But every time I print it, only the last string is printed multiple times even though different strings are created every time. Can anyone tell me what I'm doing wrong.
static const char alphanum[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz";
char s[5],*b[5] ;
int num =0;
for(int j=0;j<5;j++)
{
*b=(char*)malloc(sizeof(char*)*10);
for (int i = 0; i < 4; ++i)
{
num = rand() % (sizeof(alphanum) - 1);
s[i] = alphanum[num];
}
s[4] = 0;
printf("%s\t",s);
b[j] = s;
}
for(int j=0;j<5;j++)
printf("\n%s",b[j]);
}
Assuming that you've seeded the random number generator with, for instance, srand(time(NULL));, so that it will generate different random number sequences on each run of the program, there is one more flaw in your code:
s is a pointer to an array of characters. With the assignment b[j] = s;, you only assign b[j] the pointer (memory location) of s, but not the contents of s. Since the memory location of s does not change, all entries of b contain the same reference to the same string s, which has been changed multiple times. To copy the current content of s to b[j], use strcpy(), like this.
strcpy(b[j], s);
I think your should read the man 3 rand
In facts you have to "seed" your rand by calling void srand(unsigned int seed); one time in the beggining of your application
First of all, doing e.g. *b is the same as *(b + 0) which is the same as b[0]. That means that when you allocate memory you assign it to the same entry all the time.
Secondly, last in the loop you overwrite the pointer and make b[j] point to s, all the time. So all pointers in b will point to the same s. That's why all your strings seems to be the same.
Thirdly, you don't need to allocate dynamically in the loop, as all strings are of a fixed size. Instead declare b as an array of arrays of characters:
char b[5][5];
Then instead of assigning the pointer, you copy the string into the correct entry in b.
Lastly, and for future reference, don't cast the return of malloc.

accessing array of strings in C

How to declare array of strings in C.
Is it like
char str[100][100] ={"this","that","those"};
If so how to access the values .. can i travers like this?
(It does not give any compilation error ..but shows some additional garbage characters)
int i ,j;
char c[100][100] = {"this","that"};
for(i = 0 ;c[i] != '\0';++i)
for(j = 0; c[i][j] != '\0';++j)
printf("%c",c[i][j]);
Is it necessary to add '\0' at end of eac string..for ex:
char c[100][100]={"this\0","that\0"}
How to declare array of strings in C
It is Ok, but you will have to be extremely careful of buffer-overflow when dealing with these strings
can i travers like this?
Note that the condition in the first for loop: for(i = 0 ;c[i] != '\0';++i) is probably wrong, and will fail since c[i] is an array, whose address is not 0. You should probably iterate the outer array by numbers [until you read all elements], and not until you find some specific character. You can do that by maintaining a different variable n, which will indicate how many elements does the array currently have.
Is it necessary to add '\0' at end of eac string..for ex:
No - the compiler add it to you, it is just fine without adding the '\0' to the string.
Yes, you can declare an array of strings that way.
No, you can't traverse it like that, the condition on your outer loop is bad - a string (char *) will never be equal to a character '\0'. The inner loop is fine.
No, you don't need to add the '\0', that will happen automatically.
c[i] is a pointer, so it has nothing to do with '\0'
so instead you should check c[i][0]
The compiler will add '\0' for you when you input a string like "this"
char str[100][100] ={"this","that","those"};
int main()
{
int i ,j;
char c[100][100] = {"this","that"};
for(i = 0 ;c[i][0] != '\0';++i)
{
for(j = 0; c[i][j] != '\0';++j)
printf("%c",c[i][j]);
}
}

C ints and chars. Strange behavior

I am learning C language and I am facing a problem I don't seem to be able to resolve on my own.
I have a simple loop where I add up ascii values of all characters in each word.
char char_array[100];
int lexicographical_values[20];
int i, j = 0;
for( i = 0; i <strlen(char_array); i++) {
if(char_array[i] == ' ')
j++;
lexicographical_values[j] += (int)char_array[i];
}
Then, if I output the lexicographical_values array in a loop
printf("%d word is: %d \n", i, lexicographical_values[i]);
I get correct figures for each word (ex: dd = 200 and so on)
But if I actually look at each element's value in the array, I get big numbers that are far from being correct.
The question is, how do I get correct values and how does printf obtain the correct values?
Thanks
You have not initialized the lexicographical_values array. You can initialize it by doing:
int lexicographical_values[20] = {};
Every time you see big numbers in the output, check for uninitialized variables.
You're starting with uninitialized memory.
man memset
You have not initialized the char_array with anything, so most likely it has garbage (depends on compiler options and platforms) so, you do a strlen(char_array) and at this point we're not sure what we're going to get out of it. If you initialize it with 0s (like: char char_array[100] = {0}; then strlen will return 0 and you'll never enter the loop.
Maybe you're looking for sizeof() here?
Oh, yes, forgot to mention that you need to initialize the second array also as was already pointed out.

Resources