Using a global variable like:
params_vector[100][100] = {};
Is it possible to 'reset' or 'clear' the values inside this array just to be equal as from when it's initialized? There are a lot of examples with char *arg[] (which arg[i] = NULL works) but none with a 'matrix' like this.
If this is a multidimensional array of char, you can "reset" it simply by calling
#include <string.h>
memset(params_vector, 0, sizeof params_vector);
If you just need to set the first byte of each string to 0, using a for loop could be more efficient.
Assuming this is a multidimensional array of char's, e.g.
char params_vector[N][M];
for some value of N and M - you don't need to memset() the entire thing to '\0'; it's enough to set the first character of each string to '\0':
for(size_t i = 0; i < N; i++) {
params_vector[i][0] = '\0';
}
However, if N is small, this optimization might not be worth it and a
memset(params_vector, '\0', M * N);
would be fine.
Use memset:
memset(params_vector, 0, sizeof(params_vector));
Related
I am a beginner to C and I was asked to calculate size of an array without using sizeof operator. So I tried out this code, but it only works for odd number of elements. Do all arrays end with NULL just like string.
#include <stdio.h>
void main()
{
int a[] = {1,2,3,4,5,6,7,8,9};
int size = 0;
for (int i = 0; a[i] != '\0'; i++)
{
size++;
}
printf("size=%d\n", size);
}
No, in general, there is no default sentinel character for arrays.
As a special case, the arrays which ends with a null terminator (ASCII value 0), is called a string. However, that's a special case, and not the standard.
> So I tried out this code, but it only works for odd number of elements.
Try your code with this array -
int a[] = {1,2,0,4,5,6,7,8,9};
^
|
3 replaced with 0
and you will find the output will be size=2, why?
Because of the for loop condition - a[i] != '\0'.
So, what's happening when for loop condition hit - a[i] != '\0'?
This '\0' is integer character constant and its type is int. It is same as 0. When a[i] is 0, the condition becomes false and loop exits.
In your program, none of the element of array a has value 0 and for loop keep on iterating as the condition results in true for every element of array and your program end up accessing array beyond its size and this lead to undefined behaviour.
> Do all arrays end with NULL just like string.
The answer is NO. In C language, neither array nor string end with NULL, rather, strings are actually one-dimensional array of characters terminated by and including the first null character '\0'.
To calculate size of array without using sizeof, what you need is total number of bytes consumed by array and size (in bytes) of type of elements of array. Once you have this information, you can simply divide the total number of bytes by size of an element of array.
#include <stdio.h>
#include <stddef.h>
int main (void) {
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ptrdiff_t size = ((char *)(&a + 1) - (char *)&a) / ((char *)(a + 1) - (char *)a);
printf("size = %td\n", size);
return 0;
}
Output:
# ./a.out
size = 9
Additional:
'\0' and NULL are not same.
I declared a table of unsigned char as follow:
unsigned char buf[10]={'1','5',0x00,'8'};
in order to know the number of elements of this table i implemented this function
int tablength(unsigned char *buf)
{
int i=0;
for (i=0;buf[i];i++)
;
return i;
}
However this function don't give me the right result when the buffer contains 0 in the middle .Sizeof don't give me the right result since it returns 10 in this case i can't neither use strlen since this is a table of unsigned char.
Do you have any idea to improve this function or any predefined function that help me solve my problem (the result that i 'am waiting for is 4)
Technically, since you declared a statically allocated array of 10 elements, the size of the array is 10. Even though you may not have initialized every element, there is something filling that space. C++ cannot determine whether the value in the array means anything or not.
After
unsigned char x[10] = {1, 2, 3};
the variable x (an array) has 10 elements, the first three initialized to 1, 2 and 3 and all the others initialized to 0. In other words that definition is absolutely identical to
unsigned char x[10] = {1, 2, 3, 0, 0, 0, 0, 0, 0, 0};
An array in C and C++ is just a fixed area of memory and doesn't include a counter of how many "interesting" elements are there.
If you are looking for a container with a variable number of elements consider instead std::vector (C++ only). With that std::vector::size() returns the current number of elements in the container.
If you need the array to contain exactly the number of elements you've specified, just declare it without a specific size:
unsigned char buf[]={'1','5',0x00,'8'};
cout << sizeof(buf); // should be 4
If you want to store a variable amount of data (in C++) use std::vector instead of an array.
Otherwise you'll need to keep track of the number of valid elements yourself. There's nothing in the language that will do it for you.
Compilers cannot know how you would like to use an array instance.
Therefore you must follow the language's semantics. By declaring your array globally or locally, but with the storage class specifier static you are initializing every element to 0 on default and your function will work.
0x00 is false. 0x00 (which same as 0x0) is a hex number representing 0 (false). This is where your counting loop will stop at - the 3rd element.
Another thing you can do is declare your array with non-fixed size.
unsigned char buf[]={'1','5',0x00,'8'};
In that case, the sizeof operator works as expected.
Because that way, you will have an array of 4 elements.
strlen() obviously won't work as it is designed to work with strings, not a buffer.
As for a function that counts on a smarter way:
size_t arrcnt (unsigned char source[], size_t size)
{
size_t i;
for(i = size; i >= 0 && !source[i]; i--);
return i + 1;
}
Usage:
printf("size of buf: %u", arrcnt(buf, sizeof(buf));
buf[i] evaluates to false when buf[i] contains 0.
You cannot do what you want unless you know one value which can never occur in your array between 0 to UCHAR_MAX (255). Say the value is 255, then you first preinitialize the full array to 255 before you start filling it up.
memset(buf, 255, sizeof(char) * sizeof(buf));
Then you fill other elements like you want and then you can use the following
for(i = 0; buf[i] != 255, ++i)
try putting :
for(int i=0;buf[i]!= 0;i++)
count++;
return count;
I have a char array LL,4014.84954 that I send into a function like this example:
#include <stdio.h>
#include <math.h>
void myFunction(char* in_string, char* out_string) {
printf("Start_String=%s\n", in_string);
int in_size = (int)(sizeof(in_string));
printf("%d\n", in_size);
int i = 0;
for(i = 0; i <= in_size-ceil(in_size/2); i++) {
out_string[i] = in_string[i];
}
}
int main(int arg) {
char in_string[] = "LL,4014.84954";
char out_string[] = "";
printf("In_String=%s\n", in_string);
myFunction(in_string, out_string);
printf("Out_String=%s\n", out_string);
}
My question has two parts.
How do I get the length of this char array? int in_size = (int)(sizeof(in_string)); in this example gives me 8 which is the size of the pointer (long int). I know I could make a for loop that marches through until it see the null termination, but is there a nicer way? I previously was using char[] and sizeof works great, but now I am converting to char*.
How can I write a portion of these chars to out_string. My example currently writes all chars to out_string.
Here is the raw output:
In_String=LL,4014.84954
Start_String=LL,4014.84954
8
Out_String=LL,40014.84954
(1)
Answer to question 2:
char out_string[] = "";
out_string[] is of only one size. you assigning out_string[i] = ... for i > 0 is wrong and cause an undefined error. Instead of this you should declare out_string[] like this:
out_string[] = malloc(strlen(in_string) + 1);
// ^ extra for \0 char
(2)
additionally #WhozCraig commenting correct, you actually need strlen() to find length of string. sizeof you are using wrong.
So replace:
int in_size = (int)(sizeof(in_string));
by
int in_size = strlen(in_string);
(3)
Also, what is in_size-ceil. As I can understands from your raw output you don't need such kind of function and calculations. Just replace your for loop:
for(i = 0; i <= in_size-ceil(in_size/2); i++)
by
for(i = 0; i < in_size; i++)
(4)
At the end don;t forget to terminate you string out_string, after for loop add this line
out_string[i] = '\0'
Regarding your first question, use strlen().
Regarding the second question, first of all you need to make sure that out_string is wide enough to accommodate the result. Currently, it isn't, and the behaviour of your code is undefined. Once you fix that, to copy a portion of the string you'd need to change the initial and final conditions of the for loop, not forgetting about the NUL terminator.
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.
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]);
}
}