How to write a C function that removes part of a string?

I want to write a C function that removes part of a string for a given range of indices.

For example, if the input line is "ABCDEFGHIJK" and the start index is 2 and the end index is 5, then the output should be: "ABGHIJK".

I am trying to do this using two functions, one function that gets the substring we want to remove:

void get_substring(char string[], char substring[], int start, int end) { strncpy(substring, string + start, end - start + 1); } 

and then a second function that removes this substring:

 void remove_portion(char string[], char substring[]) { // memmove? } 

Another possibility that I was thinking about is to directly modify the original string without using a substring:

 void remove_portion(char string[], int start, int end) { // if end is less then the length of the string, then // copy everything after string[end] into a temp string // Then replace string[start] with '\0' and then concatenate // string and temp. // If end is greater than the length of string then just replace // string[start] with '\0'. } 

Is this the right approach? Are there any built-in functions from string.h that may be useful here?

+5
source share
4 answers

I would use memmove, as in the second approach:

 void remove_portion(char string[], int start, int end) { if (start>=0 && end>=start && start<strlen(string) && end<strlen(string)) { // some more sanity checking (EDIT added later) memmove(string+start, string+end+1, strlen(string)-(end+1)+1); // final +1 to copy string terminator } } 

Also note that in your first example (using strncpy) it is not going to copy the final line terminator \ 0 to the substring. Therefore you need to add

 substring[end - start + 1]= '\0'; 

.

+5
source

New to C itself, but it worked for me:

 void remove_portion(char str[], int start, int end) { assert((end > start) && (strlen(str) > end)); char out[strlen(str) - (end - start)]; int i, j = 0; for (i = 0; str[i] != '\0'; i++) { if ((i < start) || (i > end)) out[j++] = str[i]; } out[j] = '\0'; strcpy(str, out); } 
+1
source

Use this:

 void remove_portion( char * str, int start, int end){ char* stro = calloc(strlen(str - (end-start+1)), sizeof(char)); strncpy(stro,str,start); strcat(stro,&str[end]); strcpy(str,stro); } 

Add conditions as well.

+1
source

I was told that using strcpy() for this is wrong because "copying that occurs between overlapping objects" is undefined in the standard (ISO / IEC 9899: 1999 7.21.2.4).

Here is a version that uses memmove() , with some checks for valid indexes. It changes the indices if the first is greater than the second, and returns NULL if the indices are outside the bounds:

 char * remove_portion(char *str, int start, int end) { int str_len = strlen(str); int temp; if (start > end) { temp = start; start = end; end = temp; } if (end > (str_len - 1) || start < 0 || end < 0) { str = NULL; } else { int ncopy = str_len - end; memmove(&str[start], &str[end+1], ncopy); } return str; } 

Of memmove() standard says: "Copying occurs as if n characters from the object pointed to by s2 are first copied to a temporary array of n characters that do not overlap the objects pointed to by s1 and s2, and then n characters from the temporary array are copied to the object pointed to by s1. " (ISO / IEC 9899: 1999 7.21.2.2)

So memmove() specifically designed to handle situations such as copying part of an array into itself.

0
source

Source: https://habr.com/ru/post/1257780/


All Articles