#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _student
{
    struct _student *next;
    char *name;
    int len;
} student;

student *top = NULL, *end = NULL;
char buf[100];

// prototype
int addvec(int *, int );
void push();
void pop();
void display();
char *func2(char *, char );
void func3();
void func4();
void func5();
void searchOneChr();
void searchDelFirst();

// 問題１
int addvec(int *a, int n)
{
    int r = 0;
    while (n--) r += *a++;
    return r;
}

void push()
{
    int n;
    student *p;

    // 数入力
    printf("数 = ");
    if (fgets(buf, 100, stdin) == NULL)return;
    n = atoi(buf);

    // 文字列入力
    printf("文字列 = ");
    if (fgets(buf, 100, stdin) == NULL)return;
    buf[strlen(buf) - 1] = '\0';

    // 構造体のメモリを確保
    p = (student *)malloc(sizeof(student));
    if (top)
    {
        end->next = p;
    }
    else
    {
        top = p;
    }
    end = p;
    end->next = NULL;

    // 文字列用のメモリを確保
    end->name = (char *)malloc(sizeof(char *) * (strlen(buf) + 1));
    strcpy(end->name, buf);
    end->next = NULL;

    end->len = n;
}

void pop()
{
    student *p = top;
    if (top)
    {
        top = top->next;
        free(p);
        /* code */
    }
}

void display()
{
    student *a = top;
    while (a)
    {
        printf("name = %s, len  = %d\n", a->name, a->len);
        a = a->next;
    }
}

void searchOneChr()
{
    printf("検索文字 = ");
    fgets(buf, 100, stdin);
    student *a = top;
    while (a)
    {
        if (strchr(a->name, buf[0]))   /* hit*/
        {
            printf("name = %s, len  = %d\n", a->name, a->len);
        }
        a = a->next;
    }
}

void searchDelFirst()
{
    printf("検索文字 = ");
    fgets(buf, 100, stdin);
    student *prev = top;
    student *a = top;
    while (a)
    {
        if (strchr(a->name, buf[0]))   /* hit */
        {
            printf("name = %s, len  = %d\n", a->name, a->len);
            if (a == top)   /* 先頭でhit */
            {
                top = top->next;
                free(prev);
            }
            else     /* 先頭以外でhit */
            {
                prev->next = a->next;
                free(a);
            }
            return;
        }
        prev = a;
        a = a->next;
    }
}

// 問題２
char *func2(char *s, char c)
{
    while (*s && (*s != c))++s;
    return s;
}

// 問題３
void func3()
{
    push();
    display();
}

// 問題４
void func4()
{
    while (1)
    {
        printf("\ni：最後に追加\nd：先頭を削除\np：全て表示\nq：終了\nコマンド= " );
        fgets(buf, 100, stdin);
        switch (buf[0])
        {
        case 'i':
            push();
            break;
        case 'd':
            pop();
            break;
        case 'p':
            display();
            break;
        case 'q':
            return;
        default:
            break;
        }
    }
}

// 問題５
void func5()
{
    while (1)
    {
        printf("\ni：最後に追加\nd：先頭を削除\np：全て表示\ns：文字検索表示\nf：文字検索先頭削除\nq：終了\nコマンド = " );
        fgets(buf, 100, stdin);
        switch (buf[0])
        {
        case 'i':
            push();
            break;
        case 'd':
            pop();
            break;
        case 'p':
            display();
            break;
        case 's':
            searchOneChr();
            break;
        case 'f':
            searchDelFirst();
            break;
        case 'q':
            return;
        default:
            break;
        }
    }
}

int main()
{
    int i;
    char s[100], c;
    int sample1[] = {2, 3, 4};

    do
    {
        printf("問題番号(1~5) = " );
        fgets(s, 100, stdin);
        i = atoi(s);
    }
    while (i < 1 || i > 5);

    switch (i)
    {
    case 1:
        printf("%d\n", addvec(sample1, sizeof(sample1) / sizeof(sample1[0])));
        break;
    case 2:
        printf("s = ");
        fgets(s, 100, stdin);
        printf("c = ");
        c = getchar();
        printf("%s\n", func2(s, c));
        break;
    case 3:
        func3();
        break;
    case 4:
        func4();
        break;
    case 5:
        func5();
        break;
    default:
        break;
    }

    return 0;
}
