funini.com 自由研究 C/C++ 小物

小物

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);
}

遅かったらごめんなさい。