回答編集履歴

3

修正

2015/07/28 04:44

投稿

ngyuki
ngyuki

スコア4516

test CHANGED
@@ -222,13 +222,15 @@
222
222
 
223
223
  {
224
224
 
225
- int i;
225
+ int i = 0;
226
226
 
227
227
  char c = '\0';
228
228
 
229
-
229
+ namelen--;
230
-
230
+
231
+
232
+
231
- for (i=0; *buf && (i < namelen); buf++) {
233
+ for (; *buf; buf++) {
232
234
 
233
235
  if ((*buf == ' ') || (*buf == '\n')) {
234
236
 
@@ -236,7 +238,7 @@
236
238
 
237
239
  }
238
240
 
239
- if ((c == '\0') && (*buf != '\0')) {
241
+ if ((c == '\0') && (*buf != '\0') && (i < namelen)) {
240
242
 
241
243
  names[i++] = buf;
242
244
 

2

get_names

2015/07/28 04:43

投稿

ngyuki
ngyuki

スコア4516

test CHANGED
@@ -207,3 +207,59 @@
207
207
  `homy\0tomi\0sami\0 ... rare\0tara\0\0`
208
208
 
209
209
 
210
+
211
+ ---
212
+
213
+
214
+
215
+ あと、KenTerada さんの回答が良い感じだと思ったので、`get_names` 関数をシンプルに改良してみました。
216
+
217
+
218
+
219
+ ```c
220
+
221
+ void get_names(char **names, int namelen, char *buf)
222
+
223
+ {
224
+
225
+ int i;
226
+
227
+ char c = '\0';
228
+
229
+
230
+
231
+ for (i=0; *buf && (i < namelen); buf++) {
232
+
233
+ if ((*buf == ' ') || (*buf == '\n')) {
234
+
235
+ *buf = '\0';
236
+
237
+ }
238
+
239
+ if ((c == '\0') && (*buf != '\0')) {
240
+
241
+ names[i++] = buf;
242
+
243
+ }
244
+
245
+ c = *buf;
246
+
247
+ }
248
+
249
+
250
+
251
+ names[i] = NULL;
252
+
253
+ }
254
+
255
+ ```
256
+
257
+
258
+
259
+ スペースと改行をすべてヌル文字にして、ヌル文字から文字に切り替わった位置(=文字列の先頭)を `names` に保存しています。
260
+
261
+
262
+
263
+ スペースが連続している場合や、改行の直前にスペースが入力された場合にもそれっぽく処理できます。
264
+
265
+

1

追記

2015/07/28 04:40

投稿

ngyuki
ngyuki

スコア4516

test CHANGED
@@ -107,3 +107,103 @@
107
107
 
108
108
 
109
109
  関数から文字列の配列を返す方法をもうちょっと考えないとダメだとは思いますし、入力行が 1024 文字以上の場合や名前が 256 文字以上の場合や、名前の数が 20 個以上の場合とか、いろいろ修正しなければならないところは多いです。
110
+
111
+
112
+
113
+ ---
114
+
115
+
116
+
117
+ 複数の文字列を返す関数を C 言語で作るとき、次のような風にすることが多かった気もします。
118
+
119
+
120
+
121
+ ```c
122
+
123
+ #include <stdio.h>
124
+
125
+ #include <string.h>
126
+
127
+
128
+
129
+ void getnames(char* names)
130
+
131
+ {
132
+
133
+ char buf[1024];
134
+
135
+ char* tok;
136
+
137
+ char* out = names;
138
+
139
+
140
+
141
+ while (fgets(buf, sizeof(buf), stdin)) {
142
+
143
+ tok = strtok(buf, " \n");
144
+
145
+ if (tok) {
146
+
147
+ do {
148
+
149
+ strcpy(out, tok);
150
+
151
+ out += strlen(tok) + 1;
152
+
153
+ }
154
+
155
+ while (tok = strtok(NULL, " \n"));
156
+
157
+ }
158
+
159
+ }
160
+
161
+
162
+
163
+ out = '\0';
164
+
165
+ }
166
+
167
+
168
+
169
+ int main(void)
170
+
171
+ {
172
+
173
+ char names[1024];
174
+
175
+ char* str;
176
+
177
+
178
+
179
+ getnames(names);
180
+
181
+
182
+
183
+ printf("=== output ===\n");
184
+
185
+
186
+
187
+ for (str = names; *str; str+=strlen(str)+1) {
188
+
189
+ printf("%s\n", str);
190
+
191
+ }
192
+
193
+
194
+
195
+ return 0;
196
+
197
+ }
198
+
199
+ ```
200
+
201
+
202
+
203
+ `names` に以下のような形式で複数の文字列が入ります。
204
+
205
+
206
+
207
+ `homy\0tomi\0sami\0 ... rare\0tara\0\0`
208
+
209
+