C言語 / C++

[ガラケー版(QRコード)]
アクセス記録[推移 / PV内訳(過去1日 / 過去1週間) / 外部アクセス元 (昨日 / 過去1週間) / ログイン論客足跡]
プロフィール私書(メール)
   /   /送済
評価(一覧   /)
投票   /共:   /
ファン登録
作品/情報/
DB構築()
ブログ
[書く]
攻略記事リンク集
My Play List
 作成日時分類記事タイトル
12010/09/05C言語 / C++..lib1stclass::C/C++基本処理ライブラ..
22010/02/18C言語 / C++..文字::文字の標準化処理(全角→半角、半角→全角)..
32010/02/18C言語 / C++..文字::libiconvのバージョンとC++での使い..
42010/02/13C言語 / C++..Apache Module::Apacheモジュール..
52009/11/29C言語 / C++..boost::boostのインストール手順..
=>古記事
 反応日時来客名来客者の最近のメッセージ
12017/05/11uyam度々、すごーく、すいません。こんばんわ!uyamです。先日、..
22017/05/11オルタフォースお帰りなさいませ。そして、諸問題への対処お疲れさまでした。毎..
32017/04/20 非論客コメント
42017/02/25Merciこんばんは。サーバー移転後からだと思いますが、以前は見られた..
52017/02/17ねこじゃらしブログ投稿やコメントをしようとすると、たまにエラーになります..
その他最近のコメント
1.
2010/09/05 C言語 / C++ > lib1stclass > C/C++基本処理ライブラリ公開」
[この書込みのみ表示(記事URL紹介用) / 編集 / 削除 / トラバ送信 / 共有分類に追加(タグ付け)]

1. C/C++の基本処理ライブラリをlib1stclassという形で公開
2. lib1stclassで出来る事
3. ヘッダーファイル
4. t/test.cpp(2010/09/05版)

    1. C/C++の基本処理ライブラリをlib1stclassという形で公開

minakoe.jp等のバックエンドで使われているC/C++のコードから、ベーシックな機能を抽出してまとめて、lib1stclassという形でsourceforgeにて公開しました。
http://sourceforge.jp/projects/lib1stclass/
sourceforge使ってみるのは初めてで不手際な部分もあるかもしれませんが、gitレポジトリへのアップと、ソースファイルのダウンロード用tar.gzのアップはしてあります。
    2. lib1stclassで出来る事

lib1stclassの機能はC言語とC++のプログラムから使う事が出来ます。
また出来る事は同じですが、インターフェースはC言語版とC++版で分離されています。
何が出来るか&使い方は、動作テスト兼使い方例示プログラムの
t/test.cpp
を見ると分かるようになっています。
出来る事は次第に拡張されていく予定です。

2010/09/05時点 出来る事
1.数字かどうかの判別
2.ホスト名からIPを得る
3.相対パスから絶対パスを得る
4.ディレクトリを再帰的に作る
5.パス全体を消去(ディレクトリを再帰的に消去)
6.int型をchar型に変換
7.文字を逆並びにする
8.ファイルシステムに使えないアスキー文字を「_」に変換
9./dev/shm上への一時ファイル生成
10.安全なstrcat

    3. ヘッダーファイル

C言語版
===============================
#include<sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif

int host2ip(const char *server, char *ip);
int is_num(const char *moji);
int itoa(int n, char s[]);
int reverse_char(char s[]);
int rmkdir(const char *check_dir);
int rel2abs(const char *rel_path, char *abs_path);
int remove_path(const char *path);
int remove_not_file_char(const char *str, char *dst);
int safe_strcat(char *dst, const char *append, size_t size);
int shmf(const char *file, char *shmfile);

#ifdef __cplusplus
};
#endif
===============================

C++版
#ifndef INCLUDED_1stclass
#define INCLUDED_1stclass
#include<string>
using namespace std;

class firstclass {
public:
  string host2ip(const string server);
  int is_num(const string moji);
  int itoa(int n, char s[]);
  int rmkdir(const string check_dir);
  string rel2abs(const string in_rel_path);
  int remove_path(const string path);
  string remove_not_file_char(const string *str);
  int reverse_char(char s[]);
  int safe_strcat(char *dst, const char *append, size_t size);
  string shmf(const string file);
};
#endif

    4. t/test.cpp(2010/09/05版)

作動テスト兼使い方例示プログラム

/*
* See the file LICENSE for redistribution information.
*
* Copyright: 2010- 1stclass.co.jp.  All rights reserved.
*
* Created by Hajime Kurita
*/
#include <string>
#include <string.h>
#include <iostream>
#include <sys/stat.h>
#include "../1stclass.hpp"
#include "../1stclass.h"
using namespace std;

class tester{
public:
  tester(){ok=0;bad=0;};
  void test();
  void report();
private:
  int ok;
  int bad;
};

void tester::test(){
  firstclass fst;
  struct stat st;
/////////////////////////////////////////////////////
// is_num:
// Judge whether this is number or not
// 数字かどうかの判別
  if(fst.is_num("2") && fst.is_num("test")==0){
    cout << "is_num/C++: ok "<< endl;
    ok++;
  }
  else{
    cout << "is_num/C++: bad" << endl;
    bad++;
  }

  if(is_num("2") && is_num("test")==0){
    cout << "is_num/C: ok "<< endl;
    ok++;
  }
  else{
    cout << "is_num/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// host2ip:
// Get IP from host name
// ホスト名からIPを得る
  string server="www.yahoo.co.jp";
  string ip=fst.host2ip(server);
  if( (ip.at(0) - '1'>=0) && (ip.at(0) - '1'<=9) ){
    cout << "host2ip/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "host2ip/C++: bad" << endl;
    bad++;
  }

  char c_server[]="www.yahoo.co.jp";
  char c_ip[32]="";
  host2ip(c_server, c_ip);
  if( (c_ip[0] - '1' >=0) && (c_ip[0] - '1' <=9) ){
    cout << "host2ip/C: ok" << endl;
    ok++;
  }
  else{
    cout << "host2ip/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// rel2abs:
// Get absolute path from relative path
// 相対パスから絶対パスを得る
  string rel_path="../lib1stclass/1/2/3";
  string abs_path=fst.rel2abs(rel_path);
  if( abs_path.find("/")==0 &&  abs_path.find("lib1stclass/1/2/3")!=string::npos){
    cout << "rel2abs/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "rel2abs/C++: bad" << endl;
    bad++;
  }
  
  char rel_path_char[]="../lib1stclass/1/2/3";
  char abs_path_char[1024]="";
  rel2abs(rel_path_char, abs_path_char);
  if( abs_path_char[0]=='/' && strstr(abs_path_char, "lib1stclass/1/2/3")!=NULL){
    cout << "rel2abs/C: ok" << endl;
    ok++;
  }
  else{
    cout << "rel2abs/C: bad" << "/" << abs_path_char << endl;
    bad++;
  }

  string rel_path2="lib1stclass/1/2/3";
  string abs_path2=fst.rel2abs(rel_path2);
  if( abs_path2.find("/")==0 &&  abs_path2.find("/lib1stclass/1/2/3")!=string::npos){
    cout << "rel2abs/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "rel2abs/C++: bad" << endl;
    bad++;
  }
  
  char rel_path_char2[]="lib1stclass/1/2/3";
  char abs_path_char2[1024]="";
  rel2abs(rel_path_char2, abs_path_char2);
  if( abs_path_char2[0]=='/' && strstr(abs_path_char2, "/lib1stclass/1/2/3")!=NULL){
    cout << "rel2abs 2/C: ok" << endl;
    ok++;
  }
  else{
    cout << "rel2abs 2/C: bad" << endl;
    bad++;
  }
  
  string rel_path3="/tmp/1/2/3";
  string abs_path3=fst.rel2abs(rel_path3);
  if( abs_path3=="/tmp/1/2/3"){
    cout << "rel2abs 3/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "rel2abs 3/C++: bad" << endl;
    bad++;
  }
  
  char rel_path_char3[]="/tmp/1/2/3";
  char abs_path_char3[1024]="";
  rel2abs(rel_path_char3, abs_path_char3);
  if( strcmp(abs_path_char3, "/tmp/1/2/3")==0){
    cout << "rel2abs 3/C: ok" << endl;
    ok++;
  }
  else{
    cout << "rel2abs 3/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// rmkdir:
// mkdir recursively
// ディレクトリを再帰的に作る
  fst.rmkdir("test_dir/depth2");
  if(stat("test_dir/depth2", &st)==0){
    cout << "rmkdir/C++: ok" << endl;
    ok++;

/////////////////////////////////////////////////////
// remove_path:
// Remove path completely
// パス全体を消去(ディレクトリを再帰的に消去)
    fst.remove_path("test_dir");
    if(stat("test_dir", &st)!=0){
      cout << "remove_path/C++: ok" << endl;
      ok++;
    }
    else{
      cout << "remove_path/C++: bad" << endl;
      bad++;
    }
  }
  else{
    cout << "rmkdir/C++: bad" << endl;
    bad++;
  }

  rmkdir("test_dir/depth_2");
  if(stat("test_dir/depth_2", &st)==0){
    cout << "rmkdir/C: ok" << endl;
    ok++;
    remove_path("test_dir");
    if(stat("test_dir", &st)!=0){
      cout << "remove_path/C: ok" << endl;
      ok++;
    }
    else{
      cout << "remove_path/C: bad" << endl;
      bad++;
    }
  }
  else{
    cout << "rmkdir/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// itoa:
// Convert int to char
// int型をchar型に変換
  int integer=12345;
  char itoa_str[6]="";

  fst.itoa(integer, itoa_str);
  if (strcmp(itoa_str,"12345") == 0){
    cout << "itoa/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "itoa/C++: bad" << endl;
    bad++;
  }

  itoa_str[0]='\0';
  itoa(integer, itoa_str);
  if (strcmp(itoa_str,"12345") == 0){
    cout << "itoa/C: ok" << endl;
    ok++;
  }
  else{
    cout << "itoa/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// reverse_char:
// Reverse char
// charを逆並びにする
  char example1[]="1234";
  fst.reverse_char(example1);
  if (strcmp(example1,"4321") == 0){
    cout << "reverse_char/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "reverse_char/C++: bad" << endl;
    bad++;
  }
  
  char example2[]="1234";
  reverse_char(example2);
  if (strcmp(example2,"4321") == 0){
    cout << "reverse_char/C: ok" << endl;
    ok++;
  }
  else{
    cout << "reverse_char/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// remove_not_file_char:
// Convert ascii characters which cannot be used for file name into "_"
// ファイルシステムに使えないアスキー文字を「_」に変換
  string not_file_str="bk\\sl/sm:as*qt?dq\"lt<rt>vt|";
  string file_str=fst.remove_not_file_char(&not_file_str);
  if (file_str=="bk_sl_sm_as_qt_dq_lt_rt_vt_"){
    cout << "remove_not_file_char/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "remove_not_file_char/C++: bad" << endl;
    bad++;
  }

  char not_file_char[]="bk\\sl/sm:as*qt?dq\"lt<rt>vt|";
  char file_char[1024]="";
  remove_not_file_char(not_file_char, file_char);
  if (strcmp(file_char,"bk_sl_sm_as_qt_dq_lt_rt_vt_")==0){
    cout << "remove_not_file_char/C: ok" << endl;
    ok++;
  }
  else{
    cout << "remove_not_file_char/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// shmf:
// Create temporary file on /dev/shm/
// /dev/shm/上への一時ファイル生成
  string file="/tmp/test.txt";
  if(fst.shmf(file)=="/dev/shm/_tmp_test.txt"){
    cout << "shmf/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "shmf/C++: bad" << endl;
    bad++;
  }

  char tfile[]="/tmp/test.txt";
  char sfile[1024]="";
  shmf(tfile, sfile);
  if(strcmp(sfile, "/dev/shm/_tmp_test.txt")==0){
    cout << "shmf/C: ok" << endl;
    ok++;
  }
  else{
    cout << "shmf/C: bad" << endl;
    bad++;
  }

/////////////////////////////////////////////////////
// safe_strcat:
// Safe strcat
// 安全なstrcat
  char a1[20]="";
  char b1[]="12345";
  fst.safe_strcat(a1, b1, sizeof(a1));
  if(strcmp(a1,b1)==0){
    cout << "safe_strcat 1/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "safe_strcat 1/C++: bad" << endl;
    bad++;
  }
  
  char a2[20]="";
  char b2[]="12345";
  safe_strcat(a2, b2, sizeof(a2));
  if(strcmp(a2,b2)==0){
    cout << "safe_strcat 2/C: ok" << endl;
    ok++;
  }
  else{
    cout << "safe_strcat 2/C: bad" << endl;
    bad++;
  }
  
  char a3[2]="";
  char b3[]="12345";
  fst.safe_strcat(a3, b3, sizeof(a3));
  if(strcmp(a3,"1")==0){
    cout << "safe_strcat 3/C++: ok" << endl;
    ok++;
  }
  else{
    cout << "safe_strcat 3/C++: bad" << endl;
    bad++;
  }
  
  char a4[2]="";
  char b4[]="12345";
  safe_strcat(a4, b4, sizeof(a4));
  if(strcmp(a4,"1")==0){
    cout << "safe_strcat 4/C: ok" << endl;
    ok++;
  }
  else{
    cout << "safe_strcat 4/C: bad" << endl;
    bad++;
  }
}

void tester::report(){
  cout << "ok=" << ok << "\t" << "bad=" << bad << endl;
}

int main(){
  tester tester;
  tester.test();
  tester.report();
  return 0;
}


コメントする

2.
2010/02/18 同日2番目 C言語 / C++ > 文字 > 文字の標準化処理(全角→半角、半角→全角)」
[この書込みのみ表示(記事URL紹介用) / 編集 / 削除 / トラバ送信 / 共有分類に追加(タグ付け)]拍手:1個

文字の半角・全角の標準化処理は、検索や統計処理の為には必須な処理ですが、C++/Cでそういうコードが見つからなかったので自分で書いてみました。

CharConverter.hpp
/* Programmed by Hajime Kurita */
/* URL: http://www.accessup.org/ */
/* This program is for EUC String */

#ifndef INCLUDED_CharConverter
#define INCLUDED_CharConverter

#include <boost/regex.hpp>
#include <iostream>
#include <map>
#include <string>
#include <vector>

using namespace std;

const boost::regex euc_regex("\\A(?:[\\x00-\\x7F]|\\x8E[\\xA1-\\xDF]|[\\xA1\\xB0-\\xCE\\xD0-\\xF3][\\xA1-\\xFE]|\\xA2[\\xA1-\\xAE\\xBA-\\xC1\\xCA-\\xD0\\xDC-\\xEA\\xF2-\\xF9\\xFE]|\\xA3[\\xB0-\\xB9\\xC1-\\xDA\\xE1-\\xFA]|\\xA4[\\xA1-\\xF3]|\\xA5[\\xA1-\\xF6]|\\xA6[\\xA1-\\xB8\\xC1-\\xD8]|\\xA7[\\xA1-\\xC1\\xD1-\\xF1]|\\xA8[\\xA1-\\xC0]|[\\xA9-\\xAF\\xF5-\\xFE][\\xA1-\\xFE]|\\xCF[\\xA1-\\xD3]|\\xF4[\\xA1-\\xA6])\\Z");
class CharConverter{
public:
  CharConverter();
  ~CharConverter(){};
  string Normalize(string);
private:
  map<string,string> normalized_euc;
};
#endif

CharConverter.cpp
/* Programmed by Hajime Kurita */
/* URL: http://www.accessup.org/ */
/* This program is for EUC String */

#include "CharConverter.hpp"

using namespace std;

CharConverter::CharConverter(){
  normalized_euc["。"]="。";
  normalized_euc["、"]="、";
  normalized_euc["「"]="「";
  normalized_euc["」"]="」";
  normalized_euc["・"]="・";
  normalized_euc["ー"]="ー";
  normalized_euc[" "]=" ";
  normalized_euc["ァ"]="ァ";
  normalized_euc["ア"]="ア";
  normalized_euc["ィ"]="ィ";
  normalized_euc["イ"]="イ";
  normalized_euc["ゥ"]="ゥ";
  normalized_euc["ウ"]="ウ";
  normalized_euc["ェ"]="ェ";
  normalized_euc["エ"]="エ";
  normalized_euc["ォ"]="ォ";
  normalized_euc["オ"]="オ";
  normalized_euc["カ"]="カ";
  normalized_euc["キ"]="キ";
  normalized_euc["ク"]="ク";
  normalized_euc["ケ"]="ケ";
  normalized_euc["コ"]="コ";
  normalized_euc["サ"]="サ";
  normalized_euc["シ"]="シ";
  normalized_euc["ス"]="ス";
  normalized_euc["セ"]="セ";
  normalized_euc["ソ"]="ソ";
  normalized_euc["タ"]="タ";
  normalized_euc["チ"]="チ";
  normalized_euc["ッ"]="ッ";
  normalized_euc["ツ"]="ツ";
  normalized_euc["テ"]="テ";
  normalized_euc["ト"]="ト";
  normalized_euc["ナ"]="ナ";
  normalized_euc["ニ"]="ニ";
  normalized_euc["ヌ"]="ヌ";
  normalized_euc["ネ"]="ネ";
  normalized_euc["ノ"]="ノ";
  normalized_euc["ハ"]="ハ";
  normalized_euc["ヒ"]="ヒ";
  normalized_euc["フ"]="フ";
  normalized_euc["ヘ"]="ヘ";
  normalized_euc["ホ"]="ホ";
  normalized_euc["マ"]="マ";
  normalized_euc["ミ"]="ミ";
  normalized_euc["ム"]="ム";
  normalized_euc["メ"]="メ";
  normalized_euc["モ"]="モ";
  normalized_euc["ャ"]="ャ";
  normalized_euc["ヤ"]="ヤ";
  normalized_euc["ュ"]="ュ";
  normalized_euc["ユ"]="ユ";
  normalized_euc["ョ"]="ョ";
  normalized_euc["ヨ"]="ヨ";
  normalized_euc["ラ"]="ラ";
  normalized_euc["リ"]="リ";
  normalized_euc["ル"]="ル";
  normalized_euc["レ"]="レ";
  normalized_euc["ロ"]="ロ";
  normalized_euc["ワ"]="ワ";
  normalized_euc["ヲ"]="ヲ";
  normalized_euc["ン"]="ン";
  normalized_euc["A"]="A";
  normalized_euc["B"]="B";
  normalized_euc["C"]="C";
  normalized_euc["D"]="D";
  normalized_euc["E"]="E";
  normalized_euc["F"]="F";
  normalized_euc["G"]="G";
  normalized_euc["H"]="H";
  normalized_euc["I"]="I";
  normalized_euc["J"]="J";
  normalized_euc["K"]="K";
  normalized_euc["L"]="L";
  normalized_euc["M"]="M";
  normalized_euc["N"]="N";
  normalized_euc["O"]="O";
  normalized_euc["P"]="P";
  normalized_euc["Q"]="Q";
  normalized_euc["R"]="R";
  normalized_euc["S"]="S";
  normalized_euc["T"]="T";
  normalized_euc["U"]="U";
  normalized_euc["V"]="V";
  normalized_euc["W"]="W";
  normalized_euc["X"]="X";
  normalized_euc["Y"]="Y";
  normalized_euc["Z"]="Z";
  normalized_euc["a"]="a";
  normalized_euc["b"]="b";
  normalized_euc["c"]="c";
  normalized_euc["d"]="d";
  normalized_euc["e"]="e";
  normalized_euc["f"]="f";
  normalized_euc["g"]="g";
  normalized_euc["h"]="h";
  normalized_euc["i"]="i";
  normalized_euc["j"]="j";
  normalized_euc["k"]="k";
  normalized_euc["l"]="l";
  normalized_euc["m"]="m";
  normalized_euc["n"]="n";
  normalized_euc["o"]="o";
  normalized_euc["p"]="p";
  normalized_euc["q"]="q";
  normalized_euc["r"]="r";
  normalized_euc["s"]="s";
  normalized_euc["t"]="t";
  normalized_euc["u"]="u";
  normalized_euc["v"]="v";
  normalized_euc["w"]="w";
  normalized_euc["x"]="x";
  normalized_euc["y"]="y";
  normalized_euc["z"]="z";
  normalized_euc["1"]="1";
  normalized_euc["2"]="2";
  normalized_euc["3"]="3";
  normalized_euc["4"]="4";
  normalized_euc["5"]="5";
  normalized_euc["6"]="6";
  normalized_euc["7"]="7";
  normalized_euc["8"]="8";
  normalized_euc["9"]="9";
  normalized_euc["0"]="0";
  normalized_euc["!"]="!";
  normalized_euc["”"]="\"";
  normalized_euc["#"]="#";
  normalized_euc["$"]="$";
  normalized_euc["%"]="%";
  normalized_euc["&"]="&";
  normalized_euc["’"]="'";
  normalized_euc["("]="(";
  normalized_euc[")"]=")";
  normalized_euc["="]="=";
  normalized_euc["^"]="^";
  normalized_euc["|"]="|";
  normalized_euc["¥"]="\\";
  normalized_euc["@"]="@";
  normalized_euc["["]="[";
  normalized_euc[";"]=";";
  normalized_euc[":"]=":";
  normalized_euc["]"]="]";
  normalized_euc[","]=",";
  normalized_euc["."]=".";
  normalized_euc["/"]="/";
  normalized_euc["`"]="`";
  normalized_euc["{"]="{";
  normalized_euc["+"]="+";
  normalized_euc["*"]="*";
  normalized_euc["}"]="}";
  normalized_euc["<"]="<";
  normalized_euc[">"]=">";
  normalized_euc["?"]="?";
  normalized_euc["_"]="_";
  normalized_euc["\t"]=" ";
}

string CharConverter::Normalize(string euc_str){
  string converted_str="";
  string char_str="";
  string last_char="";
  for (string::iterator iter = euc_str.begin(); iter != euc_str.end(); ++iter) {
    char_str+=tolower(*iter);
    if(regex_match(char_str, euc_regex)){
      if(char_str=="゙" && converted_str.length()>=2){
        last_char=converted_str[converted_str.length()-2]+converted_str[converted_str.length()-1];
        if(last_char=="ウ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ヴ");
        }
        else if(last_char=="カ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ガ");
        }
        else if(last_char=="キ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ギ");
        }
        else if(last_char=="ク"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("グ");
        }
        else if(last_char=="コ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ゴ");
        }
        else if(last_char=="サ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ザ");
        }
        else if(last_char=="シ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ジ");
        }
        else if(last_char=="ス"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ズ");
        }
        else if(last_char=="セ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ゼ");
        }
        else if(last_char=="ソ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ゾ");
        }
        else if(last_char=="タ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ダ");
        }
        else if(last_char=="チ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ヂ");
        }
        else if(last_char=="ツ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ヅ");
        }
        else if(last_char=="テ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("デ");
        }
        else if(last_char=="ト"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ド");
        }
        else if(last_char=="ハ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("バ");
        }
        else if(last_char=="ヒ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ビ");
        }
        else if(last_char=="フ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ブ");
        }
        else if(last_char=="ヘ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ベ");
        }
        else if(last_char=="ホ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ボ");
        }
      }
      else if(char_str=="゚" && converted_str.length()>=2){
        last_char=converted_str[converted_str.length()-2]+converted_str[converted_str.length()-1];
        if(last_char=="ハ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("パ");
        }
        else if(last_char=="ヒ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ピ");
        }
        else if(last_char=="フ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("プ");
        }
        else if(last_char=="ヘ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ペ");
        }
        else if(last_char=="ホ"){
          converted_str.erase(converted_str.length()-2, converted_str.length()-1);
          converted_str.append("ポ");
        }
      }
      else if(normalized_euc.count(char_str)){
        converted_str.append(normalized_euc[char_str]);
      }
      else{
        if(char_str==" "){
          if(converted_str.length()==0 ||
             (iter==euc_str.end()-1) ||
             (converted_str.length()>0 && converted_str[converted_str.length()-1]==' ')
             ){
          }
          else{
            converted_str.append(char_str);
          }
        }
        else{
          converted_str.append(char_str);
        }
      }
      char_str="";
    }
  }
  return converted_str;
}

呼び出し側
#include "CharConverter.hpp"
...
CharConverter char_converter;
...
string normalized_str;
normalized_str=char_converter.Normalize(raw_str);


コメントする1個

3.
2010/02/18 C言語 / C++ > 文字 > libiconvのバージョンとC++での使い方」
[この書込みのみ表示(記事URL紹介用) / 編集 / 削除 / トラバ送信 / 共有分類に追加(タグ付け)]拍手:2個

1. iconvのバージョンの問題
2. インストールコマンド例
3. libiconvのC++からの使い方

    1. iconvのバージョンの問題

C言語の文字コード変換ライブラリとしては、iconvとnkfが有名ですが、nkfは元々ライブラリになっていないし、iconvはiconvで使いづらいですよね。
それはそれとして、iconvは現在最新版のCentOS5.4などに付属しているものは古い物(2006年版)なので、コアダンプするようなバグがあります。
バグを避けるには最新版(この記事の時点で2009年版)を手動でインストールして使った方が良いでしょう。

公式: http://www.gnu.org/software/libiconv/
    2. インストールコマンド例

VERSION=1.14;
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-$VERSION.tar.gz
tar xvfz libiconv-$VERSION.tar.gz; 
cd libiconv-$VERSION;
./configure 
make
make install
    3. libiconvのC++からの使い方

インストールは/usr/localの方にされるので、コンパイルする時には
-L/usr/local/lib/ -I/usr/local/include/ -liconv
をオプションに付けて実行する。
libiconv自体はCですが、C++から使うには↓な感じでWrapperを作ってWrapper経由で使う。

IconvWrapper.hpp
#ifndef INCLUDED_IconvWrapper
#define INCLUDED_IconvWrapper

#include <iconv.h>
#include <string>
#include <iostream>
#include <errno.h>
#include <string.h>

using namespace std;

class IconvWrapper{
public:
  IconvWrapper();
  ~IconvWrapper();
  string from_to(string src, string fromcode, string tocode);

protected:
  iconv_t open(const char* tocode, const char* fromcode);
  void close();

private:
  iconv_t conversion_descriptor;
  char* tocode_cache;
  char* fromcode_cache;
};

#endif

※2012/10/24 に不正な文字が入ってきた時起きうる問題について対応

IconvWrapper.cpp
#include "IconvWrapper.hpp"

using namespace std;

IconvWrapper::IconvWrapper(){
  conversion_descriptor = 0;
  tocode_cache = NULL;
  fromcode_cache = NULL;
}

IconvWrapper::~IconvWrapper(){
  close();
}

iconv_t IconvWrapper::open(const char* tocode, const char* fromcode){
  if(conversion_descriptor  > 0){
    close();
  }
  iconv_t ret = iconv_open(tocode, fromcode);
  if(ret > 0) {
    conversion_descriptor  = ret;
    tocode_cache = new char[strlen(tocode) + 1];
    strcpy(tocode_cache, tocode);
    fromcode_cache = new char[strlen(fromcode) + 1];
    strcpy(fromcode_cache, fromcode);
  }
  else{
    conversion_descriptor  = 0;
  }
  return conversion_descriptor ;
}

void IconvWrapper::close(){
  if(conversion_descriptor  > 0){
    iconv_close(conversion_descriptor );
    conversion_descriptor  = 0;
  }
  
  if(tocode_cache){
    delete [] tocode_cache;
    tocode_cache = NULL;
  }
  
  if(fromcode_cache){
    delete [] fromcode_cache;
    fromcode_cache = NULL;
  }
}

string IconvWrapper::from_to(string src, string fromcode, string tocode){
  string ret;
  int break_flag=0;
      
  if (!tocode_cache || !fromcode_cache || tocode != tocode_cache || fromcode != fromcode_cache) {
    open(tocode.c_str(), fromcode.c_str());
  }
  char* inbuf = const_cast<char*>(src.c_str());
  size_t inbytesleft = src.size();

  char* dst = new char[inbytesleft*2+1];
  char* outbuf = dst;
  size_t outbytesleft = inbytesleft;
  size_t dstmax = inbytesleft;

  while (inbytesleft > 0) {
    char* inbuf_org = inbuf;
    size_t n = iconv(conversion_descriptor , &inbuf, &inbytesleft, &outbuf, &outbytesleft);
    if ((n != (size_t)-1 && inbytesleft == 0) || (errno == EINVAL)) {
       /* EINVAL = An incomplete multibyte sequence has been encountered in the input. */
      inbytesleft = 0;
      ret.append(dst, 0, dstmax-outbytesleft);
    }
    else {
      
      switch (errno) {
      case E2BIG: /* There is not sufficient room at *outbuf. And something wrong can happen, so break the loop*/
        ret.append(dst, 0, dstmax-outbytesleft);
        outbuf = dst;
        outbytesleft = dstmax;
        break_flag++;
        break;
      case EILSEQ: /* An invalid multibyte sequence has been encountered in the input. */
        ret.append(dst, 0, dstmax-outbytesleft);
        ret.append(inbuf, 0, 1);
        inbuf++;
        inbytesleft--;
        outbuf = dst;
        outbytesleft = dstmax;
        break;
      default:
        ret.append(inbuf_org);
        inbytesleft = 0;
        break;
      }
      
      if(break_flag){
         break;
      }
    }
  }
  outbuf = dst;
  outbytesleft = dstmax;
  if ( iconv(conversion_descriptor , NULL, NULL, &outbuf, &outbytesleft) != (size_t)-1) {
    ret.append(dst, 0, dstmax-outbytesleft);
  }
  delete [] dst;
  return ret;
}

呼び出し側
#include "IconvWrapper.hpp"
...
IconvWrapper iconv;
...
string euc_string;
euc_string=iconv.from_to(sjis_string,"shift_jis", "euc-jp");

上記コードを使ったmakeの例
.PHONY: all
all: LogAnalyzer

LogAnalyzer: LogAnalyzer.cpp
 g++ -Wall -O3 -finline-functions -o -L/usr/local/lib:/usr/lib -I/usr/local/include/boost -I/usr/include/boost-1_33_1/ -I/usr/local/include/ -I../common/ -o LogAnalyzer LogAnalyzer.cpp ../common/IconvWrapper.cpp ../common/CGICommon.cpp ../common/CharConverter.cpp -liconv /usr/local/lib/libboost_regex.so

.PHONY: install
install:
 mkdir -p /home/www/bin/;
 mv -f LogAnalyzer /home/www/bin/;
 cp /home/www/bin/LogAnalyzer .;

.PHONY: clean
clean:
 rm LogAnalyzer;
 rm *~;
 rm *.o;


コメントする2個

4.
2010/02/13 同日2番目 C言語 / C++ > Apache Module > Apacheモジュールの作り方(2.x系)」
[この書込みのみ表示(記事URL紹介用) / 編集 / 削除 / トラバ送信 / 共有分類に追加(タグ付け)]拍手:3個

1. Apacheモジュールの作り方
    1. Apacheモジュール手始め
        1. rootで下準備
        2. ひな形作成
        3. とりあえず動かす
    2. リダイレクトするapacheモジュールを作ってみる
        1. リクエストパラメーター処理用ライブラリlibapreqをインストール
        2. ひな形作成
        3. ソースコード
        4. redirモジュールをインストール
        5. 動かす
        6. パフォーマンスを比較
    3. 開発にあたって多分参考になるところ

1. Apacheモジュールの作り方

今更ながらApacheモジュールに手を出してみようと思ったので、C言語でApacheモジュールの作り方手始め(Apache2.x系向け)メモしておこうと思います。
Apacheモジュールの作り方に関する本は少しだけ出ていますが、全部1.3系が基本なので、Apache2.2系を使っている自分としてはあまり使えない...、と放置していたけど、実用途でちょっと簡単なの作ってみようと思ったのでやってみました。
以下、Cent OSの最新版付属のhttpdを使った場合で書いてみます。
あんまりネット上にも情報が無かったので手探りで。
基本的にapacheモジュールを使う理由は速度や負荷軽減の為、というのが主目的になると思います。
    1. Apacheモジュール手始め


      1. rootで下準備

rootで
yum install httpd-devel
をインストール。
apacheモジュール開発に必要なコマンドがインストールされます。
      2. ひな形作成

まずhello worldを作ってみましょう。
/usr/sbin/apxs -g -n hellow_world

そうすると
mod_hello_world.c
というものが出来るので中身を眺めてみましょう。

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"

/* The sample content handler */
static int hello_world_handler(request_rec *r)
{
    if (strcmp(r->handler, "hello_world")) {
        return DECLINED;
    }
    r->content_type = "text/html";      

    if (!r->header_only)
        ap_rputs("The sample page from mod_hello_world.c\n", r);
    return OK;
}

static void hello_world_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(hello_world_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA hello_world_module = {
    STANDARD20_MODULE_STUFF, 
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    hello_world_register_hooks  /* register hooks                      */
};

      3. とりあえず動かす

/usr/sbin/apxs -c -i mod_hello_world.c
でインストールし(モジュールのディレクトリに権限があるのなら/無ければrootで)、
vi /etc/httpd/conf/httpd.conf

LoadModule hello_world_module modules/mod_hello_world.so
<Location /hello_world>
SetHandler hello_world
</Location>
を追加。
apachectl restart
し、
http://サーバー名/hello_wolrd
にアクセスすると、最初のひな形
The sample page from mod_hello_world.c
が表示される。

_handelerの所の処理が実行される事が分りました。
ここまではプログラミングすら必要なく動かせるので、これだけで動くんだと理解する為の最初の勉強としては中々ナイス。
    2. リダイレクトするapacheモジュールを作ってみる

外部へのリンクの流れを把握するには、リダイレクト用のページを用意するというのがあります。
後でapacheのaccess_logを解析して、外部への流れを把握するのに使えます。
特に頻繁に機能を追加するようなものでもないので、apacheでモジュールを作るには適している分野の一つです(更新がほとんどないプログラム)。
これを作ってみます。
要件としては、
url=...
としてパラメタ-を受け取る事と、リダイレクトのHTTPヘッダーを返す機能が必要になります。
      1. リクエストパラメーター処理用ライブラリlibapreqをインストール

http://www.apache.org/dist/httpd/libapreq/
からapache2系のlibapreq最新版をダウンロードしてインストールします。
# rootになってインストールします
su - 

32bit環境
VERSION=2-2.13
wget http://www.apache.org/dist/httpd/libapreq/libapreq$VERSION.tar.gz
tar xvfz  libapreq$VERSION.tar.gz
cd libapreq$VERSION;
./configure --with-apache-include=/usr/include/httpd
make;
make install;

64bit環境
VERSION=2-2.13
wget http://www.apache.org/dist/httpd/libapreq/libapreq$VERSION.tar.gz
tar xvfz  libapreq$VERSION.tar.gz
cd libapreq$VERSION;
./configure --with-apache-include=/usr/local/apache2/include;
make;
make install;
64bit環境だとconfigureで生成されるlibtoolが駄目だと気付くのに時間が掛かった。
消去して/usr/bin/libtool を使うようにシンボリックリンクを張っている。
一体何の為に独自のlibtoolを生成しているんだ?
とにかく64bit環境だとバグるので消す。

そして
vi /etc/httpd/conf/httpd.conf

LoadModule apreq_module modules/mod_apreq2.so
を追加
      2. ひな形作成

短いネーミングで作ってみる。
apxs -g -n redir
      3. ソースコード

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"

#include "apreq2/apreq_module_apache2.h"

/* The sample content handler */
static int redir_handler(request_rec *r)
{
  apreq_handle_t *req;
  const apreq_param_t *url;
  if (strcmp(r->handler, "redir")) {
    return DECLINED;
  }
  req = apreq_handle_apache2(r);
  
  url = apreq_param(req, "url");
  if (!url)
    return DECLINED;
  
  apr_table_set(r->headers_out, "Location", url->v.data);
  return 301;
}

static void redir_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(redir_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA redir_module = {
    STANDARD20_MODULE_STUFF, 
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    redir_register_hooks  /* register hooks                      */
};

      4. redirモジュールをインストール

localの方に入れているのなら
apxs -I /usr/local/apr/include/apreq2/ -c -i mod_redir.c

デフォルトのところに入れているのなら
apxs -I /usr/include/apreq2/ -c -i mod_redir.c

vi /etc/httpd/conf/httpd.conf
LoadModule redir_module modules/mod_redir.so
<Location /redir>
SetHandler redir
</Location>

apachectl restart
      5. 動かす

http://サーバー名/redir?url=http://www.yahoo.co.jp/
きちんとリダイレクトされ、access_logに記録されている事を確認。
現在実運用に使っています。
      6. パフォーマンスを比較

簡単にですが、mod_perlプログラム
#!/usr/bin/perl -w
package redir;
use strict;
use CGI::Accessup;

my $pro=new redir;
$pro->run();
sub new(){
        my $self={};
        return bless $self;
}

sub run(){
  my $self=shift;
  $self->init_vars();
  $self->{'c'}->redirect($self->{'url'});
}

sub init_vars(){
  my $self=shift;
  $self->{'c'}=new CGI::Accessup;
  $self->{'url'}=$self->{'c'}->param('url') || $self->{'c'}->show_error("url parameter is missing");
}
とパフォーマンスを比較

# 10個同時接続で10000リクエスト実行
ab -n 10000 -c 10 -w "http://開発マシン/redir?url=http://www.yahoo.co.jp/" > c.html
ab -n 10000 -c 10 -w "http://開発マシン/redir.asp?url=http://www.yahoo.co.jp/" > perl.html

比較してみると、手元のPCでやっているのでとりわけmod_perl版にはバラツキが毎回ありましたが、5回程それぞれ実行してみたところ、
 C言語apacheモジュールmod_perl
1秒間のリクエスト回数2536, 2544, 2577, 2615, 2709142, 364, 620, 843, 857
となりました。
C言語によるapacheモジュールの方がかなり高速に動いているのと、また、それもありますが、負荷が高くマシンスペックが低い環境でも、かなり安定した時間での実行が期待出来る事が分ります。
mod_perlでは時間が掛かりすぎてタイムアウトで実行され切らない時もありました。

↓で紹介する本でだと時間を整形するプログラムの実行結果の差として
 C言語apacheモジュールmod_perlJava Servlet(Tomcat)PHPCGI(C)CGI(Perl)
1秒間のリクエスト回数3111081051024912
という例が処理速度の差として紹介されています。
    3. 開発にあたって多分参考になるところ

ぱっと見2.x系の情報があまりあるようには見えませんが、
http://modules.apache.org/reference.php
が公式推奨の文章。

後は実際のモジュールのソースコードを見つつ勉強が王道かなぁ。
とりあえず手始めモジュールを作って、後はやりたい事をやっているモジュールのソースを眺めていくのが一番手軽かなと。
文章は見た限り、apache2.x系はあんまり整備されてなさそう。

1.3系の文章はオライリーとかからも出ているんですけどね。
 
といっても、Cとperlの解説があるといっても、perlの比率が多いので、C言語で書くにはかなり微妙...といった内容ですが。
速度を目的にApacheモジュールで書くのなら、perlじゃなくてCで書きたいですからね。

1.3系の情報から2.x系だったらどのようにやるのかを調べるというのが、本とか使った場合の調べ方になるかな。

今でも手に入るのはオライリーの本だけですが、自分が参考にしたのは
Apacheモジュール プログラミングガイド


読者が少ない分野な為絶版になり、新品で元々2800円程だったものが今見たら中古価格で1万円以上になっています。
こちらも1.3系向けに書かれていますが、ほんの少し(13ページ)だけ2.x系の書き方についての章があります。
「ノウハウが蓄積され、安定稼働しているApache1.3系が今後も現場では使われるだろう」という想定でそうなっているようですが、そんな事はなかったですし、結局つい先ほどApache1.3は先月完全にライフサイクルも終了しちゃいましたしね(Final Releaseのアナウンス)。
更新が続くソフトウェアについての本を書いたり、とりわけその過渡期に本を書くというのはどっちに合わせるのかという点で大変なのでしょうが、ちょっと残念な時期に出された内容になっちゃっています。
それでも希少なC言語のApacheモジュール本なので、情報は役に立つと思いますが。

コメントする3個

5.
2009/11/29 C言語 / C++ > boost > boostのインストール手順」
[この書込みのみ表示(記事URL紹介用) / 編集 / 削除 / トラバ送信 / 共有分類に追加(タグ付け)]拍手:3個

1. Boostライブラリのインストール手順
    1. yumでのインストール
    2. ソースからインストールする場合

1. Boostライブラリのインストール手順

C++プログラミングを楽にしてくれるboostライブラリのインストール手順。
Boostライブラリを使うと、C++で正規表現を使ったり、foreach文を使ったりすることが出来るようになります。
    1. yumでのインストール

CentOSなどでは
yum install boost*
とrootで打つことでインストール可能です。
    2. ソースからインストールする場合

1. echo $LD_LIBRARY_PATH;
をして/usr/local/libが返ってこなければ、
vi ~/.bash_profile;
して
LD_LIBRARY_PATH=/usr/local/lib:/usr/lib64:/usr/lib:/lib64:/lib
export LD_LIBRARY_PATH
を追加して
. ~/.bash_profile
して反映しておく

2. bjamをインストール

VERSION=3.1.18
wget http://downloads.sourceforge.net/project/boost/boost-jam/$VERSION/boost-jam-$VERSION.tgz?use_mirror=jaist
tar xvfz boost-jam-$VERSION.tgz;
cd boost-jam-$VERSION;
./build.sh --show-locate-target;
cp boost-jam-$VERSION/bin.linuxx86_64/bjam /usr/local/bin;

途中から要らなくなったみたい

3. http://www.boost.org/ に行ってboostライブラリ最新版をダウンロードしてインストール
VERSION=1_53_0
PATHVERSION=1.53.0
wget http://downloads.sourceforge.net/project/boost/boost/$PATHVERSION/boost_$VERSION.tar.gz?use_mirror=jaist
tar xvfz boost_$VERSION.tar.gz;
cd boost_$VERSION
./bootstrap.sh
./b2 install --prefix=/usr/local

bjam -sTOOLS=gcc --prefix=/usr/local install
↑昔はこれだった

4. 後は実際にboostライブラリを使ったプログラムを作ってみて、動くか試してみましょう。
-L/usr/local/lib -I/usr/local/include
とすることで、g++にインストールしたboostのヘッダーファイルとライブラリを見つけさせる事が出来ます。

コメントする3個

=>古記事
RSS購読
RSS
ブログ表示スタイル
リスト/携帯(QRコード)
画像/動画/音声/リンク
表示開始年月
分類
全て
1.このサイトについて
2.作品DB開発/運用
3.ホームページ制作技術
4.Perl
5C言語 / C++
6.検索エンジン&SEO
7.サッカー
8.自分のこと
9.Linux
10.旅行
11.思ったこと
12.パソコン
13.Berkeley DB
14.その他技術系
15.企画
16.スマートフォン
17.鑑賞
18.皆声.jpニュース
19.インターネット業界
20.運用マニュアル(自分用)
21.技術系以外実用書
22.料理
23.ALEXA
24.アニメ
25.会計
26.漫画
27.設計書
28.色々サイト作成
29.サーバー
30.自分専用
31.生活
32.OP/ED/PV
33.ゲーム
34.DB整備
35.新規開始作品紹介
36.英語圏の話題
37.大道芸
38.映画
39.PHP
40.ダイエット
41.Mac
42.JavaScript
43.MySQL
44.介護
45.作品DB作品追加作業
46.BI
47.Web API
48.パフォーマンス
49.インターネットの活用方法
50.Riak
51.Androidアプリ開発
52.Cassandra
53.スパム
54.写真
55.iOSアプリ開発
56.AWS
57.マーケティング
58.Web漫画
59.法律
60.mongodb
61.開発環境整備
62.Google Apps Script
63.meteor
64.Pentaho
65.Ansible
66.VPS
67.技術書メモ
68.Vagrant
69.Docker
70.dokuwiki
71.Apple Watch
72.Webサービス
73.セキュリティ
74.Elastic Search
75.Wordpress
76.クラウド
77.英語
78.MVNO
79.シンガポール
80.マレーシア
81.海外生活
日記の主な内容
サイト運営/開発
検索エンジン情報
・技術ネタ(Berkeley DB,
Linux, Perl, サイト作成)等

サイト管理
全まとめ
サーバー管理
定期処理状況
開発予定
削除提案
作品追加依頼
OP/ED追加依頼
OP/ED not found
作品提案承認欄

格言 fromスクライド
この世の理は即ち速さ
20年かければ馬鹿でも
傑作小説を書ける

助けられたら助け返す
それが俺のルール

強くなるには
一番弱い考えをする事だ
そしてその考えに反逆する




右側に何か入れてみるテスト


仕事でのサイト
介護DB
Helpyou
Doctor career
Nurse career
上へ ↑上へ 最速検索作品DB皆声