Having trouble making memset function? - c

void memSet(char destination[], char valueMemSet, int numOfValue)
{
char temp;
int j=1;
for (int i = 0; i <= numOfValue; i++)
{
temp = destination[i];
destination[i] = valueMemSet;
destination[j] = temp;
j++;
}
}
The array is originally "this is the source Concatenate means to link."
This is what I am trying to get "------this is the source Concatenate means to link."
This is What I am currently getting "-------Tthe source Concatenate means to link."
When I ran the debugger it saves the first letter of the array but every single one after gets replaced.
How can I solve this issue?

memset() is a function, which sets a particular value in a given memory, like you want to initialize total array's elements to some particular value(for eg - zero). So it will set the same in that array.
what you need here is strcat() function.

Is that what you need?
void memSet(char destination[], char valueMemSet, int numOfValue, int len)
{
int j=len-numOfValue;
for (int i = len-1;i>=numOfValue;i--) {
destinstion[i] = destination[j--];
}
for (int i = 0; i < numOfValue; i++)
{
destination[i] = valueMemSet;
}
}

Related

Why the for loop is filling the whole array with the latest string?

Apologies if this is simple, but I am new to C. I am trying to create a loop that fills in an empty array of strings with multiple strings. However, at the end, the whole array is being filled with the latest element ! Below is the code:
int main(void)
{
string array_test[2];
char string_test[300];
for (int i = 0; i < 2; i++)
{
snprintf(string_test, sizeof(string_test),"Test: %i", i);
array_test[i] = string_test;
}
for (int i = 0; i < 2; i++)
{
printf("%s\n", array_test[i]);
}
}
This returns:
Test: 1
Test: 1
But I am expecting:
Test: 0
Test: 1
Because you are using the same buffer to save strings in all iterations. This will make previous strings overwritten by new strings.
Allocate separate buffers for each strings to avoid this.
/* put #include of required headers here */
int main(void)
{
string array_test[2];
char string_test[2][300];
for (int i = 0; i < 2; i++)
{
snprintf(string_test[i], sizeof(string_test[i]),"Test: %i", i);
array_test[i] = string_test[i];
}
for (int i = 0; i < 2; i++)
{
printf("%s\n", array_test[i]);
}
}
Why the for loop is filling the whole array with the latest string?
The for loop is filling the whole array of pointers array_test with the address of the first character of the character array string_test.
That is you declared an array of two pointers
string array_test[2];
and each element of the array points to the first character of the same array string_test
array_test[i] = string_test;
The statement above is equivalent to the following statement
array_test[i] = &string_test[0];
That is an array designator used in expressions with rare exceptions is converted to a pointer to its first element.
So you are outputting the same character array string_test using two pointers.
printf("%s\n", array_test[i]);
Instead of the array of pointers you could declare a two-dimensional character array like
char array_test[2][300];
and in the first for loop you could copy strings formed in the array string_test into elements of the array array_test like
strcpy( array_test[i], string_test );
In this case each element of the two-dimensional array will store its own string.
All elements in the string array point to the same buffer, so they all appear to have the same string, more precisely the value last composed into this buffer.
Using the typedef string for char * creates confusion about this fact, which is one more reason to not hide pointers behind typedefs.
You can allocate a copy of the string in the loop:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char *array_test[2];
char string_test[300];
for (int i = 0; i < 2; i++) {
snprintf(string_test, sizeof(string_test), "Test: %i", i);
array_test[i] = strdup(string_test);
}
for (int i = 0; i < 2; i++) {
printf("%s\n", array_test[i]);
}
for (int i = 0; i < 2; i++) {
free(array_test[i]);
}
return 0;
}

How to "delete" every element in array by value in C

I have been trying to solve this problem for about 5 days..can't find any solution please send help. I am supposed to implement a function to "delete" every element in an array by value. Let's say my array is "Hello" and I want to delete every "l". So far I can only delete l once. By the way keep in mind I am not allowed to use pointers for this function...(we haven't learned that yet in my school) Here's my code:
#include <stdio.h>
#include <string.h>
void strdel(char array[], char c);
int main(void)
{
char source[40];
printf("\nStrdel test: ");
strcpy(source, "Hello");
printf("\nsource = %s", source);
strdel(source, 'l');
printf("\nStrdel: new source = %s", source);
return 0;
}
void strdel(char array[], char c)
{
int string_lenght;
int i;
for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {}
for (i = 0; i < string_lenght; i++) {
if (array[i] == c) {
for (i = i; array[i] != '\0'; ++i)
array[i] = array[i + 1];
}
}
}
Simple use 2 indexes, one for reading and one for writing. #Carl Norum
void strdel(char array[], char c) {
int read_index = 0;
int write_index = 0;
while (array[read_index] != '\0') {
if (array[read_index] != c) {
array[write_index] = array[read_index];
write_index++; // Only advance write_index when a character is copied
}
read_index++; // Always advance read_index
}
array[write_index] = '\0';
}
The has O(n) performance, much faster than using nested for() loops which is O(n*n).
Details:
OP: By the way keep in mind I am not allowed to use pointers for this function.
Note that array in void strdel(char array[], char c) is a pointer, even though it might look like an array.
int for array indexing is OK for learner and much code, yet better to use size_t. int may lack the range needed. Type size_t is an unsigned type that is neither too narrow nor too wide for array indexing needs. This becomes important for very long strings.
Your problem is related to using the variable i in both loops. So once the inner loop is executed, outer loop will terminate right after.
Use another variable for the inner loop.
void strdel(char array[], char c)
{
int string_lenght;
int i, j;
for (string_lenght = 0; array[string_lenght] != '\0'; string_lenght++) {}
for (i = 0; i < string_lenght; i++) {
if (array[i] == c) {
for (j = i; array[j] != '\0'; ++j) // Use variable j instead of i
array[j] = array[j + 1];
--i; // Decrement i to "stay" at the same index
--string_lenght; // As one character were just removed
}
}
}
The above shows how to make OPs approach work. For a better solution see the answer from #chux : https://stackoverflow.com/a/53487767/4386427

Remove some elements from array and re-size array in C

Regards
I want to remove some elements from my array and re-size it.
for example my array is:
char get_res[6] = {0x32,0x32,0x34,0x16,0x00,0x00};
Now I want to remove elements after 0x16, so my desire array is:
get_res[] = {0x32,0x32,0x34,0x16};
what is solution?
You cannot resize arrays in C (unlike Python, for example). For real resizing, at least from an API user's point of view, use malloc, calloc, realloc, and free (realloc specifically).
Anyway, "resizing" an array can be imitated using
a delimiter; for example, a delimiter like 0xff could mark the end of the valid data in the array
Example:
#define DELIMITER 0xff
print_data(char* data) {
for (size_t i = 0; data[i] != DELIMITER; ++i)
printf("%x", data[i]);
}
a member counter; count the number of valid data from the beginning of the array onward
Example:
size_t counter = 5;
print_data(char* data) {
for (size_t i = 0; i < counter; ++i)
printf("%x", data[i]);
}
Notes:
Use unsigned char for binary data. char may be aliasing signed char, which you might run into problems with because signed char contains a sign bit.
There is no need to "remove" them. Just don't access them. Pretend like they don't exist. Same like in stacks, when you "pop" a value from the top of the stack, you just decrement the stack pointer.
Manipulating arrays in C isn't easy as it is for vector in C++ or List in Java. There is no "remove element" in C. I mean that you have to do the job yourself, that is, create another array, copy only the elements you want to this new array, and free the memory occupied by the previous one.
Can you do that? Do you want the code?
EDIT:
Try that. It's just a simple program that simulates the situation. Now, you have to see the example and adapt it to your code.
#include <stdio.h>
#include <stdlib.h>
int main() {
char get_res[6] = {0x32,0x32,0x34,0x16,0x00,0x00};
char target = 0x16;
int pos, i, length = 6; // or specify some way to get this number
for(i = 0; i < length; i++)
if(get_res[i] == target) {
pos = i;
break;
}
pos = pos + 1; // as you have to ignore the target itself
char *new_arr = malloc(pos);
for(i = 0; i < length; i++) {
new_arr[i] = get_res[i];
i++;
}
for(i = 0; i < pos; i++)
printf("%c ", new_arr[i]);
return 0;
}

How to find an element in an array of structs in C?

I have to write a function that finds a product with given code from the given array. If product is found, a pointer to the corresponding array element is returned.
My main problem is that the given code should first be truncated to seven characters and only after that compared with array elements.
Would greatly appreciate your help.
struct product *find_product(struct product_array *pa, const char *code)
{
char *temp;
int i = 0;
while (*code) {
temp[i] = (*code);
code++;
i++;
if (i == 7)
break;
}
temp[i] = '\0';
for (int j = 0; j < pa->count; j++)
if (pa->arr[j].code == temp[i])
return &(pa->arr[j]);
}
Why don't you just use strncmp in a loop?
struct product *find_product(struct product_array *pa, const char *code)
{
for (size_t i = 0; i < pa->count; ++i)
{
if (strncmp(pa->arr[i].code, code, 7) == 0)
return &pa->arr[i];
}
return 0;
}
temp is a pointer which is uninitialized and you are dereferencing it which will lead to undefined behavior.
temp = malloc(size); // Allocate some memory size = 8 in your case
One more mistake I see is
if (pa->arr[j].code == temp[i]) // i is already indexing `\0`
should be
strcmp(pa->arr[j].code,temp); // returns 0 if both the strings are same
This code can completely be avoided if you can use strncmp()
As pointed out by others, you are using temp uninitialized and you are always comparing characters with '\0'.
You don't need a temp variable:
int strncmp ( const char * str1, const char * str2, size_t num );
Compare characters of two strings
Compares up to num characters of the
C string str1 to those of the C string str2.
/* Don't use magic numbers like 7 in the body of function */
#define PRODUCT_CODE_LEN 7
struct product *find_product(struct product_array *pa, const char *code)
{
for (int i = 0; i < pa->count; i++) {
if (strncmp(pa->arr[i].code, code, PRODUCT_CODE_LEN) == 0)
return &(pa->arr[i]);
}
return NULL; /* Not found */
}
When you write char* temp; you are just declaring an uninitialized pointer
In your case since you say that the code is truncated to 7 you could create a buffer
on the stack with place for the code
char temp[8];
Writing
temp[i] = (*code);
code++;
i++;
Can be simplified to:
temp[i++] = *code++;
In your loop
for (int j = 0; j < pa->count; j++)
if (pa->arr[j].code == temp[i])
return &(pa->arr[j]);
You are comparing the address of code and the character value of temp[i] which incidentally could be 8 and outside the array.
Instead what you want to do is compare what code points to and what temp contains:
for (int j = 0; j < pa->count; j++)
if (!strncmp(pa->arr[j].code, temp, 7)
return &(pa->arr[j]);
You should also return NULL; if nothing was found, seems you do not return anything.
Probably a good thing is also to make sure your temp[] always contains 7 characters.

Arduino - Optimising existing method for iterating through an array

Is there a more efficient and cleaner way of doing what the following method is already doing?
void sendCode(prog_uint16_t inArray[], int nLimit) {
unsigned int arr[nLimit];
unsigned int c;
int index = 0;
while ((c = pgm_read_word(inArray++))) {
arr[index] = c;
index++;
}
for (int i = 0; i < nLimit; i=i+2) {
delayMicroseconds(arr[i]);
pulseIR(arr[i+1]);
}
}
This is in reference to an existing question I had answered.
Arduino - Iterate through C array efficiently
There should be no need for the local arr array variable. If you do away with that you should both save temporary stack space and speed up execution by removing the need to copy data.
void sendCode(const prog_uint16_t inArray[]) {
unsigned int c;
for (int i = 0; c = pgm_read_word(inArray++); i++) {
if (i % 2 == 0) { // Even array elements are delays
delayMicroseconds(c);
} else { // Odd array elements are pulse lengths
pulseIR(c);
}
}
}
This code assumes that the maximum integer stored in an int is greater than the maximum size of inArray (this seems reasonable as the original code essentially makes the same assumption by using an int for nLimit).

Resources