I have been running into issues with the strcpy() function in C. In this function I take a string in buffer and the string contains a something along the lines of '(213);'and I am trying to remove the brackets so the output would be something like 200;.
for (i = 0; i < bufferlen; i++) {
// check for '(' followed by a naked number followed by ')'
// remove ')' by shifting the tail end of the expression
// remove '(' by shifting the beginning of the expression
if((buffer[i] == '(') && (isdigit(buffer[i+1]))){
int numberLen = 0;
int test =0;
i++;
while((isdigit(buffer[i]))){
i++;
numberLen++;
}
if(buffer[i] == ')'){
int numberStart = i - numberLen-1;
strcpy(&buffer[i], &buffer[i+1]);
strcpy(&buffer[numberStart], &buffer[numberStart+1]);
printf("buffer = %s\n", buffer);
}
}
}
However, the output is as follows
buffer before strcpy(&buffer[i], &buffer[i+1]); = (213);
buffer after strcpy(&buffer[i], &buffer[i+1]); = (213;
buffer after strcpy(&buffer[numberStart], &buffer[numberStart+1]); = 23;;
for some reason the second strcpy function removes the second value of the string. I have also tried strcpy(&buffer[0], &buffer[1]); and still end up with the same results. Any insight as to why this is occurring would be greatly appreciated.
Continuing from the comment, strcpy(&buffer[i], &buffer[i+1]);
where source
and dest
overlap results in Undefined Behavior , use memmove
, or simply use a couple of pointers instead.
The prohibition on using strings that overlap (ie are the same string) is found in C11 Standard - 7.24.2.3 The strcpy function
If I understand your question and you simply want to turn "'(213)'"
into "213"
, you don't need any of the string.h
functions at all. You can simply use a couple of pointers and walk down the source-string until you find a digit. Start copying digits to dest
at that point by simple assignment. When the first non-digit is encountered, break
your copy loop. Keeping a flag to indicate when you are " in
" a number copying digits will allow you to break on the 1st non-digit to limit your copy to the first sequence of digits found (eg so from the string "'(213)' (423)"
, only 213
is returned instead of 213423
). You could do somehting like:
char *extractdigits (char *dest, const char *src)
{
/* you can check src != NULL here */
char *p = dest; /* pointer to dest (to preserve dest for return) */
int in = 0; /* simple flag to break loop when non-digit found */
while (*src) { /* loop over each char in src */
if (isdigit(*src)) { /* if it is a digit */
*p++ = *src; /* copy to dest */
in = 1; /* set in-number flag */
}
else if (in) /* if in-number, break on non-digit */
break;
src++; /* increment src pointer */
}
*p = 0; /* nul-terminate dest */
return dest; /* return pointer to dest (for convenience) */
}
A short example would be:
#include <stdio.h>
#include <ctype.h>
#define MAXC 32
char *extractdigits (char *dest, const char *src)
{
/* you can check src != NULL here */
char *p = dest; /* pointer to dest (to preserve dest for return) */
int in = 0; /* simple flag to break loop when non-digit found */
while (*src) { /* loop over each char in src */
if (isdigit(*src)) { /* if it is a digit */
*p++ = *src; /* copy to dest */
in = 1; /* set in-number flag */
}
else if (in) /* if in-number, break on non-digit */
break;
src++; /* increment src pointer */
}
*p = 0; /* nul-terminate dest */
return dest; /* return pointer to dest (for convenience) */
}
int main (void) {
char digits[MAXC] = "";
const char *string = "'(213}'";
printf ("in : %s\nout: %s\n", string, extractdigits (digits, string));
}
Example Use/Output
$ ./bin/extractdigits
in : '(213}'
out: 213
Look things over and let me know if you have further questions.
A method by filtering '(' and ')' in place. Time complexity is O(N).
int main(void) {
char buffer[] = "(213)";
int bufferLen = 5;
int left = -1;
for (int right = 0; right < bufferLen; ++right) {
if ((buffer[right] != '(') && (buffer[right] != ')')) {
++left;
buffer[left] = buffer[right];
}
}
buffer[++left] = '\0';
printf("%s", buffer);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.