LINEトーク履歴集計アプリ開発② - 前編 -

今回は**アップロードされたテキストファイルを読み込み、集計、出力**についての記事だ
C言語とincronというコマンドどシェルスクリプトで構成される

## 手順
- GCCコンパイラのインストール
- 結果を書き出すディレクトリ・ファイルの作成 **result.html** or **result.txt**
- C言語にて集計処理を記述 **test.c**
- コマンドライン引数を利用するためシェルスクリプトの作成 **hoge.sh**
- incronのインストール
- crontabにて処理の流れを登録

save/
    |-txt_form.php
    |-txt_post.php
    |-test.c
    |-test  test.cの実行ファイル
    |-hoge.sh
    |-アップロードされた.txt
    result/
          |-result.html(.txt)
## GCCコンパイラのインストール
UbuntuでのGCCのインストール方法

```$sudo apt update```

```$sudo apt install build-essential```

```$gcc -v```

これでバージョンが出力されたらインストール完了
## 結果を書き出すディレクトリ・ファイルの作成 **result.html** or **result.txt**
先に、集計結果を書き込むディレクトリ・ファイルを作成しておく

筆者は/save下に/resultをつくった　

ファイルは.txtでも.htmlでも可
## C言語にて集計処理の記述
```test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int lookup(char **str1, char *str2, int n);
 
int main(int argc, char** argv)
{
    FILE *fp;
    char *fname = argv[1];
    int cnt = 0;
    char moji[1024];
 
    fp = fopen(fname, "r");
    if(fp == NULL){
        return -1;
    }
    else{
    }
 
 
    while((fgets(moji, 1024, fp)) != NULL){
        cnt++;
    }
    fclose(fp);
 
 
    char **name = calloc(cnt - 3, sizeof(char*));
    for(int i = 0; i < cnt - 3; i++){
        name[i] = calloc(50, sizeof(char));
    }
 
    fp = fopen(fname, "r");
    if(fp == NULL){
        return -1;
    }
    else{
    }
 
    fgets(moji, sizeof(moji), fp);
    fgets(moji, sizeof(moji), fp);
    fgets(moji, sizeof(moji), fp);
    fgets(moji, sizeof(moji), fp);
    int o = 0;
    while((fgets(moji, 1024, fp)) != NULL) {
        for(int i = 0; moji[i] != '\0'; i++){
            if(moji[i] != '\t'){
                continue;
            }
            else{
                int k = 0;
                for(int j = i + 1; moji[j] != '\t'; j++){
                    name[o][k] = moji[j]; 
                    k++;
                }
                name[o][k] = '\0';
                o++;
                break;
 
            }
        }
    }
 
    char **index = calloc(o, sizeof(char*));
    for(int i = 0; i < o; i++){
        index[i] = calloc(50, sizeof(char));
    }

    int namecnt = 0;
    for(int i = 0; i < o; i++){
        namecnt++;
    }
    
    int k = 0;
    int ans = 0;   //return value of lookup function
    int kindcnt;
    for(int i = 0; i < o; i++){
        ans = lookup(index, name[i], o);
        if(ans == 0){
            continue;
        }
        else if(ans != 0){
            strcpy(index[k], name[i]);
            k++;
        }
    }

    int *fin = calloc(k, sizeof(int));
    // m 発言回数カウント
    int m = 0;
    for(int i = 0; i < k; i++){
        for(int j = 0; j < o; j++){
            if(strcmp(index[i], name[j]) == 0){
                m++;
            }
            else{
                continue;
            }
        }
        fin[i] = m;
        m = 0;
    }
 
    int tmp = 0;
    char *stmp = 0;
    for(int i = 0; i < k; i++){
        for(int j = 0; j < k; j++){
            if(fin[i] > fin[j]){
                tmp = fin[i];
                fin[i] = fin[j];
                fin[j] = tmp;
 
                stmp = index[i];
                index[i] = index[j];
                index[j] = stmp;
 
            }
        }
    }
    for(int i = 0; i < k; i++){
        printf("名前：%-40s発言回数 : %d\n", index[i], fin[i]);
    }
 
 
    fclose(fp);
 
//書き出し
    fp = NULL;
    char fname2[] = "/var/www/html/save/result/result.html";
    fp = fopen(fname2, "w");
 

    fprintf(fp, "<!DOCKTYPE html>\n");
    fprintf(fp, "<html lang=\"ja\">\n");
    fprintf(fp, "\t<head>\n");
    fprintf(fp, "\t\t<meta charset=\"utf-8\">\n");
    fprintf(fp, "\t\t<title>タイトル</title>\n");
    fprintf(fp, "\t</head>\n");
    fprintf(fp, "\t<body>\n");
    fprintf(fp, "\t\t<header>\n");
    fprintf(fp, "\t\t\t<p>集計結果</p>\n");
    fprintf(fp, "\t\t</header>\n");
    fprintf(fp, "\t\t<main>\n");
    fprintf(fp, "\t\t\t<article>\n");
    for(int i = 0; i < k; i++){
        fprintf(fp, "\t\t\t<p>名前：%-40s発言回数 : %d</p>\n", index[i], fin[i]);
    }
    fprintf(fp, "\t\t\t</article>\n");
    fprintf(fp, "\t\t</main>\n");
    fprintf(fp, "\t</body>\n");
    fprintf(fp, "</html>\n");
 
 
    fclose(fp);
 
    for(int i = 0; i < cnt - 3; i++){
        free(name[i]);
    }
    for(int i = 0; i < o; i++){
        free(index[i]);
    }
    free(name);
    free(index);
    free(fin);
    return 0;
}
               //index[]         name[]
int lookup(char **str1, char *str2, int n)
{
    int cnt = 0;
    for(int i = 0; i < n; i++){
        if(strcmp(str1[i], str2) == 0){
            cnt = 0;
            break;
        }
        else{
            cnt++;
        }
    }
    return cnt;
}
```

```$gcc -o test test.c```
test.cをtestという名前でコンパイルし保存

テキストファイルを開いて読み込み、集計、書き出し用のファイルに書き込むという内容だ
読み込むテキストファイルは動的なため、コマンドライン引数として、実行時に渡す

./test ファイルの名前
で実行できる






前半はここまで
続きは後半にて