回答編集履歴

1

コード追加

2021/07/15 05:46

投稿

jimbe
jimbe

スコア12648

test CHANGED
@@ -3,3 +3,247 @@
3
3
  特別厳しい条件があるわけでも無いでしょうし、きちんと動かすことさえ出来ればどれでも構わないレベルだと思います。
4
4
 
5
5
  むしろ、機能の追加によってもコード全体の見通しを良く(読み易く分かり易く)出来るかの方が難しいと思います。
6
+
7
+
8
+
9
+ ---
10
+
11
+ episteme さんの回答のコードからファイル分割・単方向リストにしてみました。
12
+
13
+ commandline は簡単にする為固定サイズです。
14
+
15
+ ```c
16
+
17
+ #include <stdio.h>
18
+
19
+ #include "history.h"
20
+
21
+
22
+
23
+ int main() {
24
+
25
+ HISTORY* hist = history_initialize(4); // 最新4つ分を保持する
26
+
27
+
28
+
29
+ const char* input[6] = { "alpha", "brabo", "charlie", "delta", "echo", "fox" };
30
+
31
+ for (int i = 0; i < 6; ++i) {
32
+
33
+ history_push(hist, input[i]);
34
+
35
+ for (int h = history_size(hist); h > 0; --h) {
36
+
37
+ printf("[%s] ", history_at(hist, h-1));
38
+
39
+ }
40
+
41
+ printf("\n");
42
+
43
+ }
44
+
45
+ history_terminate(hist);
46
+
47
+ return 0;
48
+
49
+ }
50
+
51
+ ```
52
+
53
+ history.h
54
+
55
+ ```c
56
+
57
+ #ifndef HISTORY_H_
58
+
59
+ #define HISTORY_H_
60
+
61
+
62
+
63
+ typedef struct link {
64
+
65
+ struct link *next;
66
+
67
+ char commandline[100];
68
+
69
+ } HIST_LINK;
70
+
71
+
72
+
73
+ typedef struct history {
74
+
75
+ HIST_LINK *list;
76
+
77
+ int capacity;
78
+
79
+ int size;
80
+
81
+ } HISTORY;
82
+
83
+
84
+
85
+ HISTORY* history_initialize(int cap);
86
+
87
+ void history_terminate(HISTORY* hist);
88
+
89
+
90
+
91
+ int history_size(const HISTORY* hist);
92
+
93
+ int history_capacity(const HISTORY* hist);
94
+
95
+ const char* history_at(const HISTORY* hist, int n);
96
+
97
+ void history_pop_back(HISTORY* hist);
98
+
99
+ void history_push(HISTORY* hist, const char* str);
100
+
101
+
102
+
103
+ #endif /* HISTORY_H_ */
104
+
105
+ ```
106
+
107
+ history.c
108
+
109
+ ```c
110
+
111
+ #include <stdio.h>
112
+
113
+ #include <stdlib.h>
114
+
115
+ #include <string.h>
116
+
117
+
118
+
119
+ #include "history.h"
120
+
121
+
122
+
123
+ /* history 実装 */
124
+
125
+
126
+
127
+ HISTORY* history_initialize(int cap) {
128
+
129
+ HISTORY* hist = (HISTORY*)malloc(sizeof(HISTORY));
130
+
131
+ if(hist != NULL) {
132
+
133
+ hist->list = NULL;
134
+
135
+ hist->capacity = cap;
136
+
137
+ }
138
+
139
+ return hist;
140
+
141
+ }
142
+
143
+
144
+
145
+ int history_size(const HISTORY* hist) {
146
+
147
+ int size = 0;
148
+
149
+ for(HIST_LINK *link=hist->list; link!=NULL; link=link->next, size++);
150
+
151
+ return size;
152
+
153
+ }
154
+
155
+
156
+
157
+ int history_capacity(const HISTORY* hist) {
158
+
159
+ return hist->capacity;
160
+
161
+ }
162
+
163
+
164
+
165
+ const char* history_at(const HISTORY* hist, int n) {
166
+
167
+ if(n < 0) return NULL;
168
+
169
+ HIST_LINK *link = hist->list;
170
+
171
+ for(int i=0; i<n && link!=NULL; i++, link=link->next);
172
+
173
+ return link!=NULL ? link->commandline : NULL;
174
+
175
+ }
176
+
177
+
178
+
179
+ void history_pop_back(HISTORY* hist) {
180
+
181
+ if(hist->list == NULL) return;
182
+
183
+ HIST_LINK **p = &hist->list;
184
+
185
+ for(; (*p)->next!=NULL; p=&(*p)->next);
186
+
187
+ free(*p);
188
+
189
+ *p = NULL;
190
+
191
+ }
192
+
193
+
194
+
195
+ void history_push(HISTORY* hist, const char* str) {
196
+
197
+ HIST_LINK *newelement = (HIST_LINK *)malloc(sizeof(HIST_LINK));
198
+
199
+ newelement->next = NULL;
200
+
201
+ strcpy(newelement->commandline, str);
202
+
203
+
204
+
205
+ while(history_size(hist) >= hist->capacity) history_pop_back(hist);
206
+
207
+
208
+
209
+ newelement->next = hist->list;
210
+
211
+ hist->list = newelement;
212
+
213
+ }
214
+
215
+
216
+
217
+ void history_terminate(HISTORY* hist) {
218
+
219
+ for(HIST_LINK *link=hist->list, *p; (p=link)!=NULL; ) {
220
+
221
+ link = link->next;
222
+
223
+ free(p);
224
+
225
+ }
226
+
227
+ free(hist);
228
+
229
+ }
230
+
231
+ ```
232
+
233
+ 実行結果:
234
+
235
+ ```plain text
236
+
237
+ [alpha]
238
+
239
+ [alpha] [brabo]
240
+
241
+ [alpha] [brabo] [charlie]
242
+
243
+ [alpha] [brabo] [charlie] [delta]
244
+
245
+ [brabo] [charlie] [delta] [echo]
246
+
247
+ [charlie] [delta] [echo] [fox]
248
+
249
+ ```