C - Replace $$ in string with ID from getpid()?












1















If I have a string like the following:



char* exampleString = "test$$";


Let's say that getpid() returns 1587.



How can I replace the $$ in the string with the result of getpid() such that the result would be a string "test1587"?










share|improve this question

























  • I have to be able to replace $$ where ever it exists in the string. The string could be "dfkgdfkgd$$fds" and I would need to replace it in the middle of the string. Any ideas?

    – yoyo1
    Nov 15 '18 at 2:22






  • 1





    Using literal strings you can't, since they are read-only in C. You need to use array, long enough to fit the modifications you do to it.

    – Some programmer dude
    Nov 15 '18 at 2:23
















1















If I have a string like the following:



char* exampleString = "test$$";


Let's say that getpid() returns 1587.



How can I replace the $$ in the string with the result of getpid() such that the result would be a string "test1587"?










share|improve this question

























  • I have to be able to replace $$ where ever it exists in the string. The string could be "dfkgdfkgd$$fds" and I would need to replace it in the middle of the string. Any ideas?

    – yoyo1
    Nov 15 '18 at 2:22






  • 1





    Using literal strings you can't, since they are read-only in C. You need to use array, long enough to fit the modifications you do to it.

    – Some programmer dude
    Nov 15 '18 at 2:23














1












1








1








If I have a string like the following:



char* exampleString = "test$$";


Let's say that getpid() returns 1587.



How can I replace the $$ in the string with the result of getpid() such that the result would be a string "test1587"?










share|improve this question
















If I have a string like the following:



char* exampleString = "test$$";


Let's say that getpid() returns 1587.



How can I replace the $$ in the string with the result of getpid() such that the result would be a string "test1587"?







c string replace






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 3:50









Swordfish

10.2k11436




10.2k11436










asked Nov 15 '18 at 2:18









yoyo1yoyo1

205




205













  • I have to be able to replace $$ where ever it exists in the string. The string could be "dfkgdfkgd$$fds" and I would need to replace it in the middle of the string. Any ideas?

    – yoyo1
    Nov 15 '18 at 2:22






  • 1





    Using literal strings you can't, since they are read-only in C. You need to use array, long enough to fit the modifications you do to it.

    – Some programmer dude
    Nov 15 '18 at 2:23



















  • I have to be able to replace $$ where ever it exists in the string. The string could be "dfkgdfkgd$$fds" and I would need to replace it in the middle of the string. Any ideas?

    – yoyo1
    Nov 15 '18 at 2:22






  • 1





    Using literal strings you can't, since they are read-only in C. You need to use array, long enough to fit the modifications you do to it.

    – Some programmer dude
    Nov 15 '18 at 2:23

















I have to be able to replace $$ where ever it exists in the string. The string could be "dfkgdfkgd$$fds" and I would need to replace it in the middle of the string. Any ideas?

– yoyo1
Nov 15 '18 at 2:22





I have to be able to replace $$ where ever it exists in the string. The string could be "dfkgdfkgd$$fds" and I would need to replace it in the middle of the string. Any ideas?

– yoyo1
Nov 15 '18 at 2:22




1




1





Using literal strings you can't, since they are read-only in C. You need to use array, long enough to fit the modifications you do to it.

– Some programmer dude
Nov 15 '18 at 2:23





Using literal strings you can't, since they are read-only in C. You need to use array, long enough to fit the modifications you do to it.

– Some programmer dude
Nov 15 '18 at 2:23












2 Answers
2






active

oldest

votes


















3














Since "test$$" is immutable and a pointer to it should better be char const* instead of char* you'd have to copy it to an array where you then can replace "$$".



Possible solution:



#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>

int main(void)
{
char const *input = "foo$$bar";
pid_t pid = 1234;

size_t format_length = strlen(input);
char *format = calloc(format_length + 2, 1);
if (!format) {
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// copy input to format replacing "$$" with "%ld" in the process
bool replacement_done = false;
for (size_t i = 0; i < format_length + replacement_done; ++i) {
if (!replacement_done && i + 1 < format_length &&
input[i] == '$' && input[i + 1] == '$')
{
format[ i] = '%'; // just
format[++i] = 'l'; // being
format[++i] = 'd'; // safe.
replacement_done = true;
continue;
}

format[i] = input[i - replacement_done];
}

if (!replacement_done) {
free(format);
fputs("Nothing to do :(nn", stderr);
return EXIT_FAILURE;
}

char *result = malloc(1);
if (!result) {
free(format);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// there is no guesswork needed, snprintf() will tell the needed size
int bytes_needed = snprintf(result, 1, format, (long)getpid());
if (bytes_needed < 0) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

char *temp = realloc(result, ++bytes_needed);
if (!temp) {
free(format);
free(result);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}
result = temp;

int written = snprintf(result, bytes_needed, format, (long)getpid()); // long should be big enough
if(written < 0 || written >= bytes_needed ) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

puts(result); // done.

free(format);
free(result);
}





share|improve this answer


























  • What would the code for this look like? And would it be possible to convert this array back into a char*?

    – yoyo1
    Nov 15 '18 at 2:28











  • @yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

    – Some programmer dude
    Nov 15 '18 at 2:30











  • @yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

    – Swordfish
    Nov 15 '18 at 2:51











  • @Swordfish Let's assume there is only one instance of "$$" per char* string

    – yoyo1
    Nov 15 '18 at 2:53











  • Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

    – yoyo1
    Nov 15 '18 at 3:30



















1














You can't do a direct substitution because your string (character array) is not long enough to hold the pid, and of course, if declared as a string literal is also not mutable.



There are a couple of ways you could go with this, but here's a reasonably elegant one:



/* Modify the existing string to be a pattern string for snprintf */
int len = strlen(exampleString) - 1; /* Can you see why I might do this? */
char* formatString = strdup(exampleString); /* Because we can't modify a literal */
int newLen = len + 12; /* How about this? */
char *pidString = malloc(newLen);
int i;
for (i = 0; i < len; i++) {
if (formatString[i] == '$' && formatString[i+1] == '$') {
formatString[i] = '%';
formatString[i+1] = 'd';
break;
}
}
snprintf(pidString, newLen - 1, formatString, getpid());


Can you follow how this works?



How would you enhance this to fail gracefully if the exampleString does not contain $$ ?






share|improve this answer


























  • Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

    – yoyo1
    Nov 15 '18 at 2:44











  • I was wrong in my first try. They were right. I fixed it.

    – bluejack
    Nov 15 '18 at 2:45











  • But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

    – yoyo1
    Nov 15 '18 at 2:47











  • "/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

    – Swordfish
    Nov 15 '18 at 2:47








  • 1





    Okay I implemented this functionality and it appears to work for me. Thanks!

    – yoyo1
    Nov 15 '18 at 3:23











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53311499%2fc-replace-in-string-with-id-from-getpid%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














Since "test$$" is immutable and a pointer to it should better be char const* instead of char* you'd have to copy it to an array where you then can replace "$$".



Possible solution:



#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>

int main(void)
{
char const *input = "foo$$bar";
pid_t pid = 1234;

size_t format_length = strlen(input);
char *format = calloc(format_length + 2, 1);
if (!format) {
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// copy input to format replacing "$$" with "%ld" in the process
bool replacement_done = false;
for (size_t i = 0; i < format_length + replacement_done; ++i) {
if (!replacement_done && i + 1 < format_length &&
input[i] == '$' && input[i + 1] == '$')
{
format[ i] = '%'; // just
format[++i] = 'l'; // being
format[++i] = 'd'; // safe.
replacement_done = true;
continue;
}

format[i] = input[i - replacement_done];
}

if (!replacement_done) {
free(format);
fputs("Nothing to do :(nn", stderr);
return EXIT_FAILURE;
}

char *result = malloc(1);
if (!result) {
free(format);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// there is no guesswork needed, snprintf() will tell the needed size
int bytes_needed = snprintf(result, 1, format, (long)getpid());
if (bytes_needed < 0) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

char *temp = realloc(result, ++bytes_needed);
if (!temp) {
free(format);
free(result);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}
result = temp;

int written = snprintf(result, bytes_needed, format, (long)getpid()); // long should be big enough
if(written < 0 || written >= bytes_needed ) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

puts(result); // done.

free(format);
free(result);
}





share|improve this answer


























  • What would the code for this look like? And would it be possible to convert this array back into a char*?

    – yoyo1
    Nov 15 '18 at 2:28











  • @yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

    – Some programmer dude
    Nov 15 '18 at 2:30











  • @yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

    – Swordfish
    Nov 15 '18 at 2:51











  • @Swordfish Let's assume there is only one instance of "$$" per char* string

    – yoyo1
    Nov 15 '18 at 2:53











  • Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

    – yoyo1
    Nov 15 '18 at 3:30
















3














Since "test$$" is immutable and a pointer to it should better be char const* instead of char* you'd have to copy it to an array where you then can replace "$$".



Possible solution:



#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>

int main(void)
{
char const *input = "foo$$bar";
pid_t pid = 1234;

size_t format_length = strlen(input);
char *format = calloc(format_length + 2, 1);
if (!format) {
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// copy input to format replacing "$$" with "%ld" in the process
bool replacement_done = false;
for (size_t i = 0; i < format_length + replacement_done; ++i) {
if (!replacement_done && i + 1 < format_length &&
input[i] == '$' && input[i + 1] == '$')
{
format[ i] = '%'; // just
format[++i] = 'l'; // being
format[++i] = 'd'; // safe.
replacement_done = true;
continue;
}

format[i] = input[i - replacement_done];
}

if (!replacement_done) {
free(format);
fputs("Nothing to do :(nn", stderr);
return EXIT_FAILURE;
}

char *result = malloc(1);
if (!result) {
free(format);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// there is no guesswork needed, snprintf() will tell the needed size
int bytes_needed = snprintf(result, 1, format, (long)getpid());
if (bytes_needed < 0) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

char *temp = realloc(result, ++bytes_needed);
if (!temp) {
free(format);
free(result);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}
result = temp;

int written = snprintf(result, bytes_needed, format, (long)getpid()); // long should be big enough
if(written < 0 || written >= bytes_needed ) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

puts(result); // done.

free(format);
free(result);
}





share|improve this answer


























  • What would the code for this look like? And would it be possible to convert this array back into a char*?

    – yoyo1
    Nov 15 '18 at 2:28











  • @yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

    – Some programmer dude
    Nov 15 '18 at 2:30











  • @yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

    – Swordfish
    Nov 15 '18 at 2:51











  • @Swordfish Let's assume there is only one instance of "$$" per char* string

    – yoyo1
    Nov 15 '18 at 2:53











  • Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

    – yoyo1
    Nov 15 '18 at 3:30














3












3








3







Since "test$$" is immutable and a pointer to it should better be char const* instead of char* you'd have to copy it to an array where you then can replace "$$".



Possible solution:



#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>

int main(void)
{
char const *input = "foo$$bar";
pid_t pid = 1234;

size_t format_length = strlen(input);
char *format = calloc(format_length + 2, 1);
if (!format) {
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// copy input to format replacing "$$" with "%ld" in the process
bool replacement_done = false;
for (size_t i = 0; i < format_length + replacement_done; ++i) {
if (!replacement_done && i + 1 < format_length &&
input[i] == '$' && input[i + 1] == '$')
{
format[ i] = '%'; // just
format[++i] = 'l'; // being
format[++i] = 'd'; // safe.
replacement_done = true;
continue;
}

format[i] = input[i - replacement_done];
}

if (!replacement_done) {
free(format);
fputs("Nothing to do :(nn", stderr);
return EXIT_FAILURE;
}

char *result = malloc(1);
if (!result) {
free(format);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// there is no guesswork needed, snprintf() will tell the needed size
int bytes_needed = snprintf(result, 1, format, (long)getpid());
if (bytes_needed < 0) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

char *temp = realloc(result, ++bytes_needed);
if (!temp) {
free(format);
free(result);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}
result = temp;

int written = snprintf(result, bytes_needed, format, (long)getpid()); // long should be big enough
if(written < 0 || written >= bytes_needed ) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

puts(result); // done.

free(format);
free(result);
}





share|improve this answer















Since "test$$" is immutable and a pointer to it should better be char const* instead of char* you'd have to copy it to an array where you then can replace "$$".



Possible solution:



#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>

int main(void)
{
char const *input = "foo$$bar";
pid_t pid = 1234;

size_t format_length = strlen(input);
char *format = calloc(format_length + 2, 1);
if (!format) {
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// copy input to format replacing "$$" with "%ld" in the process
bool replacement_done = false;
for (size_t i = 0; i < format_length + replacement_done; ++i) {
if (!replacement_done && i + 1 < format_length &&
input[i] == '$' && input[i + 1] == '$')
{
format[ i] = '%'; // just
format[++i] = 'l'; // being
format[++i] = 'd'; // safe.
replacement_done = true;
continue;
}

format[i] = input[i - replacement_done];
}

if (!replacement_done) {
free(format);
fputs("Nothing to do :(nn", stderr);
return EXIT_FAILURE;
}

char *result = malloc(1);
if (!result) {
free(format);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}

// there is no guesswork needed, snprintf() will tell the needed size
int bytes_needed = snprintf(result, 1, format, (long)getpid());
if (bytes_needed < 0) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

char *temp = realloc(result, ++bytes_needed);
if (!temp) {
free(format);
free(result);
fputs("Couldn't allocate memory :(nn", stderr);
return EXIT_FAILURE;
}
result = temp;

int written = snprintf(result, bytes_needed, format, (long)getpid()); // long should be big enough
if(written < 0 || written >= bytes_needed ) {
free(format);
free(result);
fputs("snprintf() failed :(nn", stderr);
return EXIT_FAILURE;
}

puts(result); // done.

free(format);
free(result);
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 '18 at 9:38

























answered Nov 15 '18 at 2:22









SwordfishSwordfish

10.2k11436




10.2k11436













  • What would the code for this look like? And would it be possible to convert this array back into a char*?

    – yoyo1
    Nov 15 '18 at 2:28











  • @yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

    – Some programmer dude
    Nov 15 '18 at 2:30











  • @yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

    – Swordfish
    Nov 15 '18 at 2:51











  • @Swordfish Let's assume there is only one instance of "$$" per char* string

    – yoyo1
    Nov 15 '18 at 2:53











  • Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

    – yoyo1
    Nov 15 '18 at 3:30



















  • What would the code for this look like? And would it be possible to convert this array back into a char*?

    – yoyo1
    Nov 15 '18 at 2:28











  • @yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

    – Some programmer dude
    Nov 15 '18 at 2:30











  • @yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

    – Swordfish
    Nov 15 '18 at 2:51











  • @Swordfish Let's assume there is only one instance of "$$" per char* string

    – yoyo1
    Nov 15 '18 at 2:53











  • Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

    – yoyo1
    Nov 15 '18 at 3:30

















What would the code for this look like? And would it be possible to convert this array back into a char*?

– yoyo1
Nov 15 '18 at 2:28





What would the code for this look like? And would it be possible to convert this array back into a char*?

– yoyo1
Nov 15 '18 at 2:28













@yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

– Some programmer dude
Nov 15 '18 at 2:30





@yoyo1 Arrays naturally decays to pointers to its first element. If you have a char array then the decayed pointer type will be char *.

– Some programmer dude
Nov 15 '18 at 2:30













@yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

– Swordfish
Nov 15 '18 at 2:51





@yoyo1 "What would the code for this look like?" I'm thinking about that. Can there be multiple "$$"?

– Swordfish
Nov 15 '18 at 2:51













@Swordfish Let's assume there is only one instance of "$$" per char* string

– yoyo1
Nov 15 '18 at 2:53





@Swordfish Let's assume there is only one instance of "$$" per char* string

– yoyo1
Nov 15 '18 at 2:53













Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

– yoyo1
Nov 15 '18 at 3:30





Sorry @Swordfish I had marked an accepted answer right before you posted this.. I'd still like to thank you though because you did help me understand this concept more! Thanks!

– yoyo1
Nov 15 '18 at 3:30













1














You can't do a direct substitution because your string (character array) is not long enough to hold the pid, and of course, if declared as a string literal is also not mutable.



There are a couple of ways you could go with this, but here's a reasonably elegant one:



/* Modify the existing string to be a pattern string for snprintf */
int len = strlen(exampleString) - 1; /* Can you see why I might do this? */
char* formatString = strdup(exampleString); /* Because we can't modify a literal */
int newLen = len + 12; /* How about this? */
char *pidString = malloc(newLen);
int i;
for (i = 0; i < len; i++) {
if (formatString[i] == '$' && formatString[i+1] == '$') {
formatString[i] = '%';
formatString[i+1] = 'd';
break;
}
}
snprintf(pidString, newLen - 1, formatString, getpid());


Can you follow how this works?



How would you enhance this to fail gracefully if the exampleString does not contain $$ ?






share|improve this answer


























  • Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

    – yoyo1
    Nov 15 '18 at 2:44











  • I was wrong in my first try. They were right. I fixed it.

    – bluejack
    Nov 15 '18 at 2:45











  • But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

    – yoyo1
    Nov 15 '18 at 2:47











  • "/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

    – Swordfish
    Nov 15 '18 at 2:47








  • 1





    Okay I implemented this functionality and it appears to work for me. Thanks!

    – yoyo1
    Nov 15 '18 at 3:23
















1














You can't do a direct substitution because your string (character array) is not long enough to hold the pid, and of course, if declared as a string literal is also not mutable.



There are a couple of ways you could go with this, but here's a reasonably elegant one:



/* Modify the existing string to be a pattern string for snprintf */
int len = strlen(exampleString) - 1; /* Can you see why I might do this? */
char* formatString = strdup(exampleString); /* Because we can't modify a literal */
int newLen = len + 12; /* How about this? */
char *pidString = malloc(newLen);
int i;
for (i = 0; i < len; i++) {
if (formatString[i] == '$' && formatString[i+1] == '$') {
formatString[i] = '%';
formatString[i+1] = 'd';
break;
}
}
snprintf(pidString, newLen - 1, formatString, getpid());


Can you follow how this works?



How would you enhance this to fail gracefully if the exampleString does not contain $$ ?






share|improve this answer


























  • Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

    – yoyo1
    Nov 15 '18 at 2:44











  • I was wrong in my first try. They were right. I fixed it.

    – bluejack
    Nov 15 '18 at 2:45











  • But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

    – yoyo1
    Nov 15 '18 at 2:47











  • "/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

    – Swordfish
    Nov 15 '18 at 2:47








  • 1





    Okay I implemented this functionality and it appears to work for me. Thanks!

    – yoyo1
    Nov 15 '18 at 3:23














1












1








1







You can't do a direct substitution because your string (character array) is not long enough to hold the pid, and of course, if declared as a string literal is also not mutable.



There are a couple of ways you could go with this, but here's a reasonably elegant one:



/* Modify the existing string to be a pattern string for snprintf */
int len = strlen(exampleString) - 1; /* Can you see why I might do this? */
char* formatString = strdup(exampleString); /* Because we can't modify a literal */
int newLen = len + 12; /* How about this? */
char *pidString = malloc(newLen);
int i;
for (i = 0; i < len; i++) {
if (formatString[i] == '$' && formatString[i+1] == '$') {
formatString[i] = '%';
formatString[i+1] = 'd';
break;
}
}
snprintf(pidString, newLen - 1, formatString, getpid());


Can you follow how this works?



How would you enhance this to fail gracefully if the exampleString does not contain $$ ?






share|improve this answer















You can't do a direct substitution because your string (character array) is not long enough to hold the pid, and of course, if declared as a string literal is also not mutable.



There are a couple of ways you could go with this, but here's a reasonably elegant one:



/* Modify the existing string to be a pattern string for snprintf */
int len = strlen(exampleString) - 1; /* Can you see why I might do this? */
char* formatString = strdup(exampleString); /* Because we can't modify a literal */
int newLen = len + 12; /* How about this? */
char *pidString = malloc(newLen);
int i;
for (i = 0; i < len; i++) {
if (formatString[i] == '$' && formatString[i+1] == '$') {
formatString[i] = '%';
formatString[i+1] = 'd';
break;
}
}
snprintf(pidString, newLen - 1, formatString, getpid());


Can you follow how this works?



How would you enhance this to fail gracefully if the exampleString does not contain $$ ?







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 15 '18 at 3:05

























answered Nov 15 '18 at 2:34









bluejackbluejack

198112




198112













  • Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

    – yoyo1
    Nov 15 '18 at 2:44











  • I was wrong in my first try. They were right. I fixed it.

    – bluejack
    Nov 15 '18 at 2:45











  • But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

    – yoyo1
    Nov 15 '18 at 2:47











  • "/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

    – Swordfish
    Nov 15 '18 at 2:47








  • 1





    Okay I implemented this functionality and it appears to work for me. Thanks!

    – yoyo1
    Nov 15 '18 at 3:23



















  • Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

    – yoyo1
    Nov 15 '18 at 2:44











  • I was wrong in my first try. They were right. I fixed it.

    – bluejack
    Nov 15 '18 at 2:45











  • But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

    – yoyo1
    Nov 15 '18 at 2:47











  • "/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

    – Swordfish
    Nov 15 '18 at 2:47








  • 1





    Okay I implemented this functionality and it appears to work for me. Thanks!

    – yoyo1
    Nov 15 '18 at 3:23

















Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

– yoyo1
Nov 15 '18 at 2:44





Why did other guys say char* is immutable, but then you modify it by doing exampleString[i] = ?

– yoyo1
Nov 15 '18 at 2:44













I was wrong in my first try. They were right. I fixed it.

– bluejack
Nov 15 '18 at 2:45





I was wrong in my first try. They were right. I fixed it.

– bluejack
Nov 15 '18 at 2:45













But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

– yoyo1
Nov 15 '18 at 2:47





But isn't that same thing? "char* formatString" that is still char* type, which I thought we can't modify

– yoyo1
Nov 15 '18 at 2:47













"/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

– Swordfish
Nov 15 '18 at 2:47







"/* Can you see why I might do this? */" unless you do it for obfuscation, you do it in the wrong place.

– Swordfish
Nov 15 '18 at 2:47






1




1





Okay I implemented this functionality and it appears to work for me. Thanks!

– yoyo1
Nov 15 '18 at 3:23





Okay I implemented this functionality and it appears to work for me. Thanks!

– yoyo1
Nov 15 '18 at 3:23


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53311499%2fc-replace-in-string-with-id-from-getpid%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Danny Elfman

Lugert, Oklahoma