How to get the last characters of formatted output when snprintf returns more than its size argument?
I have a buffer that is 65536 characters long. I need to print formatted output to the buffer. Problem is: If the formatted output size turns out to be bigger than 65535, I would like to have the last characters of it in the buffer, discarding the first ones, and not the remaining ones, as snprintf
does.
I thought about implementing the snprintf
logic, but starting from the end of the string instead of the beginning.
Is there any easier way to accomplish this?
c printf
|
show 9 more comments
I have a buffer that is 65536 characters long. I need to print formatted output to the buffer. Problem is: If the formatted output size turns out to be bigger than 65535, I would like to have the last characters of it in the buffer, discarding the first ones, and not the remaining ones, as snprintf
does.
I thought about implementing the snprintf
logic, but starting from the end of the string instead of the beginning.
Is there any easier way to accomplish this?
c printf
What are you doing that could possibly need more than 65535 characters in a single formatted output?
– Barmar
Jan 18 at 21:48
1
Consider dynamically allocating if you're unsure of how much storage you need. If you guess wrong you can reallocate.
– tadman
Jan 18 at 21:49
1
Can you show an example of the format string? I assume it must be printing a potentially long string. So you could split it up into separate calls, for everything before the string, and everything after the string. Then you add the lengths of each of these to the length of the string, and see whether it's longer than 65535.
– Barmar
Jan 18 at 21:52
@Barmar I'm writing my own terminal. I haven't thought about examples of my program where that could happen. Currently, I'm writing a function that sends data to be printed to the terminal, and can be formatted. What if the buffer size was smaller? "Declare bigger buffers" can't be a solution to every instance of this problem :P
– Yuri J
Jan 18 at 22:01
2
@Barmar By doing that, you're formatting the entirety of the data anyway. At that point you might as well do it the easy way and just use something likeasprintf()
to start.
– Andrew Henle
Jan 18 at 22:02
|
show 9 more comments
I have a buffer that is 65536 characters long. I need to print formatted output to the buffer. Problem is: If the formatted output size turns out to be bigger than 65535, I would like to have the last characters of it in the buffer, discarding the first ones, and not the remaining ones, as snprintf
does.
I thought about implementing the snprintf
logic, but starting from the end of the string instead of the beginning.
Is there any easier way to accomplish this?
c printf
I have a buffer that is 65536 characters long. I need to print formatted output to the buffer. Problem is: If the formatted output size turns out to be bigger than 65535, I would like to have the last characters of it in the buffer, discarding the first ones, and not the remaining ones, as snprintf
does.
I thought about implementing the snprintf
logic, but starting from the end of the string instead of the beginning.
Is there any easier way to accomplish this?
c printf
c printf
edited Jan 18 at 22:37
Yuri J
asked Jan 18 at 21:46
Yuri JYuri J
947
947
What are you doing that could possibly need more than 65535 characters in a single formatted output?
– Barmar
Jan 18 at 21:48
1
Consider dynamically allocating if you're unsure of how much storage you need. If you guess wrong you can reallocate.
– tadman
Jan 18 at 21:49
1
Can you show an example of the format string? I assume it must be printing a potentially long string. So you could split it up into separate calls, for everything before the string, and everything after the string. Then you add the lengths of each of these to the length of the string, and see whether it's longer than 65535.
– Barmar
Jan 18 at 21:52
@Barmar I'm writing my own terminal. I haven't thought about examples of my program where that could happen. Currently, I'm writing a function that sends data to be printed to the terminal, and can be formatted. What if the buffer size was smaller? "Declare bigger buffers" can't be a solution to every instance of this problem :P
– Yuri J
Jan 18 at 22:01
2
@Barmar By doing that, you're formatting the entirety of the data anyway. At that point you might as well do it the easy way and just use something likeasprintf()
to start.
– Andrew Henle
Jan 18 at 22:02
|
show 9 more comments
What are you doing that could possibly need more than 65535 characters in a single formatted output?
– Barmar
Jan 18 at 21:48
1
Consider dynamically allocating if you're unsure of how much storage you need. If you guess wrong you can reallocate.
– tadman
Jan 18 at 21:49
1
Can you show an example of the format string? I assume it must be printing a potentially long string. So you could split it up into separate calls, for everything before the string, and everything after the string. Then you add the lengths of each of these to the length of the string, and see whether it's longer than 65535.
– Barmar
Jan 18 at 21:52
@Barmar I'm writing my own terminal. I haven't thought about examples of my program where that could happen. Currently, I'm writing a function that sends data to be printed to the terminal, and can be formatted. What if the buffer size was smaller? "Declare bigger buffers" can't be a solution to every instance of this problem :P
– Yuri J
Jan 18 at 22:01
2
@Barmar By doing that, you're formatting the entirety of the data anyway. At that point you might as well do it the easy way and just use something likeasprintf()
to start.
– Andrew Henle
Jan 18 at 22:02
What are you doing that could possibly need more than 65535 characters in a single formatted output?
– Barmar
Jan 18 at 21:48
What are you doing that could possibly need more than 65535 characters in a single formatted output?
– Barmar
Jan 18 at 21:48
1
1
Consider dynamically allocating if you're unsure of how much storage you need. If you guess wrong you can reallocate.
– tadman
Jan 18 at 21:49
Consider dynamically allocating if you're unsure of how much storage you need. If you guess wrong you can reallocate.
– tadman
Jan 18 at 21:49
1
1
Can you show an example of the format string? I assume it must be printing a potentially long string. So you could split it up into separate calls, for everything before the string, and everything after the string. Then you add the lengths of each of these to the length of the string, and see whether it's longer than 65535.
– Barmar
Jan 18 at 21:52
Can you show an example of the format string? I assume it must be printing a potentially long string. So you could split it up into separate calls, for everything before the string, and everything after the string. Then you add the lengths of each of these to the length of the string, and see whether it's longer than 65535.
– Barmar
Jan 18 at 21:52
@Barmar I'm writing my own terminal. I haven't thought about examples of my program where that could happen. Currently, I'm writing a function that sends data to be printed to the terminal, and can be formatted. What if the buffer size was smaller? "Declare bigger buffers" can't be a solution to every instance of this problem :P
– Yuri J
Jan 18 at 22:01
@Barmar I'm writing my own terminal. I haven't thought about examples of my program where that could happen. Currently, I'm writing a function that sends data to be printed to the terminal, and can be formatted. What if the buffer size was smaller? "Declare bigger buffers" can't be a solution to every instance of this problem :P
– Yuri J
Jan 18 at 22:01
2
2
@Barmar By doing that, you're formatting the entirety of the data anyway. At that point you might as well do it the easy way and just use something like
asprintf()
to start.– Andrew Henle
Jan 18 at 22:02
@Barmar By doing that, you're formatting the entirety of the data anyway. At that point you might as well do it the easy way and just use something like
asprintf()
to start.– Andrew Henle
Jan 18 at 22:02
|
show 9 more comments
1 Answer
1
active
oldest
votes
A solution is :
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
int snprintfEnd(char *str, size_t size, const char *format, ...)
{
va_list ap1, ap2;
va_start(ap1, format);
va_copy(ap2, ap1);
/* get length of all */
int sz = vsnprintf(0, 0, format, ap2);
va_end(ap2);
/* get all */
char * all = malloc(sz + 1);
vsprintf(all, format, ap1);
va_end(ap1);
/* copy the expected part */
int r;
if (sz < size) {
strcpy(str, all);
r = sz;
}
else {
strcpy(str, all + sz - size);
r = size;
}
free(all);
return r;
}
int main()
{
char s[6];
int ln = snprintfEnd(s, 5, "%d %d %d", 1, 234, 567);
printf("%d : '%s'n", ln, s);
return 0;
}
Execution :
5 : '4 567'
size_t size
insnprintfEnd()
is begin used as the max string length (without the null character). IMO,snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should usesize
as the size of the destination allowed including the null character and thens
becomes"4 56"
that needs 5char
.
– chux
Jan 18 at 23:57
Such excessively long uses of*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that fromint sz = vsnprintf()
would be prudent.
– chux
Jan 19 at 0:07
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54261854%2fhow-to-get-the-last-characters-of-formatted-output-when-snprintf-returns-more-th%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
A solution is :
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
int snprintfEnd(char *str, size_t size, const char *format, ...)
{
va_list ap1, ap2;
va_start(ap1, format);
va_copy(ap2, ap1);
/* get length of all */
int sz = vsnprintf(0, 0, format, ap2);
va_end(ap2);
/* get all */
char * all = malloc(sz + 1);
vsprintf(all, format, ap1);
va_end(ap1);
/* copy the expected part */
int r;
if (sz < size) {
strcpy(str, all);
r = sz;
}
else {
strcpy(str, all + sz - size);
r = size;
}
free(all);
return r;
}
int main()
{
char s[6];
int ln = snprintfEnd(s, 5, "%d %d %d", 1, 234, 567);
printf("%d : '%s'n", ln, s);
return 0;
}
Execution :
5 : '4 567'
size_t size
insnprintfEnd()
is begin used as the max string length (without the null character). IMO,snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should usesize
as the size of the destination allowed including the null character and thens
becomes"4 56"
that needs 5char
.
– chux
Jan 18 at 23:57
Such excessively long uses of*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that fromint sz = vsnprintf()
would be prudent.
– chux
Jan 19 at 0:07
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
add a comment |
A solution is :
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
int snprintfEnd(char *str, size_t size, const char *format, ...)
{
va_list ap1, ap2;
va_start(ap1, format);
va_copy(ap2, ap1);
/* get length of all */
int sz = vsnprintf(0, 0, format, ap2);
va_end(ap2);
/* get all */
char * all = malloc(sz + 1);
vsprintf(all, format, ap1);
va_end(ap1);
/* copy the expected part */
int r;
if (sz < size) {
strcpy(str, all);
r = sz;
}
else {
strcpy(str, all + sz - size);
r = size;
}
free(all);
return r;
}
int main()
{
char s[6];
int ln = snprintfEnd(s, 5, "%d %d %d", 1, 234, 567);
printf("%d : '%s'n", ln, s);
return 0;
}
Execution :
5 : '4 567'
size_t size
insnprintfEnd()
is begin used as the max string length (without the null character). IMO,snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should usesize
as the size of the destination allowed including the null character and thens
becomes"4 56"
that needs 5char
.
– chux
Jan 18 at 23:57
Such excessively long uses of*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that fromint sz = vsnprintf()
would be prudent.
– chux
Jan 19 at 0:07
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
add a comment |
A solution is :
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
int snprintfEnd(char *str, size_t size, const char *format, ...)
{
va_list ap1, ap2;
va_start(ap1, format);
va_copy(ap2, ap1);
/* get length of all */
int sz = vsnprintf(0, 0, format, ap2);
va_end(ap2);
/* get all */
char * all = malloc(sz + 1);
vsprintf(all, format, ap1);
va_end(ap1);
/* copy the expected part */
int r;
if (sz < size) {
strcpy(str, all);
r = sz;
}
else {
strcpy(str, all + sz - size);
r = size;
}
free(all);
return r;
}
int main()
{
char s[6];
int ln = snprintfEnd(s, 5, "%d %d %d", 1, 234, 567);
printf("%d : '%s'n", ln, s);
return 0;
}
Execution :
5 : '4 567'
A solution is :
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
int snprintfEnd(char *str, size_t size, const char *format, ...)
{
va_list ap1, ap2;
va_start(ap1, format);
va_copy(ap2, ap1);
/* get length of all */
int sz = vsnprintf(0, 0, format, ap2);
va_end(ap2);
/* get all */
char * all = malloc(sz + 1);
vsprintf(all, format, ap1);
va_end(ap1);
/* copy the expected part */
int r;
if (sz < size) {
strcpy(str, all);
r = sz;
}
else {
strcpy(str, all + sz - size);
r = size;
}
free(all);
return r;
}
int main()
{
char s[6];
int ln = snprintfEnd(s, 5, "%d %d %d", 1, 234, 567);
printf("%d : '%s'n", ln, s);
return 0;
}
Execution :
5 : '4 567'
answered Jan 18 at 22:22
brunobruno
4,7111921
4,7111921
size_t size
insnprintfEnd()
is begin used as the max string length (without the null character). IMO,snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should usesize
as the size of the destination allowed including the null character and thens
becomes"4 56"
that needs 5char
.
– chux
Jan 18 at 23:57
Such excessively long uses of*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that fromint sz = vsnprintf()
would be prudent.
– chux
Jan 19 at 0:07
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
add a comment |
size_t size
insnprintfEnd()
is begin used as the max string length (without the null character). IMO,snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should usesize
as the size of the destination allowed including the null character and thens
becomes"4 56"
that needs 5char
.
– chux
Jan 18 at 23:57
Such excessively long uses of*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that fromint sz = vsnprintf()
would be prudent.
– chux
Jan 19 at 0:07
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
size_t size
in snprintfEnd()
is begin used as the max string length (without the null character). IMO, snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should use size
as the size of the destination allowed including the null character and then s
becomes "4 56"
that needs 5 char
.– chux
Jan 18 at 23:57
size_t size
in snprintfEnd()
is begin used as the max string length (without the null character). IMO, snprintfEnd(s, 5, "%d %d %d", 1, 234, 567)
should use size
as the size of the destination allowed including the null character and then s
becomes "4 56"
that needs 5 char
.– chux
Jan 18 at 23:57
Such excessively long uses of
*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that from int sz = vsnprintf()
would be prudent.– chux
Jan 19 at 0:07
Such excessively long uses of
*print()
are prone to Environmental limits. C11 §7.21.6.1 15. This may be a case where "fprintf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.". So checking for that from int sz = vsnprintf()
would be prudent.– chux
Jan 19 at 0:07
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
@chux yes I do not follow the same rule for size, but whatever because without news from the OP I will probably destruct that wasted answer
– bruno
Jan 19 at 8:32
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54261854%2fhow-to-get-the-last-characters-of-formatted-output-when-snprintf-returns-more-th%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
What are you doing that could possibly need more than 65535 characters in a single formatted output?
– Barmar
Jan 18 at 21:48
1
Consider dynamically allocating if you're unsure of how much storage you need. If you guess wrong you can reallocate.
– tadman
Jan 18 at 21:49
1
Can you show an example of the format string? I assume it must be printing a potentially long string. So you could split it up into separate calls, for everything before the string, and everything after the string. Then you add the lengths of each of these to the length of the string, and see whether it's longer than 65535.
– Barmar
Jan 18 at 21:52
@Barmar I'm writing my own terminal. I haven't thought about examples of my program where that could happen. Currently, I'm writing a function that sends data to be printed to the terminal, and can be formatted. What if the buffer size was smaller? "Declare bigger buffers" can't be a solution to every instance of this problem :P
– Yuri J
Jan 18 at 22:01
2
@Barmar By doing that, you're formatting the entirety of the data anyway. At that point you might as well do it the easy way and just use something like
asprintf()
to start.– Andrew Henle
Jan 18 at 22:02