I have two strings that I would like to combine, removing duplicate substrings. Note that every two consecutive numbers constitute a substring. Consider string str1 and str2:
str1 = "#1#.1.2.3#1#.6.7.8"
str2 = "#1#.6.7.8#1#.5.6"
I would like to produce a combined string as:
comboStr = "#1#.1.2.3#1#.6.7.8#1#.5.6" (i.e. I removed the duplicate #1#.6.7.8).
I have written a small function that does this:
char *combine (char *nodehashkey ,char *ngbrhashkey)
{
char *suffix, *combo_hashkey;
char prefix[5], token[15];
short qid;
short len = strlen(nodehashkey);
combo_hashkey = (char*) malloc(sizeof(char) * (len+1));
strcpy(combo_hashkey, nodehashkey);
short offset = len;
sscanf(nodehashkey, "#%hd#", &qid);
sprintf(prefix, "#%hd#", qid);
printf("prefix: %s\n", prefix);
suffix = strtok(ngbrhashkey, prefix);
while (suffix != NULL)
{
strcpy(token, prefix);
strcpy(token + strlen(prefix), suffix);
int token_len = strlen(token);
if(strstr(nodehashkey, token) == NULL)
{
if(!(combo_hashkey = (char*) realloc (
combo_hashkey, sizeof(char) * (offset+token_len+1))))
printf("malloc failed!");
strncpy(combo_hashkey + offset, token, token_len+1);
offset += token_len;
combo_hashkey[offset] = '\0';
}
suffix = strtok(NULL, prefix);
}
return combo_hashkey;
}
In order to test it, I have tried the following. While, the first two calls to combine produce the correct combo string, the third call doesn't. In stead of producing #1#.1.6#1#.2.4#1#.3.5, it's producing #1#.1.6#1#.2.4#1#.6#1#.3.5
int main (int argc, char *argv[])
{
char *str1 = malloc(sizeof(char) * 8);
strcpy(str1, "#1#.1.6");
char *str2= malloc(sizeof(char) * 8);
strcpy(str2, "#1#.2.4");
char *str3 = malloc(sizeof(char) * 8);
strcpy(str3, "#1#.3.5");
str2 = combine(str1, str2);
str3 = combine(str1, str3);
char *weird = combine(str2, str3);
printf("weird: %s\n", weird);
}
I have traced the function again and I can not spot where the extra #1#.6 comes from.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *combine (const char *nodehashkey, const char *ngbrhashkey){
int i, dup, len, pos_count = 0;
const char *p1, *p2, *pos[64];
char *combo_hashkey, *p3;
if(!nodehashkey || !ngbrhashkey)
return NULL;
//store key position
pos[0] = p1 = nodehashkey;
while(*p1){
sscanf(p1, "#%*d#%*[.0123456789]%n", &len);
pos[++pos_count] = (p1 += len);
}
len = p1 - nodehashkey;
p2 = ngbrhashkey;
p3 = combo_hashkey = malloc(len + strlen(p2) + 1);
memcpy(p3, nodehashkey, len);
p3 += len;
while(*p2){
sscanf(p2, "#%*d#%*[.0123456789]%n", &len);
for(dup=i=0;i<pos_count;++i){
if(pos[i+1]-pos[i] == len && strncmp(pos[i], p2, len)==0){
dup = 1;
break;
}
}
if(!dup){
memcpy(p3, p2, len);
p3 += len;
}
p2 += len;
}
*p3 = '\0';
return combo_hashkey;
}
int main(){
char *str1, *str2, *str3;
str1 = combine("#1#.1.2.3#1#.6.7.8", "#1#.6.7.8#1#.5.6");
printf("%s\n", str1);//#1#.1.2.3#1#.6.7.8#1#.5.6
free(str1);
str2 = combine("#1#.1.6", "#1#.2.4");
str3 = combine("#1#.1.6", "#1#.3.5");
printf("str2:%s\n", str2);
printf("str3:%s\n", str3);
char *weird = combine(str2, str3);
printf("weird: %s\n", weird);//weird: #1#.1.6#1#.2.4#1#.3.5
free(str2);free(str3);free(weird);
return 0;
}
Related
Situation as following:
In the first line input a string, then the following lines are 'command'. 2 types of command 'p' and 's', 'p' means printing the string, 's' means substitution.
e.g. Input a string aaabbbcccqwerdd then input sbqwerbkkk
(s means substitution, b acts as a delimiter, therefore it means replacing qwer in the string with kkk)
The expected result should be aaabbbccckkkdd, but instead I got aaabbbccckkkrdd
Any help?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 1023
int main() {
char str[MAXLEN];
scanf("%s", str);
char command[MAXLEN];
while (scanf("%s", command) != EOF) {
if (command[0] == 'p') {
printf("%s\n", str); }
else if (command[0] == 's') {
char delimiter[] = {"0"};
strncpy(delimiter, command+1, 1);
char *a = command;
a = strtok(command, delimiter);
a = strtok(NULL, delimiter);
char *b = command;
b = strtok(NULL, delimiter);
int alength = strlen(a);
int blength = strlen(b);
char *bereplaced = strstr(str, a);
if (bereplaced == NULL) {
continue; }
int aindex = bereplaced - str;
strncpy(str + aindex, b, blength);
}
}
return 0;
}
Many things can go wrong here but the main issue is copying from from source string on to itself, there can be memory overlap. Instead declare a new buffer for the result for find/replace operation.
You can define a separate find_replace function as follows:
char* find_replace(const char* src, const char* find, const char* replace)
{
if (!src) return NULL;
char* find_ptr = strstr(src, find); if (!find_ptr) return NULL;
int find_start = find_ptr - src;
int find_length = strlen(find);
char* result = malloc(strlen(src) + strlen(replace) + 1);
strncpy(result, src, find_start);
strcpy(result + find_start, replace);
strcat(result, find_ptr + find_length);
return result;
}
int main()
{
char source[] = "aaabbbcccqwerdd";
char command[] = "sbqwerbkkk";
if (command[0] != 's') return 0;
char delimiter[] = { "0" };
delimiter[0] = command[1];
char* find = strtok(command, delimiter); if (!find) return 0;
find = strtok(NULL, delimiter); if (!find) return 0;
char* replace = strtok(NULL, delimiter); if (!replace) return 0;
char* result = find_replace(source, find, replace);
if (!result) return 0;
printf("%s\n", result);
free(result);
return 0;
}
Here is another solution. It does the substitution directly into the input string by:
Use memmove to move the trailing part of the orginal string to its final location
Use strncpy to copy the substitute substring to its final location
Like:
#include <stdio.h>
#include <string.h>
#define MAXLEN 1023
int main(void)
{
char str[MAXLEN] = "aaabbbcccqwerdd";
char command[MAXLEN] = "sbqwerbkkk";
printf("COMMAND : %s\n", command);
printf("TEXT BEFORE : %s\n", str);
char* pfind = command + 2; // skip initial sb
char* psub = strchr(pfind, 'b'); // find delimiter
*psub = '\0'; // terminate replace string
++psub; // point to substitute substring
size_t flen = strlen(pfind); // calculate length
size_t slen = strlen(psub); // calculate length
char* p = strstr(str, pfind); // find location of replace string
size_t sc = strlen(p); // calculate length
memmove(p + slen, p + flen, sc - flen + 1); // Move trailing part
strncpy(p, psub, slen); // Put in substitute substring
printf("TEXT AFTER : %s\n", str);
return 0;
}
Output:
COMMAND : sbqwerbkkk
TEXT BEFORE : aaabbbcccqwerdd
TEXT AFTER : aaabbbccckkkdd
Disclamer
In order to keep the code example short, the above code blindly trust that the command and the original string form a legal substitution and that there are sufficient memory for the result.
In real code, you need to check that. For instance check that strchr and strstr doesn't return NULL.
Maybe it's a stupid question, but I get stuck here for a while.
Let's say freq_tostring() converts a word frequency freq into string, and freq_intostream() appends that string to the end of a stream.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
typedef struct {
char *word; // null-terminated
int freq;
} freq;
/**
* Constructor
*/
void new_freq(freq *fq, const char *word, const int freq) {
fq->word = (char *)malloc((strlen(word) + 1) * sizeof(char)); // +1 for null-terminator
strcpy(fq->word, word);
fq->freq = freq;
}
/**
* Free memory
*/
void dispose_freq(void *fq) {
freq *p = (freq *)fq;
free(p->word);
p->word = NULL;
}
/**
* snprintf() will terminate the string with a null character, unless buf_size is zero.
*/
char *freq_tostring(freq *fq) {
size_t wordlen = strlen(fq->word);
char *buffer = (char *)malloc(wordlen + 16); // maximum integer has 10 digits
snprintf(buffer, wordlen + 16, "[%s, %d]\n", fq->word, fq->freq);
return buffer;
}
/**
* Append the string of freq to the end of stream.
*/
void freq_intostream(void *elem, void *stream) {
freq *fq = (freq *)elem;
char *str = *(char **)stream;
size_t strsize = strlen(str);
// printf("Stream = \"%s\", length = %lu\n", str, strsize);
char *word = freq_tostring(fq);
size_t wordsize = strlen(word);
// printf("Element = \"%s\"%lu\n", word, wordsize);
char *temp = (char *)realloc(str, strsize + wordsize + 1);
strcpy(temp + strsize, word);
temp[strsize + wordsize] = '\0';
// printf("After strcpy(): \"%s\"\n", temp);
str = temp;
free(word);
}
int main(void) {
freq apple, banana, kiwi;
new_freq(&apple, "apple", 3);
new_freq(&banana, "banana", 2);
new_freq(&kiwi, "kiwi", 5);
char *buffer = (char *)malloc(1);
buffer[0] = '\0';
freq_intostream(&apple, &buffer);
freq_intostream(&banana, &buffer);
freq_intostream(&kiwi, &buffer);
assert(strlen(buffer) == 33);
assert(strcmp(buffer, "[apple, 3]\n[banana, 2]\n[kiwi, 5]\n") == 0);
dispose_freq(&apple);
dispose_freq(&banana);
dispose_freq(&kiwi);
free(buffer);
}
The weird thing is, when I run 10 times, it gives me about 9 pointer being realloc'd was not allocated, but maybe in 1~2 cases, everything is ok.
If I comment out the printf(), it shows that before appending the third element kiwi, the stream is empty, and that could be why realloc is failed. But I'm sure that I pass a pointer of char * stream to the freq_intostream() function, which is a char ** for sure. I can't find out what's the problem, anyone can help?
You've done the equivalent of i = j; i = 3; when you wanted j = 3;. Obviously, these don't do the same thing. Have a close look at the marked line in this funciton:
/**
* Append the string of freq to the end of stream.
*/
void freq_intostream(void *elem, void *stream) {
freq *fq = (freq *)elem;
char *str = *(char **)stream;
size_t strsize = strlen(str);
// printf("Stream = \"%s\", length = %lu\n", str, strsize);
char *word = freq_tostring(fq);
size_t wordsize = strlen(word);
// printf("Element = \"%s\"%lu\n", word, wordsize);
char *temp = (char *)realloc(str, strsize + wordsize + 1);
strcpy(temp + strsize, word);
temp[strsize + wordsize] = '\0';
// printf("After strcpy(): \"%s\"\n", temp);
str = temp; // OOPS!!
free(word);
}
You change the value of str, but str is a local to this function and its value is thrown away as soon as the function ends.
You wanted: *(char**)stream = temp; to change the value the caller passed you a pointer to.
This code would be much simpler if you get rid of all the casts. If elem were of type char **, you could just do *elem = temp; and the code would be much easier to understand.
I wrote a program to concat two strings and make sure the buffer will double the size when there's no enough space.
char * strcat_ex(char * * dest, int * n, const char * src){
int dest_len = 0;
int src_len = 0;
if (*dest == NULL) *n = 0;
else dest_len = strlen(*dest);
if (src == NULL) return *dest;
else src_len = strlen(src);
if (dest_len + src_len + 1 > *n) {
//(1) malloc a new buffer of size 1 + 2 * (strlen(*dest) + strlen(src))
char * temp;
temp = (char*) malloc(1 + 2 * (strlen(*dest) + strlen(src)));
//(2) set '*n' to the size of the new buffer
*n = 1 + 2 * (strlen(*dest) + strlen(src));
//(3) copy '*dest' into the beginning of the new buffer
strcpy(temp, *dest);
//(4) free the memory '*dest', and then set '*dest' to point to the new buffer
free(*dest);
*dest = temp;
}
//(5) concatenate 'src' onto the end of '*dest'.
while (temp) temp++;
while ((temp++ = src++) =! '\0');
return *dest;}
and this code doesn't work. I got segmentation fault at "free(*dest)".
Please help. Thank you very much!
Here's the main function:
int main(int argc, char * * argv){
printf("\nTesting strcat_ex(...)\n");
char * str1;
str1 = "one";
char * str2;
str2 = "two";
int n;
n = strlen(str1);
printf("Before strcat_ex, str1 == %p (%s), str2 == %p (%s)\n", str1, str1, str2, str2);
strcat_ex(&(str1), &n, str2);
printf("After swap, str1 == %p (%s), str2 == %p (%s)\n", str1, str1, str2, str2);
return EXIT_SUCCESS;
}
The problem is that the initial value of str1 is a pointer to a literal string. That pointer cannot be freed. So the fix is to malloc space in main, e.g.
char *str1 = malloc( 100 ); // allocate an initial buffer
int n = 100; // the buffer has 100 bytes
strcpy( str1, "one" ); // put some text in the buffer
I'm new to C programming. I have a task to do.
User inputs two strings. What I need to do is to create a new string that will consist only from common letters of those two given strings.
For example:
if given:
str1 = "ABCDZ"
str2 = "ADXYZ"
the new string will look like: "ADZ".
I can't make it work. I think there must be a better (more simple) algorithm but I have waisted too much time for this one so I want to complete it .. need your help!
what I've done so far is this:
char* commonChars (char* str1, char* str2)
{
char *ptr, *qtr, *arr, *tmp, *ch1, *ch2;
int counter = 1;
ch1 = str1;
ch2 = str2;
arr = (char*) malloc ((strlen(str1)+strlen(str2)+1)*(sizeof(char))); //creating dynamic array
strcpy(arr, str1);
strcat(arr,str2);
for (ptr = arr; ptr < arr + strlen(arr); ptr++)
{
for (qtr = arr; qtr < arr + strlen(arr); qtr++) // count for each char how many times is appears
{
if (*qtr == *ptr && qtr != ptr)
{
counter++;
tmp = qtr;
}
}
if (counter > 1)
{
for (qtr = tmp; *qtr; qtr++) //removing duplicate characters
*(qtr) = *(qtr+1);
}
counter = 1;
}
sortArray(arr, strlen(arr)); // sorting the string in alphabetical order
qtr = arr;
for (ptr = arr; ptr < arr + strlen(arr); ptr++, ch1++, ch2++) //checking if a letter appears in both strings and if at least one of them doesn't contain this letter - remove it
{
for (qtr = ptr; *qtr; qtr++)
{
if (*qtr != *ch1 || *qtr != *ch2)
*qtr = *(qtr+1);
}
}
}
Don't know how to finish this code .. i would be thankful for any suggestion!
The output array cannot be longer that the shorter of the two input arrays.
You can use strchr().
char * common (const char *in1, const char *in2) {
char *out;
char *p;
if (strlen(in2) < strlen(in1)) {
const char *t = in2;
in2 = in1;
in1 = t;
}
out = malloc(strlen(in2)+1);
p = out;
while (*in1) {
if (strchr(in2, *in1)) *p++ = *in1;
++in1;
}
*p = '\0';
return out;
}
This has O(NxM) performance, where N and M are the lengths of the input strings. Because your input is alphabetical and unique, you can achieve O(N+M) worst case performance. You apply something that resembles a merge loop.
char * common_linear (const char *in1, const char *in2) {
char *out;
char *p;
if (strlen(in2) < strlen(in1)) {
const char *t = in2;
in2 = in1;
in1 = t;
}
out = malloc(strlen(in2)+1);
p = out;
while (*in1 && *in2) {
if (*in1 < *in2) {
++in1;
continue;
}
if (*in2 < *in1) {
++in2;
continue;
}
*p++ = *in1;
++in1;
++in2;
}
*p = '\0';
return out;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define min(x,y) ((x)<(y)? (x) : (y))
char* commonChars (const char *str1, const char *str2){
//str1, str2 : sorted(asc) and unique
char *ret, *p;
int len1, len2;
len1=strlen(str1);
len2=strlen(str2);
ret = p = malloc((min(len1, len2)+1)*sizeof(char));
while(*str1 && *str2){
if(*str1 < *str2){
++str1;
continue;
}
if(*str1 > *str2){
++str2;
continue;
}
*p++ = *str1++;
++str2;
}
*p ='\0';
return ret;
}
char *deleteChars(const char *str, const char *dellist){
//str, dellist : sorted(asc) and unique
char *ret, *p;
ret = p = malloc((strlen(str)+1)*sizeof(char));
while(*str && *dellist){
if(*str < *dellist){
*p++=*str++;
continue;
}
if(*str > *dellist){
++dellist;
continue;
}
++str;
++dellist;
}
if(!*dellist)
while(*str)
*p++=*str++;
*p ='\0';
return ret;
}
int main(void){
const char *str1 = "ABCDXYZ";
const char *str2 = "ABCDZ";
const char *str3 = "ADXYZ";
char *common2and3;
char *withoutcommon;
common2and3 = commonChars(str2, str3);
//printf("%s\n", common2and3);//ADZ
withoutcommon = deleteChars(str1, common2and3);
printf("%s\n", withoutcommon);//BCXY
free(common2and3);
free(withoutcommon);
return 0;
}
I will do something like this :
char* commonChars(char* str1, char* str2) {
char* ret = malloc(strlen(str1) * sizeof(char));
int i = j = k = 0;
for (; str1[i] != '\n'; i++, j++) {
if (str1[i] == str2[j]) {
ret[k] = str1[i];
k++;
}
}
ret[k] = '\0';
ret = realloc(ret, k);
return ret;
}
It's been a while i didn't do C, hope this is correct
You can use strpbrk() function, to do this job cleanly.
const char * strpbrk ( const char * str1, const char * str2 );
char * strpbrk ( char * str1, const char * str2 );
Locate characters in string
Returns a pointer to the first occurrence in str1 of any of the characters that are part of str2, or a null pointer if there are no matches.
The search does not include the terminating null-characters of either strings, but ends there.
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "ABCDZ";
char key[] = "ADXYZ";
char *newString = malloc(sizeof(str)+sizeof(key));
memset(newString, 0x00, sizeof(newString));
char * pch;
pch = strpbrk (str, key);
int i=0;
while (pch != NULL)
{
*(newString+i) = *pch;
pch = strpbrk (pch+1,key);
i++;
}
printf ("%s", newString);
return 0;
}
Sorry for the weird use of char arrays, was just trying to get it done fast. The idea behind the algorithm should be obvious, you can modify some of the types, loop ending conditions, remove the C++ elements, etc for your purposes. It's the idea behind the code that's important.
#include <queue>
#include <string>
#include <iostream>
using namespace std;
bool isCharPresent(char* str, char c) {
do {
if(c == *str) return true;
} while(*(str++));
return false;
}
int main ()
{
char str1[] = {'h', 'i', 't', 'h', 'e', 'r', 'e', '\0'};
char str2[] = {'a', 'h', 'i', '\0'};
string result = "";
char* charIt = &str1[0];
do {
if(isCharPresent(str2, *charIt))
result += *charIt;
} while(*(charIt++));
cout << result << endl; //hih is the result. Minor modifications if dupes are bad.
}
So i found the solution for my problem. Eventually I used another algorithm which, as turned out, is very similar to what #BLUEPIXY and #user315052 have suggested. Thanks everyone who tried to help! Very nice and useful web source!
Here is my code. Someone who'll find it useful can use it.
Note:
(1) str1 & str2 should be sorted alphabetically;
(2) each character should appear only once in each given strings;
char* commonChars (char* str1, char* str2)
{
char *ptr, *arr,*ch1, *ch2;
int counter = 0;
for (ch1 = str1; *ch1; ch1++)
{
for(ch2 = str2; *ch2; ch2++)
{
if (*ch1 == *ch2)
counter++;
}
}
arr = (char*)malloc ((counter+1) * sizeof(char));
ch1 = str1;
ch2 = str2;
ptr = arr;
for (ch1 = str1; *ch1; ch1++,ch2++)
{
while (*ch1 < *ch2)
{
ch1++;
}
while (*ch1 > *ch2)
{
ch2++;
}
if (*ch1 == *ch2)
{
*ptr = *ch1;
ptr++;
}
}
if (ptr = arr + counter)
*ptr = '\0';
return arr;
}
how I do to repeat a string?
something like "hello world" * 3
the output "hello world hello world hello world"
In your source code, without much processing, probably the easiest way is with:
#define HI "hello world"
char str[] = HI " " HI " " HI;
This will declare a string of the requested value:
"hello world hello world hello world"
If you want code that will do it, you can use something like:
char *repeatStr (char *str, size_t count) {
if (count == 0) return NULL;
char *ret = malloc (strlen (str) * count + count);
if (ret == NULL) return NULL;
strcpy (ret, str);
while (--count > 0) {
strcat (ret, " ");
strcat (ret, str);
}
return ret;
}
Now keep in mind this can be made more efficient - multiple strcat operations are ripe for optimisation to avoid processing the data over and over (a). But this should be a good enough start.
You're also responsible for freeing the memory returned by this function.
(a) Such as with:
// Like strcat but returns location of the null terminator
// so that the next myStrCat is more efficient.
char *myStrCat (char *s, char *a) {
while (*s != '\0') s++;
while (*a != '\0') *s++ = *a++;
*s = '\0';
return s;
}
char *repeatStr (char *str, size_t count) {
if (count == 0) return NULL;
char *ret = malloc (strlen (str) * count + count);
if (ret == NULL) return NULL;
*ret = '\0';
char *tmp = myStrCat (ret, str);
while (--count > 0) {
tmp = myStrCat (tmp, " ");
tmp = myStrCat (tmp, str);
}
return ret;
}
You could use sprintf.
char s[20] = "Hello";
char s2[20];
sprintf(s2,"%s%s%s",s,s,s);
I've made this function based on earlier answers in this post.
I share it here because some of previous examples has been thrown me segfaults
const char* str_repeat(char* str, size_t times)
{
if (times < 1) return NULL;
char *ret = malloc(sizeof(str) * times + 1);
if (ret == NULL) return NULL;
strcpy(ret, &str);
while (--times > 0) {
strcat(ret, &str);
}
return ret;
}
http://ideone.com/5sNylW
#include <stdio.h>
#include <string.h>
int main(void) {
char k[100];
gets(k);
int lk=strlen(k);
int times;
scanf("%d",×);
int tl= times*lk;
int i,x=0;
for(i=lk-1;i<tl;i++)
{
k[i+1]=k[x];
x++;
}
for(i=0;i<tl;i++)
{
printf("%c",k[i]);
}
return 0;
}
You may try write own function. It will be work with single-length string also (i. e. duplication a single char). It use the function "strcat()" from the "string.h", so do not forget include this header.
char *
str_repeat(char str[], unsigned int times)
{
if (times < 1)
return NULL;
char *result;
size_t str_len = strlen(str);
result = malloc(sizeof(char) * str_len + 1);
while (times--) {
strcat(result, str);
}
return result;
}
But, if you need only duplication of a string for print it, try macro
#define PRINT_STR_REPEAT(str, times) \
{ \
for (int i = 0; i < times; ++i) \
printf("%s", str); \
puts(""); \
}
Results
PRINT_STR_REPEAT("-", 10); // ----------
puts(str_repeat("-", 10)); // ----------
PRINT_STR_REPEAT("$", 2); // $$
puts(str_repeat("$", 2)); // $$
PRINT_STR_REPEAT("*\t*", 10); // * ** ** ** ** ** ** ** ** ** *
puts(str_repeat("*\t*", 10)); // * ** ** ** ** ** ** ** ** ** *
PRINT_STR_REPEAT("*_*", 10); // *_**_**_**_**_**_**_**_**_**_*
puts(str_repeat("*_*", 10)); // *_**_**_**_**_**_**_**_**_**_*
Here's a way to repeat a string in C, N times.
That is have a string "abc"
and I want a string of length 7 that is comprised of this string repeated.
N = 7;
result: "abcabca"
while(Index != N){
repeatedString[Index] = oldString[Index%strlen(oldString)];
Index++;
}
Where repeated String would be "abcabca" at the end, and oldString is "abc".