回答編集履歴

4

c style object-oriented

2017/07/29 16:24

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -133,3 +133,249 @@
133
133
  - 文字列中から文字検索は自分でループを書かずに、`strchr`関数を利用しましょう(今回は`strtok`でやってしまいましたが)
134
134
 
135
135
  - 構造体をつかうと可読性が上がることがあります。
136
+
137
+
138
+
139
+ # 追記
140
+
141
+
142
+
143
+ もうすこし関数わけするべきだったという反省を活かし、C言語でオブジェクト指向してみました。C++書きたい・・・
144
+
145
+
146
+
147
+ ```C
148
+
149
+ #include <stdio.h>
150
+
151
+ #include <stdlib.h>
152
+
153
+ #include <string.h>
154
+
155
+ #include <assert.h>
156
+
157
+
158
+
159
+ #ifndef countof
160
+
161
+ # if defined(_MSC_VER) && !defined(__c2__)
162
+
163
+ //MSVC except Clang CodeGen
164
+
165
+ # define countof _countof
166
+
167
+ # else
168
+
169
+ # define countof( arr ) (sizeof(arr) / sizeof(*arr))
170
+
171
+ # endif
172
+
173
+ #endif
174
+
175
+
176
+
177
+ ///! 単語情報を格納する構造体
178
+
179
+ typedef struct tag_word_info {
180
+
181
+ ///! 見つかった数
182
+
183
+ size_t count;
184
+
185
+ ///! 単語
186
+
187
+ char word[1001];
188
+
189
+ } word_info;
190
+
191
+
192
+
193
+ typedef struct tag_word_list word_list;
194
+
195
+ size_t word_list_find_word(const word_list* words, const char* key_str);
196
+
197
+ void word_list_print(const word_list* words);
198
+
199
+ void word_list_push_back(word_list* words, const char* word);
200
+
201
+ struct tag_word_list {
202
+
203
+ size_t (*find_word)(const word_list* words, const char* key_str);
204
+
205
+ void (*print)(const word_list* words);
206
+
207
+ void (*push_back)(word_list* words, const char* word);
208
+
209
+ ///! 現在の大きさ(1001以下)
210
+
211
+ size_t size;
212
+
213
+ ///! リスト
214
+
215
+ word_info list[1001];
216
+
217
+ };
218
+
219
+
220
+
221
+ /**
222
+
223
+ * @brief find word from list
224
+
225
+ * @params words[in] read-only pointer to word list
226
+
227
+ * @params key_str[in] read-only pointer to key string to find.
228
+
229
+ * @return Found index. If not found, this function will return `words->size`.
230
+
231
+ */
232
+
233
+ size_t word_list_find_word(const word_list* words, const char* key_str){
234
+
235
+ size_t i;
236
+
237
+ for (i = 0; i < words->size; ++i) {
238
+
239
+ if (0 == strcmp(words->list[i].word, key_str)) return i;
240
+
241
+ }
242
+
243
+ return i;
244
+
245
+ }
246
+
247
+ /**
248
+
249
+ * @brief print-out word list
250
+
251
+ * @params words[in] read-only pointer to word list
252
+
253
+ */
254
+
255
+ void word_list_print(const word_list* words){
256
+
257
+ for (size_t i = 0; i < words->size; ++i) {
258
+
259
+ //単語リストとそれぞれの出現回数を表示
260
+
261
+ printf("%s %zd\n", words->list[i].word, words->list[i].count);
262
+
263
+ }
264
+
265
+ }
266
+
267
+ /**
268
+
269
+ * @brief append new word to word list
270
+
271
+ * @params words[in,out] pointer to word list
272
+
273
+ * @params word[in] Read-only pointer to string to append.
274
+
275
+ */
276
+
277
+ void word_list_push_back(word_list* words, const char* word){
278
+
279
+ if(countof(words->list) <= words->size) return;
280
+
281
+ memcpy(words->list[words->size].word, word, strlen(word) + 1);
282
+
283
+ words->list[words->size].count = 1;
284
+
285
+ ++words->size;
286
+
287
+ }
288
+
289
+ /**
290
+
291
+ * @brief create word list
292
+
293
+ */
294
+
295
+ word_list* new_word_list(){
296
+
297
+ word_list* re = (word_list*)malloc(sizeof(word_list));
298
+
299
+ if(NULL == re) return NULL;
300
+
301
+ //set function pointer
302
+
303
+ re->find_word = word_list_find_word;
304
+
305
+ re->print = word_list_print;
306
+
307
+ re->push_back = word_list_push_back;
308
+
309
+ //init size is zero
310
+
311
+ re->size = 0;
312
+
313
+ return re;
314
+
315
+ }
316
+
317
+ /**
318
+
319
+ * @brief delete word list
320
+
321
+ * @params words[in,out] pointer to word list
322
+
323
+ */
324
+
325
+ void delete_word_list(word_list* words){
326
+
327
+ free(words);
328
+
329
+ }
330
+
331
+ int main(void) {
332
+
333
+ char line[1001];
334
+
335
+ word_list* words = new_word_list();//単語リスト
336
+
337
+ if(NULL == words) return 1;
338
+
339
+ //半角スペースで区切られて単語(半角英字)が標準入力される(末尾は改行)
340
+
341
+ if(NULL == fgets(line, countof(line), stdin)){
342
+
343
+ delete_word_list(words);
344
+
345
+ return 1;
346
+
347
+ }
348
+
349
+ for(const char* word = strtok(line, " \n"); NULL != word; word = strtok(NULL, " \n")) {
350
+
351
+ const size_t found_index = words->find_word(words, word);
352
+
353
+ if(words->size == found_index) {
354
+
355
+ //同単語がない場合は追加
356
+
357
+ words->push_back(words, word);
358
+
359
+ }
360
+
361
+ else {
362
+
363
+ //同単語の場合、カウントアップ
364
+
365
+ ++words->list[found_index].count;
366
+
367
+ }
368
+
369
+ }
370
+
371
+ words->print(words);
372
+
373
+ delete_word_list(words);
374
+
375
+ }
376
+
377
+ ```
378
+
379
+
380
+
381
+ [https://wandbox.org/permlink/qo52P1eMw7KXXnAQ](https://wandbox.org/permlink/qo52P1eMw7KXXnAQ)

3

m

2017/07/29 16:24

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -58,15 +58,13 @@
58
58
 
59
59
  size_t ct = 0; //入力された単語の数
60
60
 
61
- word_info word_list[1001]; //単語カウン
61
+ word_info word_list[1001];//単語リス
62
62
 
63
63
  //半角スペースで区切られて単語(半角英字)が標準入力される(末尾は改行)
64
64
 
65
65
  if(NULL == fgets(line, countof(line), stdin)) return 1;
66
66
 
67
67
  for(const char* word = strtok(line, " \n"); NULL != word; word = strtok(NULL, " \n")) {
68
-
69
- const size_t word_len = strlen(word);
70
68
 
71
69
  size_t i;
72
70
 
@@ -88,11 +86,13 @@
88
86
 
89
87
  //同単語がない場合はlist_W[i]へコピー
90
88
 
89
+ //strcpy(word_list[i].word, word);
90
+
91
- memcpy(word_list[i].word, word, word_len + 1);
91
+ memcpy(word_list[i].word, word, strlen(word) + 1);
92
92
 
93
93
  word_list[i].count = 1;
94
94
 
95
- ct += 1;
95
+ ++ct;
96
96
 
97
97
  }
98
98
 
@@ -116,7 +116,7 @@
116
116
 
117
117
 
118
118
 
119
- [https://wandbox.org/permlink/rHGycJrn1Svf1rEb](https://wandbox.org/permlink/rHGycJrn1Svf1rEb)
119
+ [https://wandbox.org/permlink/AdnCtvSQJx5d32MM](https://wandbox.org/permlink/AdnCtvSQJx5d32MM)
120
120
 
121
121
 
122
122
 

2

specify const

2017/07/29 06:53

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -64,7 +64,7 @@
64
64
 
65
65
  if(NULL == fgets(line, countof(line), stdin)) return 1;
66
66
 
67
- for(char* word = strtok(line, " \n"); NULL != word; word = strtok(NULL, " \n")) {
67
+ for(const char* word = strtok(line, " \n"); NULL != word; word = strtok(NULL, " \n")) {
68
68
 
69
69
  const size_t word_len = strlen(word);
70
70
 
@@ -116,7 +116,7 @@
116
116
 
117
117
 
118
118
 
119
- [https://wandbox.org/permlink/x3PF2ZURrjSU1Boh](https://wandbox.org/permlink/x3PF2ZURrjSU1Boh)
119
+ [https://wandbox.org/permlink/rHGycJrn1Svf1rEb](https://wandbox.org/permlink/rHGycJrn1Svf1rEb)
120
120
 
121
121
 
122
122
 

1

strchrいらなかった

2017/07/29 06:43

投稿

yumetodo
yumetodo

スコア5850

test CHANGED
@@ -64,13 +64,7 @@
64
64
 
65
65
  if(NULL == fgets(line, countof(line), stdin)) return 1;
66
66
 
67
- for(char* word = strtok(line, " "); NULL != word; word = strtok(NULL, " ")) {
67
+ for(char* word = strtok(line, " \n"); NULL != word; word = strtok(NULL, " \n")) {
68
-
69
- char* lf_pos = strchr(word, '\n');
70
-
71
- //改行文字の除去
72
-
73
- if(NULL != lf_pos) *lf_pos = '\0';
74
68
 
75
69
  const size_t word_len = strlen(word);
76
70
 
@@ -122,7 +116,7 @@
122
116
 
123
117
 
124
118
 
125
- [https://wandbox.org/permlink/Ydnd0XwCQd64VgoQ](https://wandbox.org/permlink/Ydnd0XwCQd64VgoQ)
119
+ [https://wandbox.org/permlink/x3PF2ZURrjSU1Boh](https://wandbox.org/permlink/x3PF2ZURrjSU1Boh)
126
120
 
127
121
 
128
122
 
@@ -136,6 +130,6 @@
136
130
 
137
131
  - 配列の添字として使う変数は原則`size_t`型にしましょう
138
132
 
139
- - 文字列中から文字検索は自分でループを書かずに、`strchr`関数を利用しましょう
133
+ - 文字列中から文字検索は自分でループを書かずに、`strchr`関数を利用しましょう(今回は`strtok`でやってしまいましたが)
140
134
 
141
135
  - 構造体をつかうと可読性が上がることがあります。