error when trasforming tolower, help would be nice - c++11

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!

Related

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

issue with <libgen.h> and using basename

Unable to get basename to work in C++, I am trying to just get the code to compile.
This is for a school assignment and I have tried to see if it is my stdlib having issues -- however, it seems that the problem is that
'''c++
#include<iostream>
#include<cstring>
#include<libgen.h>
int main(){
const char *ch = "asdfasdf/asdf.cpp";
std::cout<<basename(ch) << std::endl;
std::cout<<dirname(strdup(ch)) << std::endl;
return 0;
}
I was supposed to print out the output of ch, however, instead I get the error message:
test.cpp:8:14: error: no matching function for call to 'basename'
std::cout<enter code here
/usr/include/libgen.h:40:7: note: candidate function not viable: 1st argument ('const char *') would lose const qualifier
char *basename(char *);
^
1 error generated.
basename's argument is char*, so this function may modify passed data. You cannot pass const char* - pointer to only-read data into basename because it would let basename modify const data - not allowed.
Create your input as modifiable array:
char ch[] = "asdfasdf/asdf.cpp";

string length: invalid static_cast

I was expecting this sample code to work:
std::string s;
int number=1;
s = std::to_string(number);
int size=static_cast<int>(s.length);
However it gives the error:
main.cpp:178:39: error: invalid static_cast from type ‘’ to type ‘int’
int size=static_cast(s.length);
Then, I also tried:
int size=atoi(s.length);
Which gives me the error:
cannot convert ‘std::basic_string<_CharT, _Traits, _Alloc>::length<char, std::char_traits<char>
... to type ‘const char*’
Then, I tried this option:
int size=atoi(s.c_str());
This one worked. Any hints why atoi(s.length) does not work, and instead atoi(s.c_str()) is required?
So, suppose that I have the input string as 999, the total of digits will be 3. Using s.length would be the best way to get the total of digits, however the s.length casting gives the error.
You did not invoke the length method.
You should use int size=static_cast<int>(s.length());: notice the call operator at the end of the length method name.
However, if by doing this, you are trying to convert the string to an integer, this is wrong. This only gives you the number of characters in the string.

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.

using MultiByteToWideChar

The following code prints the desired output but it prints garbage at the end of the string. There is something wrong with the last call to MultiByteToWideChar but I can't figure out what. Please help??
#include "stdafx.h"
#include<Windows.h>
#include <iostream>
using namespace std;
#include<tchar.h>
int main( int, char *[] )
{
TCHAR szPath[MAX_PATH];
if(!GetModuleFileName(NULL,szPath,MAX_PATH))
{cout<<"Unable to get module path"; exit(0);}
char ansiStr[MAX_PATH];
if(!WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,szPath,-1,
ansiStr,MAX_PATH,NULL,NULL))
{cout<<"Unicode to ANSI failed\n";
cout<<GetLastError();exit(1);}
string s(ansiStr);
size_t pos = 0;
while(1)
{
pos = s.find('\\',pos);
if(pos == string::npos)
break;
s.insert(pos,1,'\\');
pos+=2;
}
if(!MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,s.c_str(),s.size(),szPath,MAX_PATH))
{cout<<"ANSI to Unicode failed"; exit(2);}
wprintf(L"%s",szPath);
}
MSDN has this to say about the cbMultiByte parameter:
If this parameter is -1, the function processes the entire input
string, including the terminating null character. Therefore, the
resulting Unicode string has a terminating null character, and the
length returned by the function includes this character.
If this parameter is set to a positive integer, the function processes
exactly the specified number of bytes. If the provided size does not
include a terminating null character, the resulting Unicode string is
not null-terminated, and the returned length does not include this
character.
..so if you want the output string to be 0 terminated you should include the 0 terminator in the length you pass in OR 0 terminate yourself based on the return value...

Resources