[C言語] ファイルアクセス

ファイル記述子を使用する関数には、open, close, read, writeがある。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

void usage(char *prog_name, char *filename){
    printf("使用方法: %s <%sに追加するデータ>\n", prog_name, filename);
    exit(0);
}

void fatal(char *);
void *ec_malloc(unsigned int);

int main(int argc, char *argv[]) {
    int fd;
    char *buffer, *datafile;

    buffer = (char *) ec_malloc(100);
    datafile = (char *) ec_malloc(20);
    strcpy(datafile, "./notes");

    if (argc < 2)
        usage(argv[0], datafile);

    strcpy(buffer, argv[1]);

    printf("[DEBUG] buffer @ %p: \'%s'\n", buffer, buffer);
    printf("[DEBUG] datafile @ %p: \'%s'\n", datafile, datafile);

    strncat(buffer, "\n", 1);

    fd = open(datafile, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
    if(fd == -1)
        fatal("main()内、ファイルのオープン中にエラーが発生しました。");
    printf("[DEBUG] ファイル記述子:%d\n", fd);

    if(write(fd, buffer, strlen(buffer)) == -1)
        fatal("main()内、ファイルへのバッファの書き込みでエラーが発生しました。");

    if(close(fd) == -1)
        fatal("main()内、ファイルのクローズ中にエラーが発生しました。");

    printf("メモが保存されました\n");
    free(buffer);
    free(datafile);

    return 0;
}

void fatal(char *message) {
    char error_message[100];

    strcpy(error_message, "[!!]致命的なエラー:");
    strncat(error_message, message, 79);
    perror(error_message);
    exit(-1);
}

void *ec_malloc(unsigned int size) {
    void *ptr;
    ptr = malloc(size);
    if(ptr == NULL)
        fatal("ec_malloc()内のメモリ割り当てでエラーが発生しました。");
    return ptr;
}

$ ./main
使用方法: ./main <./notesに追加するデータ>
$ ./main “this is a test note”
[DEBUG] buffer @ 0xaaaadc4a72a0: ‘this is a test note’
[DEBUG] datafile @ 0xaaaadc4a7310: ‘./notes’
[DEBUG] ファイル記述子:3
メモが保存されました

### ビット単位の演算

int main() {
    int i, bit_a, bit_b;
    printf("ビット単位の論理和演算子 |\n");
    for(i=0; i< 4; i++){
        bit_a = (i & 2) / 2;
        bit_b = (i & 1);
        printf("%d | %d = %d\n", bit_a, bit_b, bit_a | bit_b);
    }

    printf("ビット単位の論理積演算子 |\n");
    for(i=0; i< 4; i++){
        bit_a = (i & 2) / 2;
        bit_b = (i & 1);
        printf("%d | %d = %d\n", bit_a, bit_b, bit_a & bit_b);
    }

    return 0;
}

$ ./main
ビット単位の論理和演算子 |
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
ビット単位の論理積演算子 |
0 | 0 = 0
0 | 1 = 0
1 | 0 = 0
1 | 1 = 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

void display_flags(char *, unsigned int);
void binary_print(unsigned int);

int main(int argc, char *argv[]) {
    display_flags("O_RDONLY\t\t", O_RDONLY);
    display_flags("O_WRONLY\t\t", O_WRONLY);
    display_flags("O_RDWR\t\t", O_RDWR);
    printf("\n");
    display_flags("O_APPEND\t\t", O_APPEND);
    display_flags("O_TRUNC\t\t", O_TRUNC);
    display_flags("O_CREAT\t\t", O_CREAT);

    printf("\n");
    display_flags("O_WRONLY|O_APPEND|O_CREAT", O_WRONLY|O_APPEND|O_CREAT);

    return 0;
}

void display_flags(char *label, unsigned int value){
    printf("%s\t %d\t:", label, value);;
    binary_print(value);
    printf("\n");
}

void binary_print(unsigned int value) {
    unsigned int mask = 0xff000000;
    unsigned int shift = 256*256*256;
    unsigned int byte, byte_iterator, bit_iterator;

    for(byte_iterator=0; byte_iterator < 4; byte_iterator++){
        byte = (value & mask) / shift;
        printf(" ");
        for(bit_iterator=0; bit_iterator < 8; bit_iterator++){
            if(byte & 0x80)
                printf("1");
            else
                printf("0");
            byte *= 2;
        }
        mask /= 256;
        shift /= 256;
    }
}

$ ./main
O_RDONLY 0 : 00000000 00000000 00000000 00000000
O_WRONLY 1 : 00000000 00000000 00000000 00000001
O_RDWR 2 : 00000000 00000000 00000000 00000010

O_APPEND 1024 : 00000000 00000000 00000100 00000000
O_TRUNC 512 : 00000000 00000000 00000010 00000000
O_CREAT 64 : 00000000 00000000 00000000 01000000

O_WRONLY|O_APPEND|O_CREAT 1089 : 00000000 00000000 00000100 01000001