Name of character arrays prints the whole array instead of its address - c++11

We have learned that in case of an array like int a[]={1,2,3}; if we print a as cout<<a; then it prints the address of the first element of the array. But for character array char a[]="Jayesha"; when we do cout<<a; it prints the whole array instead of its address. Also if we print &a[0] it prints 'Jayesha', &a[1] prints 'ayesha', &a[2] prints 'yesha', &a[3] prints 'esha' and so on...
Can anybody please explain why that happens??

const char* a = "Jajesha"; points to a c-style char string. In memory it looks like
J a j e s h a \0 ???
^
a
^ ^ ^ ^
&a[0] &a[2] &a[6] &a[8]
^ ^ ^
&a[1] &a[3] &a[7]
You are doing some pointer arithmetics.
&a[x] is equivalent to a+x.
And it will be of type const char *.
When accessing beyond the length, in your case >7 chars, the result is undefined and may crash
a cout<< of a const char * will output all chars until it finds a \0

This is due to operator overloading, explained here and here.
In your two cases, either you're printing a const void*, the address or you're printing const char*, the contents of the string.

There are two different overloads of std::ostream& << that are being used here.
The first is std::ostream& << void const*, the second is std::ostream << const char*. All pointers can convertable to void const*, and arrays convert to pointers-to-their-first-element.
So when you pass an array of non-character data to <<, its best match is the void const* overload, which prints the address.
When you pass an array of character data to <<, its best match is the char const* overload. That version assumes it has a pointer to a null-terminated strings and prints that buffer.
To avoid this, do a static_cast<void*> on the array prior to passing it to <<.

Related

Is const keyword mandatory while declaring"constexpr char*" string?

The project that I have just started working on has many instances of following,
constexpr const char* str = "Some Character(s)";
I wanted to understand, is the "const" keyword in above statement not redundant, as constexpr is implicitly constant?
It is mandatory because it won't compile if you remove it. This code:
constexpr char *str = "Some Character(s)";
Produces the following error on x64 GCC 11.2 (link):
error: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
1 | constexpr char *str = "Some Character(s)";
| ^~~~~~~~~~~~~~~~~~~
The implied const is for the pointer itself so a redundant const would actually be this:
constexpr const char *const str = "Some Character(s)";
// ^~~~~
const and constexpr has diferent behaivours, as both has the same prefix, you may think that they are the same, but constexpr means that an atribute (or function, or whatever) will be done in compile time, and const means that that atribute won't be modified (it is an inmutable value, you can modify it, but thats undefined behaivour), but maybe can't be evaluated at compile time.
Also, in that particular case, you can't create an char *from an string literal since -std=c++17

how can i safely convert an ascii integer back to its associated ascii character using curses in c++?

I have not been able to find a reliable solution for my problem, what i'm simply trying to do is create some function which:
takes an rows and columns position in the terminal.
calls mvinch(window_object , rows, cols), which returns an unsigned int which corresponds to the character in the terminal at that position.
returns the ascii character associated with that unsigned int, effectively casting it back to a char.
Here is an example of my code in c++11:
char Kmenu::getChrfromW(size_t const y, size_t const x,
bool const save_cursor) const {
size_t curr_y, curr_x;
getyx(_win, curr_y, curr_x);
char ich = mvwinch(_win, y, x);
char ch = ich;
if (save_cursor)
wmove(_win, curr_y, curr_x);
return ch;
}
If for example the character in the terminal at position 2,3 is the letter 'a', i want this function to return the letter 'a'.
I tried the solution described here:
Convert ASCII number to ASCII Character in C
which effectively casts an integer as char.
unfortunately what i get back is still the integer: testing with a screen filled with 'w's, i get back the integer 119.
the man page for the curses function mvwinch() describes the function to return chtype, which the compiler recognises as unsigned int.
Is there a built in a curses function which gives the char back directly without casting to unsigned int, or some other way i can achieve this?
Edit: ch to ich, as in the actual code
A chtype contains a character along with other data. The curses.h header has several symbols which are useful for extracting those bits. If you mask it with A_CHARTEXT and cast that to a char, you will get a character:
char c = (char)((A_CHARTEXT) & n);
Your example should not compile, since it declares ch twice. You may have meant this:
char Kmenu::getChrfromW(size_t const y, size_t const x,
bool const save_cursor) const {
int curr_y, curr_x; // size_t is inappropriate...
getyx(_win, curr_y, curr_x);
char ch = (char)((A_CHARTEXT) & mvwinch(_win, y, x));
// char ch = ich;
if (save_cursor)
wmove(_win, curr_y, curr_x);
return ch;
}
The manual page for mvwinch mentions the A_CHARTEXT mask in the Attributes section, assuming the reader is familiar with things like that:
The following bit-masks may be AND-ed with characters returned by
winch.
A_CHARTEXT Bit-mask to extract character
A_ATTRIBUTES Bit-mask to extract attributes
A_COLOR Bit-mask to extract color-pair field information

what does it mean typedef char *b?

I'm reading through this memory management code overloading operator new. there's expression something like
typedef char *b
and later in the code b was used like this:
b(h); //h is a pointer to some class;
h defined here:
static Head* h= (Head*) HEAP_BASE_ADDRESS;
I'm assuming when b is used it is considered a pointer to a char. But how can a pointer have expressions like b()?? Is there some sort of conversion going on in here? Can I understand it as b now is having the same address as h?
The first code line you posted is a typedef which creates an alias for char* as b. The second code line shows a functional-style type conversion from h to b.
Can I understand it as b now is having the same address as h?
The b is just an alias of char*, so b(h) eventually does nothing unless you store the result of that expresion like:
b b_ptr = b(h); // equivalent to: char* b_ptr = ((char*)h);
The functional-style type conversion works only with single-word type names, so if you want to use this conversion style to e.g. a pointer, you have to typedef it first. (This is the reason of the typedef char *b.) This style of conversion can be used for expressions like int(3.14 + 6.67).

error when trasforming tolower, help would be nice

I'm trying to convert a txt file so all words can be lower case. and when I try I get an error I've tried to differ ways but no luck, my code is as followed
ifstream words("sample_doc.txt");
ofstream samp("sample.txt");
set <string> lower;
set <string> to_low;
copy(istream_iterator<string>(words), istream_iterator<string> (), inserter(lower, begin(lower)) );
transform(begin(lower), end(lower), inserter(to_low, begin(to_low) ), tolower );
when I tried to complete I get this error
'int (int)': cannot convert argument 1 from 'const std::basic_string,std::allocator>' to 'int'
Your problem is that int tolower(int ch); takes as argument an int or a char. However, you are passing it a std::string.
for(std::string& x: lower)
{
transform(x.begin(), x.end(), x.begin(), [](unsigned char c) { return std::tolower(c);});
to_low.insert(x);
}
If you change your last line to the above loop, it will convert each string in std::set<std::string> lower to a lower case string, character by character, and insert it in std::set<std::string> to_low
Hope this helps!

passing argument 1 of 'strlen' makes pointer from integer without a cast

It is not clear why I get a warning of:
[Warning] passing argument 1 of 'strlen' makes pointer from integer without a cast [enabled by default]
expected 'const char *' but argument is of type 'char'
on two of the 3 statements containing strlen() below.
Even when I attempted to cast *str it still gave the same warning.
bfr is a character buffer. *str points to that char buffer after the call to
gets(). If I use strlen(*str) I get a warning. If I use strlen(bfr) I do not.
But *str should be the equivalent to bfr. Thus the confusion regarding the error.
Now in reality, strlen arg 1 is defined as strlen(const char *string). So I
would have expected strlen(bfr) to also produce an error since bfr[] is a
char string and not a const char either.
And where is the integer that is being made into a pointer?
I am using gcc under wXDev-C++.
void test(){
FILE *fileID = fopen("somefile.txt","r");
char *str, len;
char bfr[16];
str = fgets(bfr,16,fileID); // str will be set equal to &bfr[0]
len = strlen(*str); // This gives a warning
len = strlen((const char)*str); // This gives a warning
len = strlen(bfr); // This does not give a warning
}
Sometimes you just need to take a fresh look in the morning at a problem. I realized that strlen is looking for a pointer to a string and 'str' is defined as a pointer. So *str would be a pointer to a pointer. So the warning was correct. It should read len = strlen(s) not len = strlen(*s). And it is 'str' pointing to 'bfr' not *str;
Answered my own question.

Resources