[an error occurred while processing this directive] [an error occurred while processing this directive]

小物プログラム

mysudo

引数のコマンドを実行します。
rootとしてsetuidして置いておくと、パスワード無しのsudoになります。危険。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 4096

int main(int args, char **argv){
  int i = 1, l = 0;
  char buf[LEN];

  while(i != args){
    strncpy(buf+l, argv[i], (size_t)(LEN - l));
    l = strlen(buf);
    if(++i == args) break;
    buf[l] = ' ';
    l += 1;
  }

  //  printf("|%s|\n", buf);
  system(buf);
  return 0;
}

設定ファイル読み込み

設定ファイルを読み込むクラスをSTLで書いてみました。 タブかスペース区切りです。
/**
  * read config file
  * sample of the config file is as follows :
----
apple    3
rate     5.2
finland  suomi
----
  */

#include <iostream>
#include <fstream>
#include <sstream>
#include <map>

#define BUF_LEN 128

class ConfigFile {
  std::map<std::string, std::string> data;
 public:
  ConfigFile(const char *fn){
  std::fstream in(fn, std::ios::in);
    if( in.fail() ){
      //my_error("Config file is not available", MY_ERROR_NOTICE);
      return;
    }

    char buf[BUF_LEN];
    while (in.getline(buf, BUF_LEN)){
      std::istringstream iss(buf);
      std::string key, value;
      iss >> key >> value;
      if(key.length() != 0 && value.length() != 0)
        data[key] = value;
    }
  }

  char *getString(const char *key){
    std::string &value = data[key];
    int len = value.length();
    char *buf = new char[len+1];
    value.copy(buf, len);
    buf[len] = '\0';
    return buf;
  }

  int getInt(const char *key){
    int ret;
    std::string &value = data[key];
    std::istringstream iss(value);
    iss >> ret;
    return ret;
  }

  double getDouble(const char *key){
    double ret;
    std::string value = data[key];
    std::istringstream iss(value);
    iss >> ret;
    return ret;
  }
};


int main(void){
  ConfigFile cf("test.txt");
  int ret = cf.getInt("apple");
  std::cout << "apple : " << ret << std::endl;

  char *sret = cf.getString("finland");
  std::cout << "suomi : " << sret << std::endl;

  double dret = cf.getDouble("rate");
  std::cout << "rate : " << dret << std::endl;
}

フィボナッチ

bakafib(n)  {return (n > 2)  ? 1 : bakafib(n-1) + bakafib (n-2);}/*(遅い)*/
main(int i, char **c){printf("%d\n", fib(atoi(c[1])));}
末尾再帰
fib(n)      {return ifib(n, 1, 0);}
ifib(n,l,l1){return (n == 0) ? last : ifib((n-1), (l+l), l);}    /*(呼ぶのは上の方)*/

クイックソート

#include <stdio.h>
void print(int *A, int size){
  int i;
  for(i = 0; i < size; i++) printf("%d ", A[i]);
  printf("\n");
}
void swap(int *a, int *b){int c = *a; *a = *b; *b = c;}
void sort(int *A, int size){
  if(size < 2) return;
  if(A[0] < A[size-1]) swap(&A[0], &A[size-1]);
  { 
    int i = 1, j = size - 2;
    int thres = A[0];
    while(i < j){
      while(thres < A[i]) i++;
      while(thres > A[j]) j--;
      if(i < j) swap(&A[i++], &A[j--]);
    }
    sort(A, j);
    sort(&A[i], size-i);
  }
}
  
int main(){
  int A[5] = {1, 7, 5, 4, 5};
  print(A, 5);
  sort(A, 5);
  print(A, 5);
}

キュー(C++)

class Queue {
  OBJECT **Q; 
  int max, head, tail, len;
  Queue(void){head = tail = len = 0;};
public:
  Queue(int max_){
    max = max_, head = tail = len = 0;
    Q = new OBJECT*[max];
  }
  bool push(OBJECT *rcp){
    if(len == max) return false;
    Q[tail] = rcp;
    tail = (tail + 1) % max, len++;
    return true;
  }
  OBJECT *pull(void){
    if(len == 0) return NULL;
    OBJECT *rcp = Q[head];
    head = (head + 1) % max, len--;
    return rcp;
  }
  int getLen(void){ return len; }
};

ストップウオッチ

pthreadとgettimeofdayのサンプル。gcc sw.c -lpthradでコンパイル、enterで終了します。
#include <sys/time.h>
#include <pthread.h>

long dt;

void showtime(long xt){
  int h, m, s;
  h = xt / 3600;
  m = (xt - h * 3600) / 60;
  s = (xt - h * 3600 - m * 60); 
  printf("%2dhour %2dmin %dsec\n", h, m, s);
}

void *f(void *x){
  int i, t;
  long pdt=0;
  struct timeval tv0, tv1;
  t = 0;
  gettimeofday(&tv0, 0);
  for(;;) {
    usleep(100);
    gettimeofday(&tv1, 0);
    dt = (tv1.tv_sec - tv0.tv_sec);
    if(dt > pdt){
      showtime(dt);
      pdt = dt;
    }
  }
  return (void *)0;
}

int main(void){
  pthread_t tidx;
  pthread_attr_t attr;

  pthread_attr_init(&attr);
  pthread_create(&tidx, &attr, f, (void *)0);
  getchar();
  printf("Elapsed time : ");
  showtime(dt);
  exit(0);
  //pthread_join(tidx, 0);
  //return 0;
}


名前からprocess idを取得(C, Linux)

popen(パイプ)のテスト。ps -aした結果をなめます。psの出力に依存します。
#include <stdio.h>
#include <stdlib.>

/*
  test program for popen
  $ gcc -o pid_from_name pid_from_name.c
  $ ./pid_from_name [process name]
*/

int readLine(char *buf, int size, FILE *fp ){
  int i;
  bzero(buf, size);
  fgets(buf, 100, fp);
  for(i = 0; i < size; i++){
    if(buf[i] == 0) return i;
  }
  return -1;
}

int get_pid(char *command, int *pid_list){
  int pid_num, pid;
  char buf[100];
  FILE *fp;

  fp = popen("ps -a", "r");
  fgets(buf, 100, fp);
  pid_num = 0;
  for(;;){
    int ret;
    char dat[10][100];
    readLine(buf, 100, fp);
    if(strlen(buf) == 0) break;
    sscanf(buf, "%d %s %s %s", &pid, dat[1], dat[2], dat[3]);
    if(strcmp(dat[3], command) == 0){
      pid_list[pid_num++] = pid;
    }
  }
  pclose(fp);
  return pid_num;
}

int main(int args, char **argv){
  int i, list_num, pid_list[100];
  if(args != 2){
    printf("Usage : %s [process name]\n", argv[0]);
    return 0;
  }
  list_num = get_pid(argv[1], pid_list);
  for(i = 0; i < list_num; i++){
    printf("pid : %d\n", pid_list[i]);
  }
  return 0;
}

テキストで木を出力

stringコピーしまくってて遅そう。
#include <iostream>
#include <string>

using namespace std;

class Entry{
public:
  virtual void print(string str){}
};

class Leaf : public Entry{
public:
  char *label;
  Leaf(char *_label){label = _label;}
  void print(string str){cout << label << endl;}
};

class Node : public Entry{
public:
  Entry *left, *right;

  Node(Entry *_left, Entry *_right){left = _left, right = _right;}

  void print(string str){
    cout << "--";
    left->print(str + "| ");
    cout << str << "`-";
    right->print(str + "  ");
  }
};

int main(void){
  Entry *root;
  root = new Node(new Node( new Leaf("a"), new Leaf("b") ),
                  new Node( new Node(new Leaf("a"), new Leaf("b")), new Leaf("kero")));
  root->print("");
  return 0;
}
出力。
----a
| `-b
`-----a
  | `-b
  `-kero

環境変数を出力

#include <iostream>

int main(int argn, char **argv, char **env){
  for(char **cpp = env; *cpp != NULL; cpp++){
    std::cout << *cpp << std::endl;
  }
}

プログラム中で時間測定。

start(0) としたあとでstop(0)とすると、経過時間が表示されます。
#include <unistd.h>
#include <sys/time.h>
#include <iostream>

class StopWatch {
 public:
  int n; 
  struct timeval *tvs;

  StopWatch(int _n){ n = _n; tvs = new struct timeval[n];  }
  void start(int i){ gettimeofday(tvs+i, 0);  }
  void stop(int i){
    struct timeval tv0;
    gettimeofday(&tv0, 0);
    std::cout << i;
    std::cout << "," << (tv0.tv_sec - tvs[i].tv_sec);
    std::cout << "," << (tv0.tv_usec - tvs[i].tv_usec) / 1000 << std::endl;
  }
};
例えばこんな風に使います。
#include "sw.h"

int main(void){
  StopWatch *sw = new StopWatch(10);
  sw->start(0);
  sw->start(1);
  sleep(1);
  sw->stop(1);
  sleep(1);
  sw->stop(0);
}
遅かったらごめんなさい。
[an error occurred while processing this directive]