This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 6 years ago.
I have been working on a project where I need to convert an int8_t variable to a string. I did a bit of reading on this and came to a conclusion that using Strint(int8_t) is an option.
Here is my code:
int8_t matt = 0;
matt += 1;
char string[3]=String(matt);
tft.textWrite(string);// this is used to display text on an lcd display (arduino)
For some reason the method I used did not work so I researched a bit more and found out String(matt) is actually a String object. I don't really know if this is true for a fact. In order for the tft.textWrite(); to work it should look something like this.
Here is the code:
char string[15]= "Hello, World! ";
tft.textWrite(string);
I tried using this also:
char string[3];
sprintf(string, "%ld", matt);
However this did not work.
Can anybody help?
Thanks
It should work fine.
sprintf(string, "%ld", matt);
%ld is used for long int. you are using int8_t which is of range -128 to +128, it is better to use %d.
This code is nearly right
char string[3];
sprintf(string, "%ld", matt);
first
"%ld"
expects a long int as a type you need to find one that can print an 8 bit int. I think its "%hh".
second your
char string[3];
is too short! what if matt is 100 then you use 3 chars but you still need room for the ending zero (and sign). So it should be at least
char string[5];
third the code
sprintf(string, "%ld", matt);
is unsafe as it can write beyond the end of string as it would in your original code, use
snprintf(string, sizeof(string), "%ld", matt);
First you have to keep in mind that there is no String type in C, only fixed sized char arrays (type: char* or char[]). We still call them strings, but keep that in mind.
Your attempt with sprintf looked good to me. Are you shure your environment includes the full C Standard Library ? If not, you will have to code your own format function. If yes, have you included string.h ?
Anyway, try to use snprintf() to precise the size of the target, it is safer.
EDIT: This post applies to the good ol' C style, which I did not see was off topic
the following code should work:
// Example program
#include <iostream>
#include <string>
int main()
{
int8_t matt = 0;
matt += 1;
char string[1];
sprintf(string, "%ld", matt);
std::cout << string << std::endl;
return 0;
}
it prints "1".
Related
I have bitset<8> v8 and its value is something like "11001101", how can I convert it to char? I need a single letter. Like letter "f"=01100110.
P.S. Thanks for help. I needed this to illustrate random errors in bits. For example without error f, and with error something like ♥, and so on with all text in file. In text you can see such errors clearly.
unsigned long i = mybits.to_ulong();
unsigned char c = static_cast<unsigned char>( i ); // simplest -- no checks for 8 bit bitsets
Something along the lines of the above should work. Note that the bit field may contain a value that cannot be represented using a plain char (it is implementation defined whether it is signed or not) -- so you should always check before casting.
char c;
if (i <= CHAR_MAX)
c = static_cast<char>( i );
The provided solution did not work for me. I was using C++14 with g++ 9. However, I was able to get it working by :
char lower = 'a';
bitset<8> upper(lower);
upper.reset(5);
cout << (char)upper.to_ulong() << endl;
This may not be the best way to do it, I am sure, but it worked for me!
Let me make this clear right away, this is for a college class. I cannot use C++ libraries, only standard C libraries. Do not suggest that I use C++ strings or cin/cout because that will not help me for this assignment.
My issue: I have global character arrays in the main function. I need to pass strings to the global character arrays from scanf() in a function foo(). Everything compiles fine, the issue is, the scanf() function seems to have no affect on the global character arrays that it points to. I'm using the "address of" operator (&) as the reference books indicate to do. Perhaps, I'm not understanding the relationship between the character array pointer and the scanf() "address of" (&). I feel I've looked everywhere for a solution.
I've spent several hours on this issue so I'm now looking for expert advice.
Here is a simplified version of my program.
#include <stdio.h>
void foo(char arr1[], char arr2[]);
int main(void)
{
char arr1[20] = "initial";
char arr2[25] = "second";
foo(arr1); // <------- should change it to the string "second" upon scanf()
printf("Test Return Value: %s\n",arr1); // <---- returns "initial" (the problem)
printf("Enter a test value: ");
scanf("%s", &arr1);
printf("Test Return Value: %s\n",&arr1);
// ---------------------- this code is not part of the issue
fflush(stdin);
getchar();
return 0;
// ----------------------
}
void foo(char arr1[], char arr2[])
{
// there will be many returned values
printf("Enter a test value: ");
scanf("%s", &arr1); // <---------- the problem function (input < 20 chars)
}
scanf("%s", &arr); // <---------- the problem function (input < 20 chars)
should be
scanf("%s", arr); // <---------- the problem function (input < 20 chars)
The perils of using the C io functions!
Although you have updated saying solved I have a few observation which you might want to consider:
1. Get rid of & before arr1 in scanf & printf calls (which has solved your problem as mentioned by Ayjay & Dennis)
2. Correct number of parameters not passed to function foo (as mentioned by Adrian Cornish). Thus code will not compile.
3. fflush(stdin); is undefined behavior. fflush is only for output streams. Please don't use it with stdin. Refer this SO question for details.
4. If this is a C++ source please use #include <cstdio> instead of #include <stdio.h>
Always compile code with full compiler warnings and resolve all of them. It is a good practice. :)
Hope this helps!
The correct syntax for the scanf function is:
scanf("%s", arr);
You only need the & operator for simple variables, not for arrays / pointers.
Besides of that, you will have to correct the improper use of arr1, arr2 and arr. Parts of your code make use of the first two arrays, others of the latter.
I'm having a bit of a problem with this piece of code:
string StringServices::ToStringf(float value)
{
char buffer[10];
sprintf (buffer, "%f", value);
return (string) buffer; // signal SIGABRT
}
Its been working previously and continues to work for other calls, but I currently get a SIGABRT on the return, when the function is being passed -211.0
The buffer loads up fine, and I'm really not sure why this isn't working. Can someone who understands std::string and c strings a lot better then me help me out here?
You probably overflowed your buffer because you're not using snprintf. You have this tagged C++ so do it that way:
std::string buffer = boost::lexical_cast<std::string>(value);
Or without boost use a string stream:
std::ostringstream os;
os << value;
// os.str() has the string representation now.
The main problem with C and its string functions is that you have to do too much work manually. You also have to make too many decisions when you write in C. One of the trivial issues is buffer overflow. Consider this code:
char buf[5]; // 5 chars, ok
sprintf(buf, "qwert"); // 5 letters, ok
You're going to have problems with this code, since when talking about strings, 5 chars means 4 letters + '\0'. So, you may try:
printf("'%s'\n", buf); // you'll probably get 'qwertIOUYOIY*&T^*&TYDGKUYTU&*#*#T^&#$T67...'
What you do with your code is a trivial buffer overflow :-)
sprintf() just has no way to check the size of buf, so a piece of memory that goes right after buf can get corrupted.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to convert a single char into an int
Well, I'm doing a basic program, wich handles some input like:
2+2
So, I need to add 2 + 2.
I did something like:
string mys "2+2";
fir = mys[0];
sec = mys[2];
But now I want to add "fir" to "sec", so I need to convert them to Int.
I tried "int(fir)" but didn't worked.
There are mulitple ways of converting a string to an int.
Solution 1: Using Legacy C functionality
int main()
{
//char hello[5];
//hello = "12345"; --->This wont compile
char hello[] = "12345";
Printf("My number is: %d", atoi(hello));
return 0;
}
Solution 2: Using lexical_cast(Most Appropriate & simplest)
int x = boost::lexical_cast<int>("12345");
Solution 3: Using C++ Streams
std::string hello("123");
std::stringstream str(hello);
int x;
str >> x;
if (!str)
{
// The conversion failed.
}
Alright so first a little backround on why what you attempted didn't work. In your example, fir is declared as a string. When you attempted to do int(fir), which is the same as (int)fir, you attempted a c-style cast from a string to an integer. Essentially you will get garbage because a c-style cast in c++ will run through all of the available casts and take the first one that works. At best your going to get the memory value that represents the character 2, which is dependent upon the character encoding your using (UTF-8, ascii etc...). For instance, if fir contained "2", then you might possibly get 0x32 as your integer value (assuming ascii). You should really never use c-style casts, and the only place where it's really safe to use them are conversions between numeric types.
If your given a string like the one in your example, first you should separate the string into the relevant sequences of characters (tokens) using a function like strtok. In this simple example that would be "2", "+" and "2". Once you've done that you can simple call a function such as atoi on the strings you want converted to integers.
Example:
string str = "2";
int i = atoi(str.c_str()); //value of 2
However, this will get slightly more complicated if you want to be able to handle non-integer numbers as well. In that case, your best bet is to separate on the operand (+ - / * etc), and then do a find on the numeric strings for a decimal point. If you find one you can treat it as a double and use the function atof instead of atoi, and if you don't, just stick with atoi.
Have you tried atoi or boost lexical cast?
This question already has answers here:
C++: how to get fprintf results as a std::string w/o sprintf
(8 answers)
Closed 5 years ago.
Does anyone know a good safe way to redirect the output of a printf-style function to a string? The obvious ways result in buffer overflows.
Something like:
string s;
output.beginRedirect( s ); // redirect output to s
... output.print( "%s%d", foo, bar );
output.endRedirect();
I think the problem is the same as asking, "how many characters will print produce?"
Ideas?
You can use:
std::snprintf if you are working with a char*
std::stringstream if you want to use strings (not same as printf but will allow you to easily manipulate the string using the normal stream functions).
boost::format if you want a function similar to printf that will work with streams. (as per jalf in comments)
fmt::format which is has been standardized since c++20 std::format
The snprintf() function prints to a string, but only as much as the length given to it.
Might be what you're looking for...
The fmt library provides fmt::sprintf function that performs printf-compatible formatting (including positional arguments according to POSIX specification) and returns the result as an std::string:
std::string s = fmt::sprintf( "%s%d", foo, bar );
Disclaimer: I'm the author of this library.
Since you've tagged this as C++ (rather than just C), I'll point out that the typical way to do this sort of thing in C++ is to use stringstream, not the printf family. No need to worry about buffer overflows with stringstreams.
The Boost Format library is also available if you like printf-style format strings but want something safer.
snprintf() returns the number of bytes needed to write the whole string.
So, as a tiny example:
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char* buf = 0;
size_t bufsize = 0;
size_t sz;
const char* format="%s and %s.";
const char* str_1 ="string 1";
const char* str_2 ="string 2";
sz = snprintf(buf, bufsize, format, str_1, str_2);
printf("The buffer needs to be %d bytes.\n", sz);
buf=malloc(sz+1);
if(!buf) {
printf("Can't allocate buffer!\n");
return 1;
}
bufsize = sz+1;
buf[bufsize-1] = '\0';
sz = snprintf(buf, bufsize, format, str_1, str_2);
printf("Filled buffer with %d bytes.\n", sz);
printf("The buffer contains:\n'%s'\n", buf);
return 0;
}
output:
The buffer needs to be 22 bytes.
Filled buffer with 22 bytes.
The buffer contains:
'string 1 and string 2.'
This StackOverflow question has a similar discussion. Also in that question I present my favorite solution, a "format" function that takes identical arguments to printf and returns a std::string.
Old school:
snprintf()
allows you to put a limit on the number written, and return the actual written size, and
asprintf()
allocate (with malloc()) a sufficient buffer which then becomes your problem to free(). `asprintf is a GNU libc function now reimplemented in the BSD libc.
With C99 you have the snprintf-function which takes the size of the buffer as a parameter. The GNU C-library has asprintf which allocates a buffer for you. For c++ though, you might be better of using iostream.
Wikipedia has more info.
I find the printf formatting to be very helpful and easier to use than streams. On the other hand, I do like std::string a lot too. The solution is to use sprintf, but that cannot handle arbitrary buffer size.
I've found that I need to handle common case (say, buffer limited to 256 chars) w/o
overhead, and yet handle the large buffer safely. To do that, I have a buffer of 256 chars alocated in my class as a member, and I use snprinf, passing that buffer and its size. If snprintf succeeds, I can immediately retunr the formatted string. If it fails, I allocate the buffer and call snprinf again. The buffer is deallocated in the class' destructor.
On Windows:
StringCchPrintf
StringCbPrintf
from strsafe.h/lib.
Microsoft introduce the 'safe' crt functions for this.
You could use printf_s()