-2

I have an array and I need to replace a subarray from this array with a character.

unsigned char * data = {'a','b','c','d','e'};

I need to delete 'a','b''c' and insert 'R' The final array will be: unsigned char * data = {'R','d','e'}; With only 3 elements. How can I do that in C?

Dariel Nunez
  • 45
  • 1
  • 8
  • Loop through the elements, compare, and modify as needed. – dbush Jan 24 '17 at 22:03
  • 1
    `data[0] = 'R'; data[1] = 'R'; data[2] = 'R';` – George Jan 24 '17 at 22:03
  • Then his string will be "RRRde", he apparently wants it to become "Rde" (an edit after you wrote this?) Maybe http://stackoverflow.com/questions/779875/what-is-the-function-to-replace-string-in-c is relevant for this? – Freek Wiedijk Jan 24 '17 at 22:12
  • 2
    `data = (unsigned char[]){'R','d','e'};` – BLUEPIXY Jan 24 '17 at 22:13
  • 1
    Is not `{'a','b','c','d','e'};` potentially in `const` memory? Is it valid portable syntax? Use [@BLUEPIXY](http://stackoverflow.com/questions/41839756/replace-a-subarray-with-a-character-in-c#comment70865056_41839756) compound literal instead. – chux - Reinstate Monica Jan 24 '17 at 22:14
  • @FreekWiedijk OP's `data` and 3 element final array are not _strings_. No null character – chux - Reinstate Monica Jan 24 '17 at 22:42
  • @chux: yes, of course. That's why I used `fwrite` in my answer. But because he put letters there, I guessed he maybe *did* want strings. I also saw that you had an answer too, that you deleted. Did I get in your way? If so, my apologies! – Freek Wiedijk Jan 24 '17 at 22:44
  • No not in my way - I find OP's post unclear on `delete 'a','b''c' ` and `sub-array` on 2nd read. What if data was `"a1b2c3de"` that apparently has 3 sub-arrays, but does OP only want one deleted or 3. IMO, the premise is too open to interpretation. Good luck. – chux - Reinstate Monica Jan 24 '17 at 22:48

3 Answers3

1
for(int i = 0; i < 5; i++){
    if (data[i] > 96 && data[i] < 100)  data[i] = 'R';
}
Alex
  • 779
  • 7
  • 15
  • 2
    wouldn't `(data[i] >= 'a' && data[i] <= 'c')` be better than using magic numbers? (ascii's common but shouldn't be assumed and the op might not be using it). – George Jan 24 '17 at 22:17
  • 1
    @George True that `'a'` is better than `96`, still code is making the _reasonable_, though not specified, assumption about the sequence of letters. – chux - Reinstate Monica Jan 24 '17 at 22:23
1

You say you think of data as an array, therefore it is better that you declare data as an array instead of a pointer. (The way your code is now you have a pointer that is initialized incorrectly by casting the character 'a' to a char * pointer. That way it will not be pointing anywhere.)

You can replace characters by assigning to elements of the array, and you can shift parts of the data in the array using memmove.

Which means that maybe you want something like this:

unsigned char data[] = {'a','b','c','d','e'};
data[0] = 'R';
memmove(data + 1, data + 3, sizeof(data) - 3);

The memmove call moves sizeof(data) - 3 bytes of data from address data + 3 to address data + 1. The function memmove even works when the regions of memory between which you are moving bytes of data overlap.

If you then print the relevant part of your data:

fwrite(data, 1, sizeof(data) - 2, stdout);
putchar('\n');

This will get you the output:

Rde

However, notice that the size of the array will not have changed. It still will be five characters long. So replacing abc by something longer than three characters will not work like this. Also, this array is not a null-terminated string, which is the more usual way to have sequences of characters in C.

If you prefer to use a string "abcde" instead of what you are doing now (but then why call it "data"?), add a comment below this answer, and I'll extend it.

Freek Wiedijk
  • 481
  • 1
  • 3
  • 15
1

How about the following way?

unsigned char * data = {'a','b','c','d','e'};

int length = strlen(data);

unsigned char * output = (unsigned char *)malloc(sizeof(unsigned char)*length);

for(int i = 0, j =0; i < length; i++, j++){
    if (i+2 < length && data[i] == 'a' && data[i+1] == 'b && data[i+2] == 'c') {
       output[j]='R';
       i++;
       i++;
    }
    else
       output[j]=data[i];
}
VHS
  • 9,534
  • 3
  • 19
  • 43