LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 8255|回复: 22

C++ STL 转换 string 大小写编译出错以及一个 C 中 strcpy 的问题

[复制链接]
发表于 2003-7-23 20:55:22 | 显示全部楼层 |阅读模式
1. STL 中 string 转换大小写的问题
程序如下:
#include <string>
#include <iostream>
#include <algorithm>
#include <cctype>
using namespace std;
int main()
{
    // create a string
    string s("This is a string");
    cout << "original: " << s << endl;

    // lowercase all characters
    transform(s.begin(), s.end(), s.begin(), tolower);
    cout << "lowered: " << s << endl;

    // uppercase all characters
    transform(s.begin(), s.end(), s.begin(), toupper);
    cout << "uppered: " << s << endl;
}

编译的时候报了一大堆错,如下:
test.cpp: In function `int main()':
test.cpp:13: no matching function for call to `transform(
   __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > >,
   __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > >,
   __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > >, <unknown type>)'
test.cpp:19: no matching function for call to `transform(
   __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > >,
   __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > >,
   __gnu_cxx::__normal_iterator<char*, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > >, <unknown type>)'

请问如何解决?我用的是 RH9 自带的 3.2.2

2. C 中 strcpy 的问题:
程序如下:
#include <string.h>
#include <stdio.h>

int main()
{
    char * a = "This is a string";
    char * b;

    printf("%s\n",a);
    b = strcpy(b, a);
    printf("%s\n",b);
}

如上编译运行没有任何错误,并且正常打印出 a 和 b ,但是如果把第一个 printf 语句,就是打印 a 的那个语句删除,或者将 strcpy 挪到这个 printf 之前,编译没有问题,运行的时候就会报告“段错误”。


请大家帮助我看看是什么问题,刚开始学习 C++ 和 C,谢谢!
发表于 2003-7-23 23:28:18 | 显示全部楼层
第2个问题,char * b;没有为b分配内存。
发表于 2003-7-24 01:36:06 | 显示全部楼层
第一个是函数不匹配。
template <class InputIterator, class OutputIterator, class UnaryFunction>
OutputIterator transform(InputIterator first, InputIterator last,
                         OutputIterator result, UnaryFunction op);

你最后的tolower,toupper,这些操作没有定义。
具体是应该怎么办,我也不清楚。
 楼主| 发表于 2003-7-24 09:31:20 | 显示全部楼层
最初由 kj501 发表
第2个问题,char * b;没有为b分配内存。


谢谢!但是为什么我在前面加上 a 的 print 语句就可以了呢?
 楼主| 发表于 2003-7-24 09:34:10 | 显示全部楼层
最初由 pupilzeng 发表
第一个是函数不匹配。
template <class InputIterator, class OutputIterator, class UnaryFunction>
OutputIterator transform(InputIterator first, InputIterator last,
                         OutputIterator result, UnaryFunction op);

你最后的tolower,toupper,这些操作没有定义。
具体是应该怎么办,我也不清楚。


tolower 和 toupper 是 cctype 中的函数,我的这个程序是照着一本《The C++ Standard Library》中的例子写的,但是不行
发表于 2003-7-24 10:35:33 | 显示全部楼层

re:

关键并不在于printf()函数的问题,如果不为b分配内存的话,是肯定要出段错误的,因为b的指针值是未定的,你知道你的strcpy将那些字符考到哪了吗,谁业不知道,只有系统知道。关于加上printf以后为什么系统不报错了,这个不太好解释,也许编译器的处理会有些不一样,这个问题单从语言上面来讲是不好解释的。
发表于 2003-7-26 18:06:12 | 显示全部楼层
#include <iostream>
#include <algorithm>
#include <ctype.h>
using namespace std;

char ToLow(char a)
{
return (char)tolower(a);
}

int main()
{
// create a string
string s("This is a string");
cout << "original: " << s << endl;

// lowercase all characters
transform(s.begin(), s.end(), s.begin(), ToLow);
cout << "lowered: " << s << endl;
}

由于gcc类型的检测比较严格
int tolower(int)这是tolower的声明。
 楼主| 发表于 2003-7-26 20:25:36 | 显示全部楼层
最初由 gybcb 发表
#include <iostream>
#include <algorithm>
#include <ctype.h>
using namespace std;

char ToLow(char a)
{
return (char)tolower(a);
}

int main()
{
// create a string
string s("This is a string");
cout << "original: " << s << endl;

// lowercase all characters
transform(s.begin(), s.end(), s.begin(), ToLow);
cout << "lowered: " << s << endl;
}

由于gcc类型的检测比较严格
int tolower(int)这是tolower的声明。


哦,原来是这个原因,后来我也发现自己再声明一个函数就可以了。但是 tolower 也在 std 的 namespace 中,为什么 transform 就不认呢?
发表于 2003-7-27 10:46:25 | 显示全部楼层
#include <cctype> 也没问题。

对于顶楼的问题,我刚开始学编程,所以觉得比较有意思,解释如下:

“...because the standard library functions the C++ inherits from C's
<ctype.h> are only defined for integer values over the range of 0 to
UCHAR_MAX and the single negative value of the macro EOF.

Specifically, it is implementation-defined whether "plain" char is
signed or unsigned, but it is signed on most common desk top systems.
In that case, any particular character of a string could have a
negative value that converts to a negative integer most likely not
equal to EOF, in which case passing it to any of the is... or to...
functions invokes undefined behavior.
。。。。。。

: What does '#include <locale>' do?  What's in that header?

    There is a declaration of a templated toupper function that deals
with locales. There are some problems with its usage that I am reading
about now (do a google search for "sanity check" in comp.lang.c++
moderated). From what I gather there are ambiguity issues arising from
the fact that it is templatized and the C toupper function found in
<ctype.h> (<cctype>) could possibly be chosen instead.”


网上找了几种方案,高手指点:
发表于 2003-7-27 10:49:54 | 显示全部楼层
例1:
// Accept string and convert to lower case
#include <string>
#include <iostream>
#include <locale>
#include <cctype>
using namespace std;

void makeUpper(string& s)
{
        for(string::size_type i=0; i < s.size(); i++)
                s = tolower((unsigned char)s);
}

int main()
{
        cout << "lease input a string: ";
        string s;
        cin >> s;

        makeUpper(s);

        cout << s << endl;
        return 0;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表