I want to add \"\"
to {\"status\":true}
so that the string looks like \"{\"status\":\"true\"}\"
. How can I insert characters to a stri
#include <stdio.h>
#include<stdlib.h>
#include<strings.h>
//{"status":true}\0_ _
//{"status": true " } \0
/*
* parses the string, reallocates and shifts chars as needed, not generic though
*/
int
insertQuotes(char ** original, int sizeOriginal)
{
int i = 0;
char * start = NULL;
char * temp = NULL;
long lenLeft = 0;
int newSize = sizeOriginal + 2;
if(*original == NULL)
return -1;
*original = realloc(*original, newSize);
if (*original) {
start = strstr(*original, ":");
temp = *original + newSize - 1;
*temp = '\0';
temp--;
*temp = '}';
temp--;
*temp = '"';
temp--;
while (temp > start + 1) {
*(temp) = *(temp - 1);
temp--;
}
*temp = '"';
return 0;
} else {
return -1;
}
}
int main()
{
char * original = NULL;
int retval = 0;
original = (char *)malloc(sizeof("{\"status\":true}"));
if (!original) return 1;
strncpy(original, "{\"status\":true}", sizeof("{\"status\":true}"));
retval = insertQuotes(&original, sizeof("{\"status\":true}"));
if (!retval) {
printf("\nnew original is [%s]", original);
}
free(original);
return 0;
}
Use sprintf()
.
const char *source = "{\"status\":\"true\"}";
/* find length of the source string */
int source_len = strlen(source);
/* find length of the new string */
int result_len = source_len + 2; /* 2 quotation marks */
/* allocate memory for the new string (including null-terminator) */
char *result = malloc((result_len + 1) * sizeof(char));
/* write and verify the string */
if (sprintf(result, "\"%s\"", source) != result_len) { /* handle error */ }
/* result == "\"{\"status\":\"true\"}\"" */
I attempted an implementation of strinsert and pasted it below. It compiles and the tests pass with VS2010.
The function takes a pointer to the destination buffer, the destination buffer size, string to insert, and the location to insert the string. The function returns -1 in case of error otherwise it returns the size of the destination buffer. If the destination buffer is too small to accommodate the inserted string, it resizes the buffer using realloc and returns the new buffer size.
I used memmove instead of strncpy as I believe strncpy is undefined when the source and destination overlap. This can be possible if the inserted string is smaller than the amount of memory that is moved.
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <assert.h>
int strinsert(char **dest, size_t destsize, char *ins, size_t location)
{
size_t origsize = 0;
size_t resize = 0;
size_t inssize = 0;
if (!dest || !ins)
return -1; // invalid parameter
if (strlen(ins) == 0)
return -1; // invalid parameter
origsize = strlen(*dest);
inssize = strlen(ins);
resize = strlen(*dest) + inssize + 1; // 1 for the null terminator
if (location > origsize)
return -1; // invalid location, out of original string
// resize string to accommodate inserted string if necessary
if (destsize < resize)
*dest = (char*)realloc(*dest, resize);
// move string to make room for insertion
memmove(&(*dest)[location+inssize], &(*dest)[location], origsize - location);
(*dest)[origsize + inssize] = '\0'; // null terminate string
// insert string
memcpy(&(*dest)[location], ins, inssize);
return max(destsize, resize); // return buffer size
}
void check(int retVal)
{
if (retVal < 0)
{
assert(!"error code returned!\n");
exit(1);
}
}
#define STARTSTRING "Hello world!"
int _tmain(int argc, _TCHAR* argv[])
{
// initialize str
int bufsize = strlen(STARTSTRING) + 1 + 10; // added 1 for null terminator and 10 to test resize on demand
int prevbufsize = 0;
char *str = (char*)malloc(bufsize);
strncpy_s(str, bufsize, STARTSTRING, strlen(STARTSTRING));
printf("str = %s\n", str);
// test inserting in the middle
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "awesome ", 6);
assert(bufsize == prevbufsize); // this should not resize the buffer as it has room for 10 more bytes
check(bufsize);
printf("str = %s\n", str);
// test inserting at front
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "John says ", 0);
assert(bufsize > prevbufsize);
check(bufsize);
printf("str = %s\n", str);
// test inserting char in the middle
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "\"", 10);
assert(bufsize > prevbufsize);
check(bufsize);
printf("str = %s\n", str);
// test inserting char at end
prevbufsize = bufsize;
bufsize = strinsert(&str, bufsize, "\"", strlen(str));
assert(bufsize > prevbufsize);
check(bufsize);
printf("str = %s\n", str);
free(str);
return 0;
}
Here is the output:
str = Hello world! str = Hello awesome world! str = John says Hello awesome world! str = John says "Hello awesome world! str = John says "Hello awesome world!"
Yes, you will need to write your own function for that.
Note that a string in C is a char[]
, i.e. an array of characters, and is of fixed size.
What you can do is, create a new string that serves as the result, copy the first part of the subject string into it, append the string that goes in the middle, and append the second half of the subject string.
The code goes something like,
// inserts into subject[] at position pos
void append(char subject[], const char insert[], int pos) {
char buf[100] = {}; // 100 so that it's big enough. fill with zeros
// or you could use malloc() to allocate sufficient space
// e.g. char *buf = (char*)malloc(strlen(subject) + strlen(insert) + 2);
// to fill with zeros: memset(buf, 0, 100);
strncpy(buf, subject, pos); // copy at most first pos characters
int len = strlen(buf);
strcpy(buf+len, insert); // copy all of insert[] at the end
len += strlen(insert); // increase the length by length of insert[]
strcpy(buf+len, subject+pos); // copy the rest
strcpy(subject, buf); // copy it back to subject
// Note that subject[] must be big enough, or else segfault.
// deallocate buf[] here, if used malloc()
// e.g. free(buf);
}
Working example here