C言語自作ユーティリティ関数

標準入力(キーボード)からの一行入力

int keyboard_linein(char *s, int ln) 関数。
char s* は入力バッファ(文字列、長さは自分で決める)。int ln は読み込む最大文字数。入力バッファの長さは ln より小さくてはいけない。
末尾の改行は含まない。
返り値は 0 ならば正常終了。1 か 2 ならばエラー。

keyboard_linein.c

#include <stdio.h>
#include <stdlib.h>    //exit()用。

#define NUM 100
int keyboard_linein(char *s, int ln);

int main() {
    char s[NUM];
    
    int i = keyboard_linein(s, NUM);
    if (i) exit(1);
    printf("%s\n", s);
    printf("%d\n", strlen(s));
    
    exit(0);
}

int keyboard_linein(char *s, int ln) {
    int c;
    
    if (fgets(s, ln, stdin) == NULL) return 1;
    if (strchr(s, '\n') != NULL) s[strlen(s) - 1] = '\0';
    else {
        while (1) {
            c = getchar();
            if (c == EOF ) return 2;
            if (c == '\n') return 0;
        }
    }
    return 0;
}

 

標準入力(キーボード)からの数値入力(long 型)

long input_long() 関数。
キーボードから数値を入力し、それを long 型で返す。
strtol() 関数のエラー処理は関数の外でやって下さい。

keyboard_linein.c

#include <stdio.h>
#include <stdlib.h>    //exit()用。
#include <errno.h>     //ERANGE用

#define NUM 100
long input_long();

int main() {
    long l = input_long();
    if (errno == ERANGE) {
        printf("オーバーフローとアンダーフローのいずれかが発生しました\n");
        exit(1);
    }
    printf("%ld\n", l);
    
    exit(0);
}

long input_long() {
    char s[NUM];
    int c, i;
loop:
    i = keyboard_linein(s, NUM);
    if (i) exit(1);
    
    char *p = s;
    while ((c = *(p++)) != '\0') {
        if ((c < 48 || c > 57) && (c != 45)) {
            printf("数字以外の文字が入っています。再入力して下さい。\n");
            goto loop;
        }
    }
    return strtol(s, NULL, 10);
}

内部で keyboard_linein() 関数を使っています。

 

int 配列などの表示

void print_array_int(int *ar, int ln) 関数。
int *ar は表示される配列。int ln は配列の長さ。

void print_array_double(double *ar, int ln) 関数。
double *ar は表示される配列。int ln は配列の長さ。

void print_str_by_ascii(char *s[]) 関数。文字列を ascii コードで表示。
char *s は表示される文字列。

print_array.c

#include <stdio.h>
#include <stdlib.h>    //exit()用。

int main() {
    int ar1[] = {2, 5, 9, -2, 3};
    print_array_int(ar1, 5);    //出力:{2, 5, 9, -2, 3}。sizeof(ar1) / sizeof(int) = 5。
    
    double ar2[] = {-1.5, 0, 310.92};
    print_array_double(ar2, sizeof(ar2) / sizeof(double));    //出力:{-1.500000, 0.000000, 310.920000}
    
    char *st = "abcd";
    print_str_by_ascii(st);    //出力:{97, 98, 99, 100}
    
    exit(0);
}

void print_array_int(int *ar, int ln) {
    if (!ln) {
        printf("{}\n");
        return;
    }
    
    printf("{");
    for (int i = 0; i < ln; i++) {
        printf("%d, ", ar[i]);
    }
    printf("\b\b}\n");
}

void print_array_double(double *ar, int ln) {
    if (!ln) {
        printf("{}\n");
        return;
    }
    
    printf("{");
    for (int i = 0; i < ln; i++) {
        printf("%f, ", ar[i]);
    }
    printf("\b\b}\n");
}

void print_str_by_ascii(char *s) {
    char *p = s;
    int c;
    
    printf("{");
    while ((c = *(p++)) != '\0') {
        printf("%d, ", c);
    }
    printf("\b\b}\n");
}

 

配列の結合、配列に push、配列から pop

void *concat_ATYPE_arrays(ATYPE *s1, int ln1, ATYPE *s2, int ln2, ATYPE *merged) 関数。配列を結合する。ただし、「#define ATYPE int」などのマクロ定義をしている。
配列 s1 と s2 を結合して配列 merged に格納する。ln1, ln2 はそれぞれ s1, s2 の配列の長さ。当然、merged の長さは ln1 + ln2 以上でなければならない。

void *push_ATYPE_array(ATYPE *ar, int ln, ATYPE c, ATYPE *pushed) 関数。
配列 ar の最後に数値 c を結合して配列 pushed に格納する。ln は配列 ar の長さ。当然、pushed の長さは ln + 1 以上でなければならない。

ATYPE pop_ATYPE_array(ATYPE *ar, int ln, ATYPE *poped) 関数。
配列 ar の最後の数値を返し、その最後の数値を取り去った配列を poped に格納する。ln は配列 ar の長さ。当然、poped の長さは ln - 1 以上でなければならない。

concat_arrays.c

#include <stdio.h>
#include <stdlib.h>    //exit()用。

#define ATYPE int

void concat_ATYPE_arrays(ATYPE *s1, int ln1, ATYPE *s2, int ln2, ATYPE *merged) {
    int *p1 = s1;
    int *p2 = s2;
    int *p3 = merged;
    int i;
    
    for (i = 0; i < ln1; i++) {
        *(p3++) = *(p1++);
    }
    for (i = 0; i < ln2; i++) {
        *(p3++) = *(p2++);
    }
}

void push_ATYPE_array(ATYPE *ar, int ln, ATYPE c, ATYPE *pushed) {
    ATYPE c1[] = {c};
    concat_ATYPE_arrays(ar, ln, c1, 1, pushed);
}

ATYPE pop_ATYPE_array(ATYPE *ar, int ln, ATYPE *poped) {
    ATYPE a = ar[ln - 1];
    
    int *p1 = ar;
    int *p2 = poped;
    
    for (int i = 0; i < ln - 1; i++) {
        *(p2++) = *(p1++);
    }
    
    return a;
}

int main() {
    ATYPE a1[] = {2, 0, 5};
    ATYPE a2[] = {-1, 7};
    ATYPE merged[5];
    
    concat_ATYPE_arrays(a1, 3, a2, 2, merged);
    print_array_ATYPE(merged, 5);    //出力:{2, 0, 5, -1, 7}
    
    ATYPE pushed[6];
    
    push_ATYPE_array(merged, 5, 10, pushed);
    print_array_ATYPE(pushed, 6);    //出力:{2, 0, 5, -1, 7, 10}
    
    ATYPE poped[5];
    
    ATYPE a = pop_ATYPE_array(pushed, 6, poped);
    printf("\n%d\n", a);    //出力:10
    print_array_ATYPE(poped, 5);    //出力:{2, 0, 5, -1, 7}
    
    exit(0);
}

この例では main() で print_array_int() 関数を使っています。