Paepoi

Paepoi » C and GLib Tips » C Tips

C Tips

# 最終更新日 2021.02.27

下記のコードは Windows では使えません。

自作 readline
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
/**
 * prompt 引数を NULL か空文字にするとパイプから読み取る
 * strnlen srtndup でセキュア、バッファ外へはアクセスしないはず
 */

char*
readline(char *prompt) {
    char buf[1024];
    if (prompt && strnlen(prompt, sizeof(prompt)) != 0)
        printf("%s", prompt);
    fgets(buf, sizeof(buf), stdin);
    size_t len = strnlen(buf, sizeof(buf));
    return strndup(buf, len - 1);
}
 
int
main (int argc, char const* argv[]) {
    char *buf = readline("何か入力してください > ");
    printf("入力されたのは「%s」です\n", buf );
    free(buf);
    return 0;
}

端末入力とパイプ入力で振り分け
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char*
readline(char *prompt) {
    char buf[1024];
    if (prompt && strnlen(prompt, sizeof(prompt)) != 0)
        printf("%s", prompt);
    fgets(buf, sizeof(buf), stdin);
    size_t len = strnlen(buf, sizeof(buf));
    return strndup(buf, len - 1);
}
 
int
main (int argc, char* argv[]) {

    char *line;

    if (isatty(0)) {
        line = readline("何か入力してください > ");
        printf("stdin に %s が入力されました\n", line);
        free(line);
    } else {
        line = readline(NULL);
        printf("パイプから %s が送られました\n", line);
        free(line);
    }
    return 0;
}

一行上に出力
#include <stdio.h>
#include <unistd.h>

/**
 * \e[数値A で戻りたい行数の数値
 * \e[0J    でカーソル以降の行を削除
 * e は 033 や x1B でもいい
 */
 
int
main (int argc, char* argv[]) {
 
    char* strs[4] = {"いーち", "にー", "さーん", "だぁー!"};
    int i;
 
    printf("いくぞー\n");
    for (i=0; i<4; i++) {
        sleep(1);
        printf("\e[1A\e[0J"); /* 移動 */
        printf("%s\n", strs[i]);
    }
    return 0;
}

色分け表示
端末アプリの機能ですが printf で使えます。
#include <stdio.h>

/**
 * 参考
 * http://7ujm.net/etc/esc.html
 * \e[数値m にて指定
 * e は上記と同じ
 */

int
main (int argc, char* argv[]) {

    printf("\e[32m緑色おおおお\n");
    printf("\e[31m赤色おおおお\n");
    // 戻す
    printf("\e[39m戻したぞおおおお\n");
    return 0;
}

setlocale
#include <stdio.h>
#include <locale.h>

/**
 * gcc, Clang では ja-JP.UTF-8 になるはず
 */

int
main (int argc, char *argv[]) {

    char *locale;

    locale = setlocale(LC_ALL, "");
    printf("locale は[%s]です\n", locale);

    return 0;
}

組み込みマクロ
#include <stdio.h>

int
main (int argc, char *argv[]) {

    printf("ファイル名は[%s]です\n", __FILE__);
    printf("現在[%d]行目を処理しています\n", __LINE__);
    printf("ビルド日時は[%s %s]です\n", __DATE__, __TIME__);
    printf("保存日時は[%s]です\n", __TIMESTAMP__);
    if (__STDC__)
        printf("ANSI C 準拠です\n");

    return 0;
}

ls の実装例
#include <stdio.h>
#include <dirent.h>

int
main (int argc, char *argv[]) {

    DIR *dir;
    struct dirent *dp;

    dir = opendir(".");
    while ((dp = readdir (dir)) != NULL) {
        if (dp->d_name[0] != '.' && dp->d_type == DT_REG)
            printf("%s\n", dp->d_name);
    }
    return 0;
}

cat の実装例
#include <stdio.h>
 
int
main (int argc, char *argv[]) {

    FILE *fp;
    char buf[256];

    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        printf("%s\n", "開けません");
        return 1;
    }
    while (1) {
        if (fgets(buf, sizeof(buf), fp) == NULL)
            break;
		printf("%s", buf);
	}
	printf("\n");
	fclose(fp);
	return 0;
}

シェルスクリプトの実行
#include <stdlib.h>

int
main (int argc, char *argv[]) {
    /* オプションもパイプも使えます */
    system("ps ax | grep bin");
    return 0;
}

日付と日時
#include <stdio.h>
#include <time.h>
#include <locale.h>

int
main(int argc, char **argv) {

    char s[256];
    time_t temp;
    struct tm *timeptr;

    /* コレをしないと日本語にならない */
    setlocale(LC_ALL, "");

    temp = time(NULL);
    timeptr = localtime(&temp);

    strftime(s, sizeof(s), "現在 %c", timeptr);
    printf("%s\n", s);

    return 0;
}

Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.