#include <iostream>
using namespace std;
int main()
{
char x;
cout << "enter a character:";
cin >> x;
cout << "ASCII Value of " << x << "is" << string(x);
return 0 ;
}
the error is
main.cpp||In function 'int main()':|
main.cpp|10|error: invalid conversion from 'char' to 'const char*'|
main.cpp|10|error: initializing argument 1 of 'std::basic_string<_CharT, _Traits,_Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]'|
||=== Build finished: 2 errors, 0 warnings ===|
std::cout << "ASCII Value of " << x << "is" << (int)x;
is one way (the cast circumvents the special treatement of a char type by the I/O stream library), but this will output your platform's encoded value of the character, which is not necessarily ASCII.
A portable solution is much more complex: You'll need to encode the ASCII set in a 128 element array of elements capable of storing a 7 bit unsigned value, and map x to a suitable element of that.
There are 3 approaches to solving this problem:
Use to_string
Passing the correct value to cout
Using the std::string class correctly
The solutions are marked (numbers in comment).
Use std::to_string
Since C++11, there is function to convert numbers to a string (to_string):
/*(1)*/ std::cout << std::to_string( x );
There is no specialization for a char parameter. So the value is implictly converted.
Passing the correct value to cout
cout would display the value of char object as a character.
If we want to output the value of a char object, we need to convert it to a type which is output by cout as a number instead of a character.
The C++ standard guarantees:
1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
So any of those integer types can be used. Usually int is selected.
There are 4 conversions that can be used here:
1) Implicit - "Implicit conversions are performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2;"
/*(2)*/ int i = x;
std::cout << i;
2) Explicit - "Converts between types using a combination of explicit and implicit conversions."
/*(3)*/ std::cout << (int)x;
/*(4)*/ std::cout << int(x); // unsigned int(x) - is invalid,
// has to be a single-word type name
3) A named cast.
/*(5)*/ std::cout << static_cast<int>(x);
4) Use the T{e} notation for construction
/*(6)*/ std::cout << int{x};
The T{e} construction syntax makes it explicit that construction is desired. The T{e} construction syntax doesn’t allow narrowing. T{e} is the only safe and general expression for constructing a value of type T from an expression e. The casts notations T(e) and (T)e are neither safe nor general.
About conversions the C++ Core Guidelines specifies the following (among others)
ES.48: Avoid casts
ES.49: If you must use a cast, use a named cast
ES.64: Use the T{e}notation for construction
In this case I would suggest (3) or (4).
Using the std::string class correctly
string is a specialization of basic_string
using string = basic_string<char>;
basic_string has many constructors.
There are only 2 constructors, which can take a predefined number of chars;
basic_string( size_type count, CharT ch, const Allocator& alloc = Allocator() );
Constructs the string with count copies of character ch. The behavior is undefined if count >= npos.
/*(7)*/ std::string s = std::string( 1, x );
basic_string( const CharT* s, size_type count, const Allocator& alloc = Allocator() );
Constructs the string with the first count characters of character string pointed to by s. s can contain null characters. The length of the string is count. The behavior is undefined if s does not point at an array of at least count elements of CharT, including the case when s is a null pointer.
/*(8)*/ std::string s = std::string( &x, 1 );
#include <iostream>
using namespace std;
int main()
{
char x;
cout<< "enter a character:";
cin>>x;
cout<< "ASCII Value of "<< x<< "is"<< int(x);
return 0 ;
}
you mean return try this code
#include <iostream>
using namespace std;
int main()
{
char x;
cout<< "enter a character:";
cin>>x;
cout<< "ASCII Value of "<< x<< "is"<< char(x);
return 0 ;
}
try this its called return
Related
What is the difference between
(type)value
and
type(value)
in C++?
There is no difference; per the standard (§5.2.3):
A simple-type-specifier (7.1.5) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).
Since the question specified the difference between type(value) and (type)value, there is absolutely no difference.
If and only if you're dealing with a comma-separated list of values can there be a difference. In this case:
If the expression list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1), and the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some invented temporary variable t, with the result being the value of t as an rvalue.
As Troubadour pointed out, there are a certain names of types for which the type(value) version simply won't compile. For example:
char *a = (char *)string;
will compile, but:
char *a = char *(string);
will not. The same type with a different name (e.g., created with a typedef) can work though:
typedef char *char_ptr;
char *a = char_ptr(string);
There is no difference; the C++ standard (1998 and 2003 editions) is clear about this point. Try the following program, make sure you use a compiler that's compliant, such as the free preview at http://comeaucomputing.com/tryitout/.
#include <cstdlib>
#include <string>
int main() {
int('A'); (int) 'A'; // obvious
(std::string) "abc"; // not so obvious
unsigned(a_var) = 3; // see note below
(long const&) a_var; // const or refs, which T(v) can't do
return EXIT_SUCCESS;
}
Note: unsigned(a_var) is different, but does show one way those exact tokens can mean something else. It is declaring a variable named a_var of type unsigned, and isn't a cast at all. (If you're familiar with pointers to functions or arrays, consider how you have to use a parens around p in a type like void (*pf)() or int (*pa)[42].)
(Warnings are produced since these statements don't use the value and in a real program that'd almost certainly be an error, but everything still works. I just didn't have the heart to change it after making everything line up.)
There is no difference when both are casts, but sometimes 'type(value)' is not a cast.
Here's an example from standard draft N3242, section 8.2.1:
struct S
{
S(int);
};
void foo(double a)
{
S w( int(a) ); // function declaration
S y( (int)a ); // object declaration
}
In this case 'int(a)' is not a cast because 'a' is not a value, it is a parameter name surrounded by redundant parentheses. The document states
The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in 6.8 can also occur in the context
of a declaration. In that context, the choice is between a function
declaration with a redundant set of parentheses around a parameter
name and an object declaration with a function-style cast as the
initializer. Just as for the ambiguities mentioned in 6.8, the
resolution is to consider any construct that could possibly be a
declaration a declaration.
In c there is no type (value), while in c/c++ both type (value) and (type) value are allowed.
To illustrate your options in C++ (only one has a safety check)
#include<boost/numeric/conversion/cast.hpp>
using std::cout;
using std::endl;
int main(){
float smallf = 100.1;
cout << (int)smallf << endl; // outputs 100 // c cast
cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast
cout << static_cast<int>(smallf) << endl; // outputs 100
// cout << static_cast<int&>(smallf) << endl; // not allowed
cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100
float bigf = 1.23e12;
cout << (int)bigf << endl; // outputs -2147483648
cout << int(bigf) << endl; // outputs -2147483648
cout << static_cast<int>(bigf) << endl; // outputs -2147483648
// cout << static_cast<int&>(bigf) << endl; // not allowed
cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}
n=b.size()
n = max(n,(int)a.size());
where a and b are some user-Input strings and n is an integer. would anybody tell me why we use (int)a.size() and what is the purpose of using (int).
I am assuming that n is of type int, and your program will be something like this :
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string a ("Test string");
string b ("Test two");
int n = b.size() ;
n = max(n,(int)a.size());
cout << "n : " << n ;
return 0;
}
Now if you see the documentation for the .size() method of the string class, you will see it returns value of type : size_t
size_t is an unsigned integral type (the same as member type
string::size_type)
: as per documentation
Now when we look at the documentation for max() you can see it uses templating (you can read more about templating here) what it essentially means is that you can use any type as parameter (int, float, etc..) but both the parameters need to be the same type.
Now since n was declared as an int when calling max(n,x);, x needs to be type of n which basically means int in our case.
Now this is the reason for using (int) before a.size(). What we are doing here is type casting, since a.size() returns in type size_t which is different from int (You can read more about this here), we need to typecast the return value to int which can be done by (int)a.size().
SIDE NOTE
int n = max(b.size(),a.size());
cout << "n : " << n << " \n";
would also work, since both are same type so no need to do type casting.
do variables automatically convert to the type required by the function as the appropriate arguments?
#include <stdio.h>
void swap(int &i, int &j) { //the arguments here are int&
int temp = i;
i = j;
j = temp;
}
int main(void) {
int a = 10;
int b = 20;
swap(a, b); // but a and b does not match the exact types of arguments
cout >> "A is %d and B is %d\n" >> a >> b;
return 0;
}
The type conversion rules are rather complex to explain in general.
But for your example, both parameters are int&, which means "reference to int". Since you pass two valid int variables, it's exactly the type expected and the reference of the variables is passed as argument.
Would you have tried with a different type, it would have failed, for example :
long a=10,b=20; would have failed to compile since it is not possible to get an int reference to refer to the non-int original variables.
swap(10,20); would have failed, because the parameters are literal int values and not variables. It is not possible to get a reference to such a value.
const int a=10; would also have failed. This time because the const of the variable is an additional constraint that the parameter passing is not allowed to losen.
Not related: You should include <iostream> and the output should look like:
std::cout << "A is "<< a << " and B is " << b << std::endl;;
The short answer is "sometimes".
The long answer is very long, and you should read this web page: https://en.cppreference.com/w/cpp/language/implicit_conversion
There are a lot of rules for when various types are implicitly converted to other types -- and when they are not.
What does char [5] const & mean?
Constant lvalue reference to array of 5 char
Or lvalue reference to array of 5 constant char
Or lvalue reference to const array of 5 char?
I am reading C++ programming language book and I am learning about pointer to char. I found this code: char s[] = "Gorm";, which reminds me that string literal is converted implicitly to const char *.
So, I felt confused that LHS and RHS are not of same type.
I used online compiler and code from here to get idea about how compiler see type of LHS and RHS. Then, I found that LHS is seen as char[5] while RHS is seen as char[5] const &.
I can interpret LHS but, I cannot understand what is "constant lvalue reference to array of 5 char" or even after implicit conversion of LHS char s[] to char* s, what is "constant lvalue reference to non const pointer to non const char"?
Is not lvalue reference by definition constant "it refers only to value initializing it"? So, why do we need const before &?
And then, how can LHS and RHS of different types be assigned?
Following is the code, I used to get type of LHS and RHS:
#include < type_traits >
#include < typeinfo >
#ifndef _MSC_VER
#include < cxxabi.h >
#endif
#include < memory >
#include < string >
#include < cstdlib >
#include < iostream > // std::cout
template < class T > std::string
type_name() {
typedef typename std::remove_reference < T >:: typeTR;
std::unique_ptr < char, void( *)(void *) > own(#ifndef _MSC_VER abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr, nullptr), #else nullptr, #endif std::free);
std::string r = own != nullptr
? own.get()
: typeid(TR).name();
if (std::is_const < TR >:: value)
r += " const";
if (std::is_volatile < TR >:: value)
r += " volatile";
if (std::is_lvalue_reference < T >:: value)
r += "&";
else if (std::is_rvalue_reference < T >:: value)
r += "&&";
return r;
}
int & foo_lref();
int && foo_rref();
int foo_value();
int main() {
int i = 0;
const int ci = 0;
char s[] = "Gorm";
std::cout << "decltype(s) is " << type_name < decltype("Gorm") > () << '\n';
std::cout << "decltype(i) is " << type_name < decltype(i) > () << '\n';
std::cout << "decltype((i)) is " << type_name < decltype((i)) > () << '\n';
std::cout << "decltype(ci) is " << type_name < decltype(ci) > () << '\n';
std::cout << "decltype((ci)) is " << type_name < decltype((ci)) > () << '\n';
std::cout << "decltype(static_cast<int&>(i)) is " << type_name < decltype(static_cast < int &> (i)) > () << '\n';
std::cout << "decltype(static_cast<int&&>(i)) is " << type_name < decltype(static_cast < int &&> (i)) > () << '\n';
std::cout << "decltype(static_cast<int>(i)) is " << type_name < decltype(static_cast < int > (i)) > () << '\n';
std::cout << "decltype(foo_lref()) is " << type_name < decltype(foo_lref()) > () << '\n';
std::cout << "decltype(foo_rref()) is " << type_name < decltype(foo_rref()) > () << '\n';
std::cout << "decltype(foo_value()) is " << type_name < decltype(foo_value()) > () << '\n';
}
char [5] const & is not a valid type. If the code you posted gives you this output, the code is broken.
Here's how you can check if a type is valid:
using type = char [5] const &; // error: expected ';' before 'const'
The actual type of string literals is const char [N], but in this case it doesn't matter.
C++ has a special rule that allows initializing character arrays with string literals. That's all.
Note that if you apply decltype to a string literal, it will give you const char (&)[N] (reference to a constant array of char). But it's not the actual type of the literal.
It might sound confusing, but expressions never have reference types. Variables do, but not expressions. See: What expressions yield a reference type when decltype is applied to them?
If decltype (when applied to an expression, rather than a variable) gives you an lvalue-reference type, it's an indication that the expression is an lvalue. (a rvalue-reference indicate an xvalue, and a lack of reference indicates a prvalue).
but i can not understand what is "constant lvalue reference to array of 5 char"
This is a misnomer; it's a reference to a constant array, not a constant reference to an array. As you've observed, references can't be changed, and const can't apply to them (because they're not objects).
and then how can lhs and rhs of different types be assigned?
You can create a reference to a const object from a value of non-const object. This makes sense, because you're turning a "view" that is read and write and constraining it into "read-only."
To eliminate confusion with "weird" types, it's important to know how to read them. The clockwise/spiral method is one way to go here. Another effective method is the right/left sweep method. While these rules work best when there's a named type, it can still be adapted by simply reading right to left.
So, char[5] const & is a[n l-value] reference to a constant array of size 5 of characters. And that sounds like an accurate description of a string literal. In saying that the array is constant, it just means that the contents can't change, which is true of a string literal.
As another example, consider an array: int arr[5]. You are allowed to change the contents of the array, but arr must always point to the first element, meaning that pointer cannot change. Declaring a pointer that will always point to the same thing is accomplished with: int * const ptr;. I can change the value of what I'm pointing at, but I cannot change where I point at. If I declare it const int * const ptr or int const * const ptr, I can not change the value of what I'm pointing at, nor can I change where I point.
#include <iostream>
template <typename T>
inline
T accum (T const* beg, T const* end)
{
T total = T(); // assume T() actually creates a zero value
while (beg != end) {
total += *beg;
++beg;
}
return total;
}
int main()
{
// create array of 5 integer values
int num[]={1,2,3,4,5};
// print average value
std::cout << "the average value of the integer values is "
<< accum(&num[0], &num[5]) / 5
<< '\n';
// create array of character values
char name[] = "templates";
int length = sizeof(name)-1;
// (try to) print average character value
std::cout << "the average value of the characters in \""
<< name << "\" is "
<< accum(&name[0], &name[length]) / length
//<< accum<int>(&name[0], &name[length]) / length //but this give me error
<< '\n';
}
I was reading c++ templates:the complete guide book and the author mentioned
that I can use template specialization
accum<int>(&name[0], &name[length]) / length
I try this in visual studio 2012 and got error
main.cpp(34): error C2664: 'accum' : cannot convert parameter 1 from 'char *' to 'const int *'
My C++ is a bit rusty.
I'm just curious, if this "behavior" previously allowed but there's changes in "latest" C++ standard making this illegal or this is an error on the book I'm reading.
The instantiation is int accum<int> (int const* beg, int const* end), you can't pass char * arguments to this function.
The reason the uncommented line works is that it instantiates accum<char>.
The line accum<int>(&name[0], &name[length]) tries to call a function declared int accumt(const int*, const int*) with arguments of type char*, char*. The compiler is right to complain: C++ never allowed implicit conversions from char* to int*. If that is what the book says, there's an error in it.