I am using the following code to convert Const char * to Unsigned long int, but the output is always 0. Where am I doing wrong? Please let me know.
Here is my code:
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
int main()
{
vector<string> tok;
tok.push_back("2");
const char *n = tok[0].c_str();
unsigned long int nc;
char *pEnd;
nc=strtoul(n,&pEnd,1);
//cout<<n<<endl;
cout<<nc<<endl; // it must output 2 !?
return 0;
}
Use base-10:
nc=strtoul(n,&pEnd,10);
or allow the base to be auto-detected:
nc=strtoul(n,&pEnd,0);
The third argument to strtoul is the base to be used and you had it as base-1.
You need to use:
nc=strtoul(n,&pEnd,10);
You used base=1 that means only zeroes are allowed.
If you need info about integer bases you can read this
The C standard library function strtoul takes as its third argument the base/radix of the number system to be used in interpreting the char array pointed to by the first argument.
Where am I doing wrong?
nc=strtoul(n,&pEnd,1);
You're passing the base as 1, which leads to a unary numeral system i.e. the only number that can be repesented is 0. Hence you'd get only that as the output. If you need decimal system interpretation, pass 10 instead of 1.
Alternatively, passing 0 lets the function auto-detect the system based on the prefix: if it starts with 0 then it is interpreted as octal, if it is 0x or 0X it is taken as hexadecimal, if it has other numerals it is assumed as decimal.
Aside:
If you don't need to know the character upto which the conversion was considered then passing a dummy second parameter is not required; you can pass NULL instead.
When you're using a C standard library function in a C++ program, it's recommended that you include the C++ version of the header; with the prefix c, without the suffix .h e.g. in your case, it'd be #include <cstdlib>
using namespace std; is considered bad practice
Related
Im using this atoi to remove all letters from the string. But my string uses special characters as seen below, because of this my atoi exits with an error. What should I do to solve this?
#include <iostream>
#include <string>
using namespace std;
int main() {
std::string playerPickS = "Klöver 12"; // string with special characters
size_t i = 0;
for (; i < playerPickS.length(); i++) { if (isdigit(playerPickS[i])) break; }
playerPickS = playerPickS.substr(i, playerPickS.length() - i); // convert the remaining text to an integer
cout << atoi(playerPickS.c_str());
}
This is what I believe is the error. I only get this when using those special characters, thats why I think thats my problem.
char can be signed or unsigned, but isidigt without a locale overload expects a positive number (or EOF==-1). In your encoding 'ö' has a negative value. You can cast it to unsigned char first: is_digit(static_cast<unsigned char>(playerPickS[i])) or use the locale-aware variant.
atoi stops scanning when it finds something that's not a digit (roughly speaking). So, to get it to do what you want, you have to feed it something that at least starts with the string you want to convert.
From the documentation:
[atoi] Discards any whitespace characters until the first non-whitespace character is found, then takes as many characters as possible to form a valid integer number representation and converts them to an integer value. The valid integer value consists of the following parts:
(optional) plus or minus sign
numeric digits
So, now you know how atoi works, you can pre-process your string appropriately before passing it in. Good luck!
Edit: If your call to isdigit is failing to yield the desired result, the clue lies here:
The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.
So you need to check for that yourself before you call it. Casting playerPickS[i] to an unsigned int will probably work.
This is the code I wrote to convert integer to string.
#include <iostream>
using namespace std;
int main()
{
string s;
int b=5;
s.push_back((char)b);
cout<<s<<endl;
}
I expected the output to be 5 but it is giving me blank space.
I know there is another way of doing it using stringstream but I want to know what is wrong in this method?
Character code for numbers are not equal to the integer the character represents in typical system.
It is granteed that character codes for decimal digits are consecutive (N3337 2.3 Character sets, Paragraph 3), so you can add '0' to convert one-digit number to character.
#include <iostream>
using namespace std;
int main()
{
string s;
int b=5;
s.push_back((char)(b + '0'));
cout<<s<<endl;
}
You are interpreting the integer 5 as a character. In ASCII encoding, 5 is the Enquiry control character as you lookup here.
The character 5 on the other hand is represented by the decimal number 53.
As others said, you can't convert an integer to a string the way you are doing it.
IMHO, the best way to do it is using the C++11 method std::to_string.
Your example would translate to:
using namespace std;
int main()
{
string s;
int b=5;
s = to_string(b);
cout<<s<<endl;
}
The problem in your code is that you are converting the integer 5 to ASCII (=> ENQ ASCII code, which is not "printable").
To convert it to ASCII properly, you have to add the ASCII code of '0' (48), so:
char ascii = b + '0';
However, to convert an integer to std::string use:
std::stringstream ss; //from <sstream>
ss << 5;
std::string s = ss.str ();
I always use this helper function in my projects:
template <typename T>
std::string toString (T arg)
{
std::stringstream ss;
ss << arg;
return ss.str ();
}
Also, you can use stringstream,
std::to_string doesn't work for me on GCC
If we were writing C++ from scratch in 2016, maybe we would make this work. However as it choose to be (mostly) backward compatible with a fairly low level language like C, 'char' is in fact just a number, that string/printing algorithms interpret as a character -but most of the language doesn't treat special. Including the cast. So by doing (char) you're only converting a 32 bit signed number (int) to a 8 bit signed number (char).
Then you interpret it as a character when you print it, since printing functions do treat it special. But the value it gets printed to is not '5'. The correspondence is conventional and completely arbitrary; the first numbers were reserved to special codes which are probably obsolete by now. As Hoffman pointed out, the bit value 5 is the code for Enquiry (whatever it means), while to print '5' the character has to contain the value 53. To print a proper space you'd need to enter 32. It has no meaning other than someone decided this was as good as anything, sometime decades ago, and the convention stuck.
If you need to know for other characters and values, what you need is an "ASCII table". Just google it, you'll find plenty.
You'll notice that numbers and letters of the same case are next to each other in the order you expect, so there is some logic to it at least. Beware, however, it's often not intuitive anyway: uppercase letters are before lowercase ones for instance, so 'A' < 'a'.
I guess you're starting to see why it's better to rely on dedicated system functions for strings!
I have a very simple program where I am using the isalnum function to check if a string contains alpha-numeric characters. The code is:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <locale>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {
string test = "(…….";
for ( unsigned int i = 0; i < test.length(); i++) {
if (isalnum(test[i])) {
cout << "True: " << test[i] << " " << (int)test[i] << endl;
}
else {
cout << "False: " << isalnum(test[i]) << test[i] << " " << (int)test[i] << endl;
}
}
return 0;
}
I am using Visual Studio Desktop Edition 2013 for this snippet.
The issue(s):
1. When this program is run in Debug mode, the program fails with a debug assertion that says: "Expression c >= -1 && c <= 255"
Printing the character at the ith position results in a negative integer (-123). Converting all calls to isalnum to accept unsigned char as input causes the above error to disappear.
I checked the documentation for isalnum and it accepts arguments of type char. Then why does this code snippet fail? I am sure I am missing something trivial here but any help is welcome.
The isalnum function is declared in <cctype> (the C++ version of <ctype.h>) -- which means you really should have #include <cctype> at the top of your source file. You're getting away with calling it without the #include directive because either "stdafx.h" or one of the standard headers (likely <locale>) includes it -- but it's a bad idea to depend on that.
isalnum and friends come from C. The isalnum function takes an argument of type int, which must be either within the range of unsigned char or equal to EOF (which is typically -1). If the argument has any other value, the behavior is undefined.
Annoyingly, this means that if plain char happens to be signed, passing a char value to isalnum causes undefined behavior if the value happens to be negative and not equal to EOF. The signedness of plain char is implementation-defined; it seems to be signed on most modern systems.
C++ adds a template function isalnum that takes an argument of any character type and a second argument of type std::locale. Its declaration is:
template <class charT> bool isalnum (charT c, const locale& loc);
I'm fairly sure that this version of isalnum doesn't suffer from the same problem as the one in <cctype>. You can pass it a char value and it will handle it correctly. You can also pass it an argument of some wide character type like wchar_t. But it requires two arguments. Since you're only passing one argument to isalnum(), you're not using this version; you're using the isalnum declared in <cctype>.
If you want to use this version, you can pass the default locale as the second argument:
std::isalnum(test[i], std::locale())
Or, if you're sure you're only working with narrow characters (type char), you can cast the argument to unsigned char:
std::isalnum(static_cast<unsigned char>(test[i]))
The problem is that characters are signed by default, and anything over 0x7f is being treated as a negative number when passed to isalnum. Make this simple change:
if (isalnum((unsigned char)test[i])) {
Microsoft's documentation clearly states that the parameter is int, not char. I believe you're getting confused with a different version of isalnum that comes from the locale header. I don't know why the function doesn't accept sign-extended negative numbers, but suspect that it's based on wording in the standard.
The program built from this code:
#include <fstream>
using std::basic_ifstream;
#include <ios>
using std::streamsize;
#include <ZenLib/Conf.h>
using ZenLib::int8u;
int main() {
#define charT int8u
#define T basic_ifstream<charT>
T ifs ("/proc/cpuinfo", T::in | T::binary);
#undef T
streamsize const bufsize (4096);
charT buf[bufsize];
#undef charT
return !ifs.read(buf, bufsize).gcount();
}
... returns 1.
So std::basic_ifstream<ZenLib::int8u>::read() could not extract any byte from /proc/cpuinfo.
Am I doing anything wrong?
Intantiating std::char_traits for anything but char or wchar_t is
undefined behavior (And I suspect that your charT is unsigned char,
not char.) If you want to use a different type for characters, you'll
have to define a new traits class; for std::istream anf
std::ostream, you'll also have to define a number of facets for the
type as well.
The question is what you want to do. In your example, you only call
std::istream::read. If this is the case, the simplest solution is
probably to just drop down to the system level functions. These
probably want a char* for there buffer as well, but a
reinterpret_cast from unsigned char* will work. You can do this for
std::istream<char>::read as well, but if you have an std::istream,
there's a definite possibility that some formatted input will creap in,
and that will interpret the characters before you can get your
reinterpret_cast in.
The stream libraries are designed to be used with the character types such as char and wchar_t, not integers:
C++11 standard: 27.2.2
In the classes of Clause 27, a template formal parameter with name
charT represents a member of the set of types containing char,
wchar_t, and any other implementation-defined character types that
satisfy the requirements for a character on which any of the iostream
components can be instantiated.
Maybe start from this:
int main()
{
std::ifstream ifs("/proc/cpuinfo", std::ios::binary);
std::cout << ifs.rdbuf();
}
When I am using the following code to convert an string to a float, it is working fine. But the next code gives the error. Please tell me why is this happening? String is a char array only is what I read.
Code1 (working)
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
char str[]="301.23";
float f=atof(str);
cout<<sizeof(str)<<" is size with contents "<<str<<endl;
cout<<sizeof(f)<<" is size with contents "<<f<<endl;
return 0;
}
Code 2(not working)
#include<stdlib.h>
#include<string>
#include<iostream>
using namespace std;
int main()
{
string str="301.23";
float f=atof(str);
cout<<sizeof(str)<<" is size with contents "<<str<<endl;
cout<<sizeof(f)<<" is size with contents "<<f<<endl;
return 0;
}
Error:
error: cannot convert std::string to const char* for argument 1 to double atof(const char*)
Please help
std::string is not a char array.
Use str.c_str() to get a const char* and you should be fine
Syntax:
#include <stdlib.h>
double atof( const char *str );
The input string is a sequence of characters that can be interpreted as a numeric value of the specified return type.
The function stops reading the input string at the first character that it cannot recognize as part of a number. This character can be the null character that ends the string.
The atof() function expects a string in the following form:
Read syntax diagramSkip visual syntax diagram
>>-+------------+--+-----+--+-digits--+---+--+--------+-+------->
'-whitespace-' +- + -+ | '-.-' '-digits-' |
'- – -' '-.--digits-----------------'
Therefore your problem lies in the atof funcion which is not designed to accept string at it doesn't store characters in integer form.
Hope this helped.. :D
Try using #include<cstring> in place of #include <string>
Technically, You're only guaranteed std::string, but all popular implementations just pull in the C header and add a using statement...
is a C++ standard library include, and is C standard library include.