473,795 Members | 3,439 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

tolower conflict with iostream?

I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.beg in(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}

; g++ lc.cc
lc.cc: In function `std::string& lc(std::string& )':
lc.cc:11: error: no matching function for call to `transform(
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >,
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >,
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >, <unknown type>)'

If I do not include iostream, or if I use a different function
(e.g., int id(int i){return i;}), I do not get any errors. Am I doing
something wrong?

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
-- unknown
Jul 19 '05 #1
13 6032
In article <3F************ ***@nomail.com> ,
David Rubin <bo***********@ nomail.com> wrote:
I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.beg in(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}

; g++ lc.cc
lc.cc: In function `std::string& lc(std::string& )':
lc.cc:11: error: no matching function for call to `transform(
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >,
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >,
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >, <unknown type>)'

If I do not include iostream, or if I use a different function
(e.g., int id(int i){return i;}), I do not get any errors. Am I doing
something wrong?


Yes, but you're in good company. This one gets almost everyone at least
once.

There are two kickers (if not more) in this one:

1. tolower is (also) a template function prototyped in <locale>:

template <class charT> charT tolower(charT c, const locale& loc);

2. Any standard C++ header is allowed to include any other standard C++
header as an implementation detail (reference 17.4.4.1/1).

So when you say:

transform(s.beg in(), s.end(), s.begin(), tolower);

and if the templated tolower is in scope, then the compiler can't figure
out what template parameters to try out for tolower<charT>, even if the
non-templated tolower is also in scope. And apparently gcc's <iostream>
brings tolower<charT> into scope as an implementation detail. Thus the
error.

This is a sneaky one in that it may well compile and do what you want
with another compiler. For example it works just fine on Metrowerks,
unless <locale> is explicitly included, and then you get a similar error.

You can correct it, portably, with the following incantation:

transform(s.beg in(), s.end(), s.begin(), (int (*)(int))tolowe r);

I.e. cast tolower to the specific function pointer type that you're
aiming for.

-Howard
Jul 19 '05 #2

"David Rubin" <bo***********@ nomail.com> wrote in message
news:3F******** *******@nomail. com...
I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.beg in(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}

; g++ lc.cc
lc.cc: In function `std::string& lc(std::string& )':
lc.cc:11: error: no matching function for call to `transform(
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >,
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >,
__gnu_cxx::__no rmal_iterator<c har*, std::basic_stri ng<char,
std::char_trait s<char>, std::allocator< char> > >, <unknown type>)'

If I do not include iostream, or if I use a different function
(e.g., int id(int i){return i;}), I do not get any errors. Am I doing
something wrong?

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
-- unknown
_______________ _______________ _______________ _______________ _
the way I fixed it is by doing
::tolower
Jul 19 '05 #3
Howard Hinnant <hi*****@metrow erks.com> wrote:
You can correct it, portably, with the following incantation:

transform(s.beg in(), s.end(), s.begin(), (int (*)(int))tolowe r);

I.e. cast tolower to the specific function pointer type that you're
aiming for.


See, even standard library implementers get it wrong :-) This one is,
however, even more subtle: 'std::tolower(i nt)' can only be called with
values which can be represented by an 'unsigned char' and EOF. However,
on systems where 'char' is a signed entity lots of possible 'char' values,
promoted to 'int', cannot be represented as 'unsigned char'. Although the
above code would be portably compilable, it won't run portably. For a
truely portable solution, you would need an auxiliary function:

char mytolower(char c) {
return std::tolower(st atic_cast<unsig ned char>(c));
}

This will convert the negative 'char' to some positive value first which
stays the same value when converted to 'int'. Promoting a negative 'char'
directly to 'int' and then converting this value to an unsigned type
would yield a value which is [normally (*)] bigger than any value which
can be hold by an 'unsigned char'.

(*): if the number of bits used for 'int' and 'unsigned char' is identical,
it would work...
--
<mailto:di***** ******@yahoo.co m> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.co m/>
Jul 19 '05 #4
On Wed, 08 Oct 2003 22:43:22 GMT, Howard Hinnant
<hi*****@metrow erks.com> wrote:
Yes, but you're in good company. This one gets almost everyone at least
once.

There are two kickers (if not more) in this one:

1. tolower is (also) a template function prototyped in <locale>:

template <class charT> charT tolower(charT c, const locale& loc);

2. Any standard C++ header is allowed to include any other standard C++
header as an implementation detail (reference 17.4.4.1/1).

So when you say:

transform(s.beg in(), s.end(), s.begin(), tolower);

and if the templated tolower is in scope, then the compiler can't figure
out what template parameters to try out for tolower<charT>, even if the
non-templated tolower is also in scope.
It's not that clear in the standard that the non-template tolower
shouldn't be chosen. For the templated tolower, argument deduction
would fail, so only the non-template version would be left. In theory
this could be chosen unambiguously.

And apparently gcc's <iostream>brings tolower<charT> into scope as an implementation detail. Thus the
error.

This is a sneaky one in that it may well compile and do what you want
with another compiler. For example it works just fine on Metrowerks,
unless <locale> is explicitly included, and then you get a similar error.
Comeau compiles it fine with both <locale> and <cctype> included.
13.4/2 suggests that it might be ok, but it certainly isn't clear
either way.

http://std.dkuug.dk/jtc1/sc22/wg21/d...ctive.html#115
also has vague relevence.
You can correct it, portably, with the following incantation:

transform(s.beg in(), s.end(), s.begin(), (int (*)(int))tolowe r);

I.e. cast tolower to the specific function pointer type that you're
aiming for.


However, this still has the problem with the domain to tolower being
EOF + the range of unsigned char.

Tom
Jul 19 '05 #5
David Rubin <bo***********@ nomail.com> wrote in message news:<3F******* ********@nomail .com>...
I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.beg in(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
} /david


david, I don't know that much about c++, but you can do what you want
by flipping the bit in the 32's place. If you know that your string
contains letters, then you can use these 3 functions:

#include <iostream>
#include <string>
using namespace std;

string lcase(string stringin){
string stringout;
for(int i = 0; i < stringin.size() ; ++i)
stringout += (stringin[i] | 32);
return stringout;
}

string ucase(string stringin){
string stringout;
for(int i = 0; i < stringin.size() ; ++i)
stringout += (stringin[i] & (223));
return stringout;
}

string flipcase(string stringin){
string stringout;
for(int i = 0; i < stringin.size() ; ++i)
stringout += (stringin[i] ^ 32);
return stringout;
}

int main(){
cout << "Enter text";
string test;
getline(cin, test);
cout << "Original " << test << endl
<< "All Caps " << ucase(test)<< endl
<< "Lower Case " << lcase(test) << endl
<< "Flip Case " << flipcase(test) << endl;
}

Of course, you will prob. want to clean up the function masks so that
they only effect characters. (eg only effect chars (65 - 90) and (97 -
122)).
Jul 19 '05 #6
"Steven C." <no****@xxx.com > wrote in message news:<KG******* *********@twist er.socal.rr.com >...
"David Rubin" <bo***********@ nomail.com> wrote in message
news:3F******** *******@nomail. com...
I get an error when I compile the following code:

#include <algorithm>
#include <cctype>
#include <iostream>
#include <string>

using namespace std;

string&
lc(string& s)
{
transform(s.beg in(), s.end(), s.begin(), tolower);
return s;
}

int
main()
{
string name = "DAVID";

cout << name << " " << lc(name) << endl;
return 0;
}


I'm sure your aren't interested, but...I improved the functions I just
wrote so that they now ignore all non alphebetic characters. You can
easily change the function to pass a string reference if you want the
change to affect the original string. Anyway...these functions should
work with any string object.

#include <iostream>
#include <string>
using namespace std;

string lcase(string in){
string stringout;
for(int i = 0; i < in.size(); ++i)
if(!(in[i] & 128) & ((in[i] & 95) > 64) & ((in[i] & 31) <= 26))
stringout += (in[i] | 32);
else stringout += in[i]; //character wasn't a letter...dont
change
return stringout;
}

string ucase(string in){
string stringout;
for(int i = 0; i < in.size(); ++i)
if(!(in[i] & 128) & ((in[i] & 95) > 64) & ((in[i] & 31) <= 26))
stringout += (in[i] & (223));
else stringout += in[i]; //character wasn't a letter...dont
change
return stringout;
}

string flipcase(string in){
string stringout;
for(int i = 0; i < in.size(); ++i)
if(!(in[i] & 128) & ((in[i] & 95) > 64) & ((in[i] & 31) <= 26))
stringout += (in[i] ^ 32);
else stringout += in[i]; //character wasn't a letter...dont
change
return stringout;
}

int main(){
cout << "Enter text\n";
string test;
getline(cin, test);
cout << "Original " << test << endl
<< "All Caps " << ucase(test)<< endl
<< "Lower Case " << lcase(test) << endl
<< "Flip Case " << flipcase(test) << endl;
}

in case you are wondering...

if(!(in[i] & 128) & ((in[i] & 95) > 64) & ((in[i] & 31) <= 26))
------------- ------------------ -------------------
0XXX XXXX X10X XXXX 000X XXXX <= 26
000X XXXX > 0
Jul 19 '05 #7
"J. Campbell" wrote:
using namespace std;

string&
lc(string& s)
{
transform(s.beg in(), s.end(), s.begin(), tolower);
return s;
}

[snip] david, I don't know that much about c++, but you can do what you want
by flipping the bit in the 32's place. If you know that your string
contains letters, then you can use these 3 functions:

[snip - code]

Thanks for the code. However, you are assuming an ASCII character set
and a particular locale. The ::tolower solution seems to work well. I
suppose you can extend this to implement Flipcase as a functor (or
simply as a function) using

s[i] = (::isupper(s[i]) ? ::tolower(s[i]) : ::toupper(s[i]));

BTW, for those in the know who are still reading this thread, is* and
to* are known to take an int argument to account for EOF. However, is it
safe to assume that an explicit cast is unnecessary when applying these
functions to a string? Presumably, a string will not contain EOF.

/david

--
Andre, a simple peasant, had only one thing on his mind as he crept
along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
-- unknown
Jul 19 '05 #8
David Rubin wrote:
s[i] = (::isupper(s[i]) ? ::tolower(s[i]) : ::toupper(s[i]));

BTW, for those in the know who are still reading this thread, is* and
to* are known to take an int argument to account for EOF. However, is it
safe to assume that an explicit cast is unnecessary when applying these
functions to a string? Presumably, a string will not contain EOF.


Although the 'is*()' and 'to*()' account for EOF, they do not account
for negative values of 'char' on platforms where 'char' is a signed
entity (at least, they are not required to; I would expect that library
implementers actually do account for this case). Thus, you have to cast
a 'char' to 'unsigned char' before passing them into these functions.
--
<mailto:di***** ******@yahoo.co m> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.co m/>
Jul 19 '05 #9
Dietmar Kuehl <di***********@ yahoo.com> wrote in message news:<bm******* *****@ID-86292.news.uni-berlin.de>...
Although the 'is*()' and 'to*()' account for EOF, they do not account
for negative values of 'char' on platforms where 'char' is a signed
entity (at least, they are not required to; I would expect that library
implementers actually do account for this case). Thus, you have to cast
a 'char' to 'unsigned char' before passing them into these functions.


#include <algorithm>
#include <string>
#include <cctype>

template <int (*F) (int)>
int safe (unsigned char c) { return F(c); }

int main () {
std::string s;
std::transform( s.begin(), s.end(), s.begin(), safe<std::toupp er>);
}

As a bonus, this also deals with the overloaded stuff in <locale> --
unless you actually wanted to call those. :)

- Shane
Jul 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
3365
by: TheDD | last post by:
Hello, i don't manage to use the tolower() function: #include <algorithm> #include <iostream> #include <locale> #include <string> using std::cout;
2
3992
by: humble04 | last post by:
Hi, I am compiling a collection of C++ code. Most of them are using the new format #include <iostream>. I think all of them because I failed at finding out which header file uses the old format #include <iostream.h>. However, I met the following error messages. "/usr/vacpp/include/iostream.h", line 74.7: 1540-0400 (S) "class ostream" has a conflicting declaration "../include/myfile.h", line 7.1: 1540-0424 (I) "ostream" is declared on
9
2116
by: asbisht | last post by:
Greetings to everyone. #include<iostream> main( void ) { unsigned char value = 'A'; std::cout << tolower(value); return 0; }
4
3255
by: Eric Lilja | last post by:
Hello, consider this program: #include <iostream> #include <algorithm> #include <string> #include <cctype> int main() { std::string s = "HEJ";
3
3256
by: beck2 | last post by:
Hello everyone its Angela again. Can anyone help me please? i want to convert uppercase characters to lower case using the <stdlib.h> and the function tolower. for example i want to display "HELLO" to lower. my code is: #include<iostream.h> #include<stdlib.h> void main() {
5
2233
by: Faray | last post by:
Hello, this is my first post, so hopefully I am posting this in the right place. Hopefully someone will be able to help me out with my problem here it is: I need to make a program that ask a user to input a word. However when they input that word I need to convert the word to all lowercase letters so it can do a serach. This is my problem: Every time I try to use tolower it gives me an error "Cannot convert parameter 1 from...
6
2240
by: tgnelson85 | last post by:
Hello, I've managed to get my c++ code calling my c code, and i can call a function that prints something to the screen etc. However, i am trying to call the following C function: char* normaliseString(char *pstring) { char *ptr; for(ptr = pstring; *ptr; ptr++) {
1
1977
nurulshidanoni
by: nurulshidanoni | last post by:
Dear all, my algorith is like this while(mor students) read studentID countexam=0 while (more examination) read examcode examID =get ExamID (examCode)
13
3003
by: Soumen | last post by:
I wanted convert a mixed case string to a lower case one. And I tried following code: std::transform(mixedCaseString.begin(), mixedCaseString::end(), mixedCaseString.begin(), std::ptr_fun(tolower)); Even though I's including cctype and algorithm, I's getting compiler (g ++ 3.3.6) error: no matching function for call to `ptr_fun(<unknown type>)'
0
9519
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10437
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10214
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10001
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9042
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6780
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5437
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4113
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2920
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.