clearing a char array c - c

I thought by setting the first element to a null would clear the entire contents of a char array.
char my_custom_data[40] = "Hello!";
my_custom_data[0] = '\0';
However, this only sets the first element to null.
or
my_custom_data[0] = 0;
rather than use memset, I thought the 2 examples above should clear all the data.

It depends on how you want to view the array. If you are viewing the array as a series of chars, then the only way to clear out the data is to touch every entry. memset is probably the most effective way to achieve this.
On the other hand, if you are choosing to view this as a C/C++ null terminated string, setting the first byte to 0 will effectively clear the string.

An array in C is just a memory location, so indeed, your my_custom_data[0] = '\0'; assignment simply sets the first element to zero and leaves the other elements intact.
If you want to clear all the elements of the array, you'll have to visit each element. That is what memset is for:
memset(&arr[0], 0, sizeof(arr));
This is generally the fastest way to take care of this. If you can use C++, consider std::fill instead:
char *begin = &arr;
char *end = begin + sizeof(arr);
std::fill(begin, end, 0);

Why would you think setting a single element would clear the entire array?
In C, especially, little ever happens without the programmer explicitly programming it. If you set the first element to zero (or any value), then you have done exactly that, and nothing more.
When initializing you can set an array to zero:
char mcd[40] = {0}; /* sets the whole array */
Otherwise, I don't know any technique other than memset, or something similar.

Use:
memset(my_custom_data, 0, sizeof(my_custom_data));
Or:
memset(my_custom_data, 0, strlen(my_custom_data));

Try the following code:
void clean(char *var) {
int i = 0;
while(var[i] != '\0') {
var[i] = '\0';
i++;
}
}

Why not use memset()? That's how to do it.
Setting the first element leaves the rest of the memory untouched, but str functions will treat the data as empty.

Pls find below where I have explained with data in the array after case 1 & case 2.
char sc_ArrData[ 100 ];
strcpy(sc_ArrData,"Hai" );
Case 1:
sc_ArrData[0] = '\0';
Result:
- "sc_ArrData"
[0] 0 ''
[1] 97 'a'
[2] 105 'i'
[3] 0 ''
Case 2:
memset(&sc_ArrData[0], 0, sizeof(sc_ArrData));
Result:
- "sc_ArrData"
[0] 0 ''
[1] 0 ''
[2] 0 ''
[3] 0 ''
Though setting first argument to NULL will do the trick, using memset is advisable

I usually just do like this:
memset(bufferar, '\0', sizeof(bufferar));

Nope. All you are doing is setting the first value to '\0' or 0.
If you are working with null terminated strings, then in the first example, you'll get behavior that mimics what you expect, however the memory is still set.
If you want to clear the memory without using memset, use a for loop.

You should use memset. Setting just the first element won't work, you need to set all elements - if not, how could you set only the first element to 0?

Writing a null character to the first character does just that. If you treat it as a string, code obeying the null termination character will treat it as a null string, but that is not the same as clearing the data. If you want to actually clear the data you'll need to use memset.

I thought by setting the first element
to a null would clear the entire
contents of a char array.
That is not correct as you discovered
However, this only sets the first
element to null.
Exactly!
You need to use memset to clear all the data, it is not sufficient to set one of the entries to null.
However, if setting an element of the array to null means something special (for example when using a null terminating string in) it might be sufficient to set the first element to null. That way any user of the array will understand that it is empty even though the array still includes the old chars in memory

set the first element to NULL. printing the char array will give you nothing back.

How about the following:
bzero(my_custom_data,40);

void clearArray (char *input[]){
*input = ' ';
}

Try the following:
strcpy(my_custom_data,"");

Related

What is the default value of an element of an uninitialized character array?

here's a code I wrote
int main(){
char arr[50][*];
arr[0][0]=1;
if(arr[0][1]){
printf("%d",arr[0][0]);}
If I am putting 1 as *, there is no output.
but anything greater than 1 in the array size would result in 1 output.that means when I am declaring array size the elements are occupied by some value.
now, my actual need is to write a condition if loop (example)
if(arr[0][1]!='null') // or '0',false,undefined, etc
but I am confused what is there in that empty but declared element, because the above is not working.
There is no default value.
For an object defined inside a function without the static keyword, the initial value is garbage.
You can't test an object to determine whether it's been initialized or not. You have to write your code to avoid reading any object's value before it's been set.
doing(while declaring),
char arr[50][2]={0} //or whatever the size of 2nd dimension other than 2
this will replace all elements(100 in this case) with 0.
So, according to my necessity,I can do
if(arr[0][1] != 0)
for checking if that element is undefined by me.
this example works when your input doesn't contain 0, if it does replcae all elements with something else and also the condition too

What happens if i don't use zero-based array in C

Can someone explain what would happen? Is it really necessary to start at index 0 instead of 1 (which would be easier for me)?
You can do whatever you want, as long as your array subscript is strictly less than the size of the array.
Example:
int a[100];
a[1] = 2; // fine, 1 < 100
What happens if I don't use zero-based array in C
Well, you can't. C arrays are zero based, by definition, by standard.
Is it really necessary to start at 0?
Well, this is no rule to prevent you from leaving index 0 unused, but then, you'll almost certainly not get the desired result.
Using non-zero based arrays in C is possible, but not recommended. Here is how you would allocate a 1-based array of 100 integers:
int * a = ((int*)malloc(100*sizeof(int)))-1;
The -1 moves the start of the pointer back one from the start of the array, making the first valid index 1. So this array will have valid indices from 1 to 100 inclusive.
a[1] = 10; /* Fine */
a[100] = 7; /* Also fine */
a[0] = 5; /* Error */
The reason why this isn't recommended is that everything else in C assumes that pointers to blocks of memory point to the first element of interest, not one before that. For example, the array above won't work with memcpy unless you add 1 to the pointer when passing it in every time.

Find longest suffix of string in given array

Given a string and array of strings find the longest suffix of string in array.
for example
string = google.com.tr
array = tr, nic.tr, gov.nic.tr, org.tr, com.tr
returns com.tr
I have tried to use binary search with specific comparator, but failed.
C-code would be welcome.
Edit:
I should have said that im looking for a solution where i can do as much work as i can in preparation step (when i only have a array of suffixes, and i can sort it in every way possible, build any data-structure around it etc..), and than for given string find its suffix in this array as fast as possible. Also i know that i can build a trie out of this array, and probably this will give me best performance possible, BUT im very lazy and keeping a trie in raw C in huge peace of tangled enterprise code is no fun at all. So some binsearch-like approach will be very welcome.
Assuming constant time addressing of characters within strings this problem is isomorphic to finding the largest prefix.
Let i = 0.
Let S = null
Let c = prefix[i]
Remove strings a from A if a[i] != c and if A. Replace S with a if a.Length == i + 1.
Increment i.
Go to step 3.
Is that what you're looking for?
Example:
prefix = rt.moc.elgoog
array = rt.moc, rt.org, rt.cin.vof, rt.cin, rt
Pass 0: prefix[0] is 'r' and array[j][0] == 'r' for all j so nothing is removed from the array. i + 1 -> 0 + 1 -> 1 is our target length, but none of the strings have a length of 1, so S remains null.
Pass 1: prefix[1] is 't' and array[j][1] == 'r' for all j so nothing is removed from the array. However there is a string that has length 2, so S becomes rt.
Pass 2: prefix[2] is '.' and array[j][2] == '.' for the remaining strings so nothing changes.
Pass 3: prefix[3] is 'm' and array[j][3] != 'm' for rt.org, rt.cin.vof, and rt.cin so those strings are removed.
etc.
Another naïve, pseudo-answer.
Set boolean "found" to false. While "found" is false, iterate over the array comparing the source string to the strings in the array. If there's a match, set "found" to true and break. If there's no match, use something like strchr() to get to the segment of the string following the first period. Iterate over the array again. Continue until there's a match, or until the last segment of the source string has been compared to all the strings in the array and failed to match.
Not very efficient....
Naive, pseudo-answer:
Sort array of suffixes by length (yes, there may be strings of same length, which is a problem with the question you are asking I think)
Iterate over array and see if suffix is in given string
If it is, exit the loop because you are done! If not, continue.
Alternatively, you could skip the sorting and just iterate, assigning the biggestString if the currentString is bigger than the biggestString that has matched.
Edit 0:
Maybe you could improve this by looking at your array before hand and considering "minimal" elements that need to be checked.
For instance, if .com appears in 20 members you could just check .com against the given string to potentially eliminate 20 candidates.
Edit 1:
On second thought, in order to compare elements in the array you will need to use a string comparison. My feeling is that any gain you get out of an attempt at optimizing the list of strings for comparison might be negated by the expense of comparing them before doing so, if that makes sense. Would appreciate if a CS type could correct me here...
If your array of strings is something along the following:
char string[STRINGS][MAX_STRING_LENGTH];
string[0]="google.com.tr";
string[1]="nic.tr";
etc, then you can simply do this:
int x, max = 0;
for (x = 0; x < STRINGS; x++) {
if (strlen(string[x]) > max) {
max = strlen(string[x]);
}
}
x = 0;
while(true) {
if (string[max][x] == ".") {
GOTO out;
}
x++;
}
out:
char output[MAX_STRING_LENGTH];
int y = 0;
while (string[max][x] != NULL) {
output[y++] = string[++x];
}
(The above code may not actually work (errors, etc.), but you should get the general idea.
Why don't you use suffix arrays ? It works when you have large number of suffixes.
Complexity, O(n(logn)^2), there are O(nlogn) versions too.
Implementation in c here. You can also try googling suffix arrays.

Search and erase char array

I am trying to parse through an array for a char and delete everything after that. I did write the code to find the location of the char search in the array. How to delete the remaining part of the array after the identified location. Thank you
You can use memset:
memset(&arr[current_location], 0, sizeof(arr) - current_location);
To set all bytes in arr after current_location contain 0
In C the easiest way to do it is like this:
str[end_idx] = '\0';
This cuts off the string at a particular index because C strings are null terminated.

changing the index of array

so far, i m working on the array with 0th location but m in need to change it from 0 to 1 such that if earlier it started for 0 to n-1 then now it should start form 1 to n. is there any way out to resolve this problem?
C arrays are zero-based and always will be. I strongly suggest sticking with that convention. If you really need to treat the first element as having index 1 instead of 0, you can wrap accesses to that array in a function that does the translation for you.
Why do you need to do this? What problem are you trying to solve?
Array indexing starts at zero in C; you cannot change that.
If you've specific requirements/design scenarios that makes sense to start indexes at one, declare the array to be of length n + 1, and just don't use the zeroth position.
Subtract 1 from the index every time you access the array to achieve "fake 1-based" indexing.
If you want to change the numbering while the program is running, you're asking for something more than just a regular array. If things only ever shift by one position, then allocate (n+1) slots and use a pointer into the array.
enum { array_size = 1000 };
int padded_array[ array_size + 1 ];
int *shiftable_array = padded_array; /* define pointer */
shiftable_array[3] = 5; /* pointer can be used as array */
some_function( shiftable_array );
/* now we want to renumber so element 1 is the new element 0 */
++ shiftable_array; /* accomplished by altering the pointer */
some_function( shiftable_array ); /* function uses new numbering */
If the shift-by-one operation is repeated indefinitely, you might need to implement a circular buffer.
You can't.
Well in fact you can, but you have to tweak a bit. Define an array, and then use a pointer to before the first element. Then you can use indexes 1 to n from this pointer.
int array[12];
int *array_starts_at_one = &array[-1]; // Don't use index 0 on this one
array_starts_at_one[1] = 1;
array_starts_at_one[12] = 12;
But I would advise against doing this.
Some more arguments why arrays are zero based can be found here. Infact its one of the very important and good features of the C programming language. However you can implement a array and start indexing from 1, but that will really take a lot of effort to keep track off.
Say you declare a integer array
int a[10];
for(i=1;i<10;i++)
a[i]=i*i;
You need to access all arrays with the index 1. Ofcourse you need to declare with the size (REQUIRED_SIZE_NORMALLY+1).
You should also note here that you can still access the a[0] element but you have to ignore it from your head and your code to achieve what you want to.
Another problem would be for the person reading your code. He would go nuts trying to figure out why did the numbering start from 1 and was the 0th index used for some hidden purpose which unfortunately he is unaware of.

Resources