C++ - "snprintf" inside "for" doesn't work as expected. (int to char*)
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I need to convert an int array into a char* array.
I'm using the following code:
Code:
for (int x = 0; x < 8; x++) {
snprintf(buffer,32,"%d\0", x);
y[x]=buffer;
}
for (int x = 0; x < 8; x++) {
cout<<y[x]<<endl;
}
but it returns me
Code:
7
7
7
7
7
7
7
7
and I can't fix it.
Can someone help me please?
Thanks in advance.
What did you mean to do by the item in red ? How about seeing the whole code ? Did you use '-Wall -Wextra -Wformat=2 -O2' during compilation ? If yes, were there any warnings ?
snprintf change the content of "buffer": it fill each case with the string representation of "x" (i'm assuming buffer is defined as "char buffer[32]" or equivalent).
so each round of your "for" loop, "buffer" is over written _AND_ "y[x]=buffer;" just copy the address of the "buffer" array (the position of its 1st char in memory), i'm assuming here that "y" is defined as "char* y[8]" or similar. This address doesn't change, its content does.
Then the 2nd "for" loop just display the content of the x'th address "y[x]" (="buffer" content).
REMARK: if your coding in C++, use C++ string object and methods. If you're sing pure C, use "printf" not "cout". MixingC and C++ is a bad habbit.
for (int x = 0; x < 8; x++) {
snprintf(buffer,32,"%d\0", x);
y[x]=buffer;
}
for (int x = 0; x < 8; x++) {
cout<<y[x]<<endl;
}
I think there are some fundamental flaws in the way you're using arrays. For example, "snprintf(buffer,32,"%d\0", x);" is always printing to the first element of buffer (you probably want "buffer[x]") and similarly "y[x]=buffer;" is always reading from the first element of the buffer (again, you probably want "buffer[x]") giving the (correct) printed result.
By making these two changes, your code will probably work, but if you don't understand why then you really need to read-up on arrays and pointers.
What did you mean to do by the item in red ? How about seeing the whole code ? Did you use '-Wall -Wextra -Wformat=2 -O2' during compilation ? If yes, were there any warnings ?
It is meant to copy the buffer value into different items of the y array (of chars).
Code:
#include <ncurses.h>
#include <menu.h>
#include <iostream>
using namespace std;
char buffer [16];
char *y[32];
int main() {
for (int x = 0; x < 8; x++) {
snprintf(buffer,32,"%d\0", x);
y[x]=buffer;
}
for (int x = 0; x < 8; x++) {
cout<<y[x]<<endl;
}
}
Command: g++ -o bin main.cpp -Wall -Wextra -Wformat=2 -O2
Output:
Code:
main.cpp: In function int main():
main.cpp:13: warning: embedded \0 in format
main.cpp:13: warning: embedded \0 in format
In file included from /usr/include/stdio.h:910,
from /usr/include/ncurses.h:141,
from main.cpp:1:
In function int snprintf(char*, size_t, const char*, ...),
inlined from int main() at main.cpp:13:
/usr/include/bits/stdio2.h:66: warning: call to int __builtin___snprintf_chk(char*, unsigned int, int, unsigned int, const char*, ...) will always overflow destination buffer
How do you define the "buffer value" ? I.e. you describe 'buffer' as
Code:
char buffer [16];
- in "C" this means an array of 16 elements, each element type is 'char'. So, how do you define the "buffer value" in terms of the array and its elements ?
snprintf change the content of "buffer": it fill each case with the string representation of "x" (i'm assuming buffer is defined as "char buffer[32]" or equivalent).
so each round of your "for" loop, "buffer" is over written _AND_ "y[x]=buffer;" just copy the address of the "buffer" array (the position of its 1st char in memory), i'm assuming here that "y" is defined as "char* y[8]" or similar. This address doesn't change, its content does.
Then the 2nd "for" loop just display the content of the x'th address "y[x]" (="buffer" content).
REMARK: if your coding in C++, use C++ string object and methods. If you're sing pure C, use "printf" not "cout". MixingC and C++ is a bad habbit.
So... why the last -not the first- value of x is displayed for the first y that was set when x was 0?
Quote:
Originally Posted by JohnGraham
I think there are some fundamental flaws in the way you're using arrays. For example, "snprintf(buffer,32,"%d\0", x);" is always printing to the first element of buffer (you probably want "buffer[x]") and similarly "y[x]=buffer;" is always reading from the first element of the buffer (again, you probably want "buffer[x]") giving the (correct) printed result.
By making these two changes, your code will probably work, but if you don't understand why then you really need to read-up on arrays and pointers.
I understand, however, if the buffer isn't set as array, i get segfault, even if i use something like "sprintf(y[x], "%d", x);" i get segfaults.
I just want to convert an array of integers into an array of chars so i can use it on ncurses menus (i'm learning ncurses).I though it was going to be a very simple thing.
Thanks.
Last edited by Repgahroll; 08-30-2010 at 03:54 PM.
main.cpp: In function ‘int main()’:
main.cpp:13: warning: embedded ‘\0’ in format
main.cpp:13: warning: embedded ‘\0’ in format
In file included from /usr/include/stdio.h:910,
from /usr/include/ncurses.h:141,
from main.cpp:1:
In function ‘int snprintf(char*, size_t, const char*, ...)’,
inlined from ‘int main()’ at main.cpp:13:
/usr/include/bits/stdio2.h:66: warning: call to int __builtin___snprintf_chk(char*, unsigned int, int, unsigned int, const char*, ...) will always overflow destination buffer
Thank you.
You need to make your code such it produces no warnings. The item in red is really grave.
C beginners usually get confused by the lack of support in C for strings.
In C, you typically use arrays of characters instead of strings. But an array of characters is nowhere near as easy to use as a string. You need to understand all the basic concepts of arrays and pointers in C.
This is one thing that makes C++ a better beginner language. Beginners tend to write things that need strings before they learn enough to understand pointers and arrays. C++ has a string class.
Quote:
Originally Posted by Repgahroll
It is meant to copy the buffer value into different items of the y array (of chars).
Code:
char buffer [16];
char *y[32];
Because buffer is an array, its name does not refer to its contents (the array of characters). Its name refers to the address of the first character.
The y you declared is not an array of characters. It is an array of character pointers.
Code:
y[x]=buffer;
So that doesn't copy the contents of the buffer. It copies the address of the buffer.
Since you said "C++" not "C". Maybe you don't need to learn so much about using character arrays instead of strings. Maybe you can mostly use strings.
snprintf would still need a character array for its destination. I'm not sure whether it is worth looking for a more C++ appropriate substitute for snprintf.
You mentioned your target is ncurses, which is based on a C interface. I don't know whether its C++ bindings make it support C++ well (strings etc.) or whether you still need char arrays there.
But even if you need char arrays at the start and end of the life of each string, you still might be less confused if you use strings in between.
Instead of
char *y[32];
try
std::string y[32];
(You'll need #include <string> at the top of your file)
Then when you do
y[x]=buffer;
it would really mean copy the contents of the buffer as you intend, rather than store the address.
#include <iostream>
#include <stdio.h>
using namespace std;
char *y;
int x = 32;
int main() {
sprintf(y, "%d", x);
cout<<y<<endl;
}
is returning segfault. what's wrong with it?
The word "pointer" in programming originates from the verb "to point to".
The wrong thing with the program is that you haven't asked yourself the question: "Where does the 'char *y' pointer point to ?".
Had you used 'Wall -Wextra -Wformat=2 -O2' during compilation, you would have seen warnings about 'y' being uninitialized. 'y' has a random/garbage value and thus points to a random memory location, and that causes segmentation fault.
I suggest to pick any C/C++ tutorial and learn about pointers first.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.