标题
服务器之王! [坛主CLQ的服务器程序开发日记,综合了众多C/C++程序崩溃的原因,强烈推荐!]
我是马甲
cin.getline()和cin.get()区别 cin.getline()和cin.get()都读取一行输入,直到到达换行符,随后getline()将丢弃换行符,而get()将换行符保留在输入序列中.
#include
using namespace std;
int main(void)
{
const int SIZE = 30;
char szStr1[SIZE], szStr2[SIZE];
/* 如果用cin.get()则需要再两次读取间插个cin.get() */
cout << "Enter szStr1: ";
cin.getline(szStr1, SIZE);
cout << "Enter szStr2: ";
cin.getline(szStr2, SIZE);
cout << "szStr1: " << szStr1 << endl;
cout << "szStr2: " << szStr2 << endl;
return 0;
}
如果是 cin>>string 那么,不但有\n的时候会等到一个字符串,并且在有 空格和 \t 的时候也会,如果是要取得一个完整的行,要用 getline 才行.
clq
服务器程序很难得的又崩溃了一次.原因是程序写文件失败,而没有校验文件就调用一个 delphi 的 dll 处理文件.这时本可以用 delphi 的 try 的,不过从我的经验来说 delphi 的 try 在被 c/c++ 调用时工作得不好,还是时有异常 -- 比如我在朋友的 wap 程序中调用 ado 时一样. 这是我一个不太好的习惯,因为 delphi 有时候用着方便就喜欢用它写点 dll 来用,而 delphi 的可靠性不佳.
其实象 fopen 这样的函数我们以为不会出错,特别是文件存在的时候.不过这种情况在实际服务器中仍然是比较常见的,特别是机器装有监控文件的杀毒软件时,即使没有开这个监控功能. 我第一次是 norton 后又有瑞星等,道理也很简单,因要锁定文件嘛.而且windows系统有时自己也是要锁定文件的.
clq
调用
#pragma pack(1)
进行字节对齐后,一定不能忘记恢复.否则会导致内存访问混乱,出现不可思义的情况.
#pragma pack()//一定不能少这个,否则会导致访问内存混乱
clq
bcb6 实现的 std::string 居然是有问题的!多个字符连接在一起后很容易内容就不对了.特别是里面有 char *, string , += 东西的时候.例如:
std::string expires = "expires="+s_time+"; ";
这样一句简单的代码也会使其出错.
clq
http://www.cppblog.com/lyman/archive/2006/06/15/8580.html
"
若要在图形界面中使用SGI STL,可在VC中调整Project-->Setting(Alt+F7), 设置编译选项,注意使用/MT和/GX,并且引入选项/Ic:\stl4vc\stlport及/libpath:c:\stl4vc\lib。
"
clq
终于找到服务器内存不断增加的原因了,原来是 gd 库生成的图片要用 gdImageDestroy() 函数释放。php 里面是不用的,而我们找到的代码是纯 C 的很少。
clq
"新加坡期货市场" 这个字符串居然不能保存到 mysql 5 的 utf8 编码的 varchar 字段中,没折,只好用回 gbk 编码方式。看来它对 utf8 的支持还是有问题的。
clq
mysql 字符集设置为 gbk.
在执行sql query的时候,碰到了如下问题:
Illegal mix of collations (gb2312_chinese_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='
解决方法是在执行 query 时先执行
SET character_set_connection='gbk'
原因见此帖子。
--------------------------------------------------
当然了最好的办法还是字符串固定为 latin1 好了,不过那样的话对中文进行查询时又要出问题。
--------------------------------------------------
http://blog.bcchinese.net/duckweed/archive/2007/04/03/108397.aspx
解决 Illegal mix of collations (gb2312_chinese_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='
在执行sql query的时候,碰到了如下问题:
Illegal mix of collations (gb2312_chinese_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '=',
下面列出解决 过程,首先想到可能是数据库的编码问题,在my.cnf 中加入 :default-character-coding=gb2312,没起作用。继续在网上找解决方案。
二.发现了一篇不错的文章,现转过来(我转的很不专业,请见谅)
下面要写的是一篇非常无聊的东西,充斥了大量各式各样的编码、转换、客户端、服务器端、连接……呃,我自己都不愿意去看它,但想一想,写下来还是有点意义的,原因有四:
MySQL 4.1 对多语言的支持有了很大变化 (这导致了问题的出现);
尽管大部分的地方 (包括个人使用和主机提供商),MySQL 3 仍然占主导地位;但 MySQL 4.1 是 MySQL 官方推荐的数据库,已经有主机提供商开始提供并将会越来越多;
许多 PHP 程序以 MySQL 作为默认的数据库管理软件,但它们一般不区分 MySQL 4.1 与 4.1 以下版本的区别,笼统地称“MySQL 3.xx.xx 以上版本”就满足安装需求了;
因为 latin1 在许多地方 (下边会详细描述具体是哪些地方) 作为默认的字符集,成功的蒙蔽了许多 PHP 程序的开发者和用户,掩盖了在中文等语言环境下会出现的问题;
简单的说,MySQL 自身的变化和使用 MySQL 的 PHP 程序对此忽略,导致了问题的出现和复杂化,而由于大部分用户使用的是英文,使这种问题不被重视。这里提到的 PHP 程序,主要就 WordPress 而言。
MySQL 4.1 字符集支持的原理
MySQL 4.1 对于字符集的指定可以细化到一台机器上安装的 MySQL,其中的一个数据库,其中的一张表,其中的一栏,应该用什么字符集。但是,传统的 Web 程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?
编译 MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;
安装 MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;
启动 mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的;
此时 character_set_server 被设定为这个默认的字符集;
当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为 character_set_server;
当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集;
在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;
当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集;
这个字符集就是数据库中实际存储数据采用的字符集,mysqldump 出来的内容就是这个字符集下的;
简单的总结一下,如果什么地方都不修改,那么所有的数据库的所有表的所有栏位的都用 latin1 存储,不过我们如果安装 MySQL,一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把 default_character_set 设置为 UTF-8,这保证了缺省情况下,所有的数据库的所有表的所有栏位的都用 UTF-8 存储。
当一个 PHP 程序与 MySQL 建立连接后,这个程序发送给 MySQL 的数据采用的是什么字符集?MySQL 无从得知 (它最多只能猜测),所以 MySQL 4.1 要求客户端必须指定这个字符集,也就是 character_set_client,MySQL 的怪异之处在于,得到的这个字符集并不立即转换为存储在数据库中的那个字符集,而是先转换为 character_set_connection 变量指定的一个字符集;这个 connection 层究竟有什么用我不大明白,但转换为 character_set_connection 的这个字符集之后,还要转换为数据库默认的字符集,也就是说要经过两次转换;当这个数据被输出时,又要由数据库默认的字符集转换为 character_set_results 指定的字符集。
一个典型的环境
典型的环境以我自己的电脑上安装的 MySQL 4.1 为例,我自己的电脑上安装着 Apache 2,PHP 5 和 WordPress 1.5.1.3,MySQL 配置文件中指定了 default_character_set 为 utf8。于是问题出现了:
WordPress 按照默认情况安装,所以所有的表都用 UTF-8 存储数据;
WordPress 默认采用的浏览字符集是 UTF-8 (Options->Reading 中设置),因此所有 WP 页面的 meta 中会说明 charset 是 utf-8;
所以浏览器会以 utf-8 方式显示所有的 WP 页面;这样一来 Write 的所有 Post,和 Comment 都会以 UTF-8 格式从浏览器发送给 Apache,再由 Apache 交给 PHP;
所以 WP 从所有的表单中得到的数据都是 utf-8 编码的;WP 不加转换的直接把这些数据发送给 MySQL;
MySQL 默认设置的 character_set_client 和 character_set_connection 都是 latin1,此时怪异的事情发生了,实际上是 utf-8 格式的数据,被“当作 latin1”转换成……居然还是转换成 latin1,然后再由这个 latin1 转换成 utf-8,这么两次转换,有一部分 utf-8 的字符就丢失了,变成 ??,最后输出的时候 character_set_results 默认是 latin1,也就输出为奇怪的东西了。
最神奇的还不是这个,如果 WordPress 中设置以 GB2312 格式阅读,那么 WP 发送给 MySQL 的 GB2312 编码的数据,被“当作 latin1”转换后,存进数据库的是一种奇怪的格式 (真的是奇怪的格式,mysqldump 出来就能发现,无论当作 utf-8 还是当作 gb2312 来读都是乱码),但如果这种格式以 latin1 输出出来,居然又能变回 GB2312!
这会导致什么现象呢?WP 如果使用 MySQL 4.1 数据库,把编码改用 GB2312 就正常了,可惜,这种正常只是貌似正常。
如何解决问题
如果你已经不耐烦了 (几乎是肯定的),google 一下,会发现绝大部分的解答是,query 之前先执行一下:SET NAMES 'utf8',没错,这是解决方案,但本文的目的是说明,这为什么是解决方案。
要保证结果正确,必须保证数据表采用的格式是正确的,也就是说,至少能够存放所有的汉字,那么我们只有两种选择,gbk 或者 utf-8,下面讨论 utf-8 的情况。
因为配置文件设置的 default_character_set 是 utf8,数据表默认采用的就是 utf-8 建立的。这也应该是所有采用 MySQL 4.1 的主机提供商应该采用的配置。所以我们要保证的只是客户端与 MySQL 交互之间指定编码的正确。
这只有两种可能,客户端以 gb2312 格式发送数据,或者以 utf-8 格式发送数据。
如果以 gb2312 格式发送:
SET character_set_client='gb2312'
SET character_set_connection='utf8' 或者
SET character_set_connection='gb2312'
都是可以的,都能够保证数据在编码转换中不出现丢失,也就是保证存储入数据库的是正确的内容。
怎么保证取出的是正确的内容呢?考虑到绝大部分客户端 (包括 WP),发送数据的编码也就是它所希望收到数据的编码,所以:
SET character_set_results='gb2312'
可以保证取出给浏览器显示的格式就是 gb2312。
如果是第二种情况,客户端以 utf-8 格式发送 (WP 的默认情况),可以采用下述配置:
SET character_set_client='utf8'
SET character_set_connection='utf8'
SET character_set_results='utf8'
这个配置就等价于 SET NAMES 'utf8'。
WP 应该作什么修改
还是那句话,客户端要发给数据库什么编码的数据,数据库是不可能确切知道的,只能让客户端自己说明白,所以,WP 是必须发送正确的 SET... 给 MySQL 的。怎么发送最合适呢?台湾的 pLog 同仁给出了一些建议:
首先,测试服务器是否 >= 4.1,编译时是否加入了 UTF-8 支持;是则继续
然后测试数据库以什么格式存储 ($dbEncoding);
SET NAMES $dbEncoding
对于第二点,WP 的情况是不同的,按照上面的典型配置,只要用 WP,肯定数据库是用 UTF-8 存储的,所以要根据用户设置的以 GB2312 还是 UTF-8 浏览来判断 (bloginfo('charset')),但这个值是要连接数据库以后才能得到的,所以效率最高的方式是连接数据库之后,根据这个配置设置一次 SET NAMES,而不必每次查询之前都设置一遍。
我的修改方式是这样的,在 wp_includes/wp-db.php 中增加:
function set_charset($charset)
{
// check mysql version first.
$serverVersion = mysql_get_server_info($this->dbh);
$version = explode('.', $serverVersion);
if ($version[0] < 4) return;
// check if utf8 support was compiled in
$result = mysql_query("SHOW CHARACTER SET like 'utf8'",
$this->dbh);
if (mysql_num_rows($result) < = 0) return;
if ($charset == 'utf-8' || $charset == 'UTF-8')
$charset = 'utf8';
@mysql_query("SET NAMES '$charset'", $this->dbh);
}
在 wp-settings.php 的 require (ABSPATH . WPINC . '/vars.php'); 后增加:
$wpdb->set_charset(get_bloginfo('charset'));
http://blog.jjgod.org/2005/07/31/a-mysql-41-story/#more-51
三.
根据下列关键部分,成功解决了数据库中中文的显示问题,但是上述问题仍未解决。
这只有两种可能,客户端以 gb2312 格式发送数据,或者以 utf-8 格式发送数据。
如果以 gb2312 格式发送:
SET character_set_client='gb2312'
SET character_set_connection='utf8' 或者
SET character_set_connection='gb2312'
都是可以的,都能够保证数据在编码转换中不出现丢失,也就是保证存储入数据库的是正确的内容。
怎么保证取出的是正确的内容呢?考虑到绝大部分客户端 (包括 WP),发送数据的编码也就是它所希望收到数据的编码,所以:
SET character_set_results='gb2312'
可以保证取出给浏览器显示的格式就是 gb2312。
如果是第二种情况,客户端以 utf-8 格式发送 (WP 的默认情况),可以采用下述配置:
SET character_set_client='utf8'
SET character_set_connection='utf8'
SET character_set_results='utf8'
这个配置就等价于 SET NAMES 'utf8'。
四.通过show VARIABLES;可以显示出Mysql所有的变量的值的情况,显示:
show VARIABLES like 'collation%';
+----------------------+-------------------+
| Variable_name | Value |
+----------------------+-------------------+
| collation_connection | gb2312_chinese_ci |
| collation_database | gb2312_chinese_ci |
| collation_server | gb2312_chinese_ci |
+----------------------+-------------------+
show VARIABLES like 'character%';
+--------------------------+---------------------------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------------------------+
| character_set_client | gb2312 |
| character_set_connection | gb2312 |
| character_set_database | gb2312 |
| character_set_filesystem | binary |
| character_set_results | gb2312 |
| character_set_server | gb2312 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-standard-5.0.22-linux-i686-glibc23/share/mysql/charsets/ |
+--------------------------+---------------------------------------------------------------------------+
但还是不行,郁闷了。发现的另外一个问题就是:数据库重起后,就恢复到默认值了,需要在数据库的配置文件
support-files/my-huge.cnf(/etc/my.cnf)下增加:default-character-set = utf8
到client和mysqld
[client]
……
default-character-set = utf8
[mysqld]
……
default-character-set = utf8
另:在创建表的时候,加上:CREATE TABLE IF NOT EXISTS table_name (key, key, key)
VALUES (value, value, value)
DEFAULT CHARACTER='gb2312' 这样就可以了。
如何使 character-set-database='gb2312'成为默认值呢(尚未解决)?
五.参考资料
1.上述二中的资料
2.http://www.cublog.cn/u/29011/showart.php?id=254188
设置 MySQL 的 my.cnf 文件,在 [client]/[mysqld]部分都设置默认的字符集:
CODE:
[Copy to clipboard]
[client]
default-character-set = utf8
[mysqld]
default-character-set = utf8
该设置需要重新启动 MySQL 服务器。启动之后在 mysql 命令行下可以用 'status' 命令查看:
CODE:
[Copy to clipboard]
mysql> status
--------------
mysql Ver 14.12 Distrib 5.0.26, for -netbsdelf (i386) using EditLine wrapper
Connection id: 16
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.0.26-log
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /tmp/mysql.sock
Uptime: 1 hour 7 min 49 sec
* 在创建表的时候,加上 default character='utf8' 这样的语句:
CODE:
[Copy to clipboard]
CREATE TABLE IF NOT EXISTS table_name (key, key, key)
VALUES (value, value, value)
DEFAULT CHARACTER='utf8'
* 在执行 MYSQL 语句时先执行 'SET NAMES 'utf8'' 语句:
CODE:
[Copy to clipboard]
SET NAMES 'utf8'
这样基本就能搞定中文问题了。
clq
今天导入数据到 mysql 发现速度特慢。仔细检察后发现是删除旧数据时很慢,原来是一条条的删除,改为删除一批再一条条插入多条数据就快很多。以前一直以为速度是差不多的,没想到单纯的添加即使是在有多个字段被索引的情况下仍然极快。
这也得出了一个结论,更新索引的速度非常快,至少远远大根据这些索引删除一条记录。
///*
//先删除//在这里删除的话非常慢
//m_Mysqldb.LExecuteSql("delete from kline_day where 1=1 "
// " and year='" + int_to_str(year) + "' "
// " and month='" + int_to_str(month) + "' "
// " and day='" + int_to_str(day) + "' "
// " and jys_code ='" + jyscode + "' limit 1 ");
//再插入
m_Mysqldb.LExecuteSql("insert into kline_day "
" (mark,jys_code,close,open,high,low,volume,amount,year,month,day) "
" values ("
" '1'," //" '" + int_to_str(tmplist[i].mark) + "',"
" '" + jyscode + "',"
//" '" + pbcode + "',"
//" '" + name + "',"
" '" + float_to_str((float)k.m_uiClosePrice/100) + "',"
" '" + float_to_str((float)k.m_uiOpenPrice/100) + "',"
" '" + float_to_str((float)k.m_uiMaxPrice/100) + "',"
" '" + float_to_str((float)k.m_uiMinPrice/100) + "',"
//" '" + float_to_str(tmplist[i].now) + "',"
//" '" + float_to_str(tmplist[i].avg) + "',"
" '" + int_to_str(k.m_uiVolume) + "',"
" '" + float_to_str((float)k.m_uiSum/100) + "',"
//" '" + int_to_str(tmplist[i].time) + "',"
" '" + int_to_str(year) + "',"
" '" + int_to_str(month) + "',"
" '" + int_to_str(day) + "'"
" ) "
);
//*/
clq
苍天,好象是因为 mysql 5 的复合索引无效,为每个字段独立建立一个索引后,速度那个快!
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.