teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

修正

2015/07/28 04:44

投稿

ngyuki
ngyuki

スコア4516

answer CHANGED
@@ -110,14 +110,15 @@
110
110
  ```c
111
111
  void get_names(char **names, int namelen, char *buf)
112
112
  {
113
- int i;
113
+ int i = 0;
114
114
  char c = '\0';
115
+ namelen--;
115
116
 
116
- for (i=0; *buf && (i < namelen); buf++) {
117
+ for (; *buf; buf++) {
117
118
  if ((*buf == ' ') || (*buf == '\n')) {
118
119
  *buf = '\0';
119
120
  }
120
- if ((c == '\0') && (*buf != '\0')) {
121
+ if ((c == '\0') && (*buf != '\0') && (i < namelen)) {
121
122
  names[i++] = buf;
122
123
  }
123
124
  c = *buf;

2

get_names

2015/07/28 04:43

投稿

ngyuki
ngyuki

スコア4516

answer CHANGED
@@ -102,3 +102,31 @@
102
102
  `names` に以下のような形式で複数の文字列が入ります。
103
103
 
104
104
  `homy\0tomi\0sami\0 ... rare\0tara\0\0`
105
+
106
+ ---
107
+
108
+ あと、KenTerada さんの回答が良い感じだと思ったので、`get_names` 関数をシンプルに改良してみました。
109
+
110
+ ```c
111
+ void get_names(char **names, int namelen, char *buf)
112
+ {
113
+ int i;
114
+ char c = '\0';
115
+
116
+ for (i=0; *buf && (i < namelen); buf++) {
117
+ if ((*buf == ' ') || (*buf == '\n')) {
118
+ *buf = '\0';
119
+ }
120
+ if ((c == '\0') && (*buf != '\0')) {
121
+ names[i++] = buf;
122
+ }
123
+ c = *buf;
124
+ }
125
+
126
+ names[i] = NULL;
127
+ }
128
+ ```
129
+
130
+ スペースと改行をすべてヌル文字にして、ヌル文字から文字に切り替わった位置(=文字列の先頭)を `names` に保存しています。
131
+
132
+ スペースが連続している場合や、改行の直前にスペースが入力された場合にもそれっぽく処理できます。

1

追記

2015/07/28 04:40

投稿

ngyuki
ngyuki

スコア4516

answer CHANGED
@@ -52,4 +52,53 @@
52
52
  9: tara
53
53
  ```
54
54
 
55
- 関数から文字列の配列を返す方法をもうちょっと考えないとダメだとは思いますし、入力行が 1024 文字以上の場合や名前が 256 文字以上の場合や、名前の数が 20 個以上の場合とか、いろいろ修正しなければならないところは多いです。
55
+ 関数から文字列の配列を返す方法をもうちょっと考えないとダメだとは思いますし、入力行が 1024 文字以上の場合や名前が 256 文字以上の場合や、名前の数が 20 個以上の場合とか、いろいろ修正しなければならないところは多いです。
56
+
57
+ ---
58
+
59
+ 複数の文字列を返す関数を C 言語で作るとき、次のような風にすることが多かった気もします。
60
+
61
+ ```c
62
+ #include <stdio.h>
63
+ #include <string.h>
64
+
65
+ void getnames(char* names)
66
+ {
67
+ char buf[1024];
68
+ char* tok;
69
+ char* out = names;
70
+
71
+ while (fgets(buf, sizeof(buf), stdin)) {
72
+ tok = strtok(buf, " \n");
73
+ if (tok) {
74
+ do {
75
+ strcpy(out, tok);
76
+ out += strlen(tok) + 1;
77
+ }
78
+ while (tok = strtok(NULL, " \n"));
79
+ }
80
+ }
81
+
82
+ out = '\0';
83
+ }
84
+
85
+ int main(void)
86
+ {
87
+ char names[1024];
88
+ char* str;
89
+
90
+ getnames(names);
91
+
92
+ printf("=== output ===\n");
93
+
94
+ for (str = names; *str; str+=strlen(str)+1) {
95
+ printf("%s\n", str);
96
+ }
97
+
98
+ return 0;
99
+ }
100
+ ```
101
+
102
+ `names` に以下のような形式で複数の文字列が入ります。
103
+
104
+ `homy\0tomi\0sami\0 ... rare\0tara\0\0`