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

回答編集履歴

14

修正

2019/01/14 06:29

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -44,7 +44,7 @@
44
44
  // ・255バイト以内で区切り文字以外を連続するだけ読み取る
45
45
  // ・255バイトを超えた部分や区切り文字自身は読み捨てる
46
46
  // ・EOF (-1) が返されるまでの間は読み続ける
47
- for (int r; (r = scanf("%255[^\n;]%*[^\n;]", buffer)) != EOF; scanf("%*c")) {
47
+ for (int r; (r = scanf("%255[^\r\n;]%*[^\r\n;]", buffer)) != EOF; scanf("%*c")) {
48
48
 
49
49
  // 読み込めた場合のみ r=1 になっている
50
50
  if (r < 1) {
@@ -55,7 +55,7 @@
55
55
  int skip = 1;
56
56
 
57
57
  // 余分な文字を削ぎ落として出力
58
- for (char *t = strtok(buffer, "\r\n "); t != NULL; t = strtok(NULL, "\r\n ")) {
58
+ for (char *t = strtok(buffer, "\t "); t != NULL; t = strtok(NULL, "\t ")) {
59
59
  skip = 0;
60
60
  printf("%s", t);
61
61
  }

13

追記

2019/01/14 06:29

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -8,19 +8,64 @@
8
8
 
9
9
  int main(void)
10
10
  {
11
- // 255バイト+NULLバイトのスペースを確保
11
+ // 255バイト+NULLバイトのスペースを確保
12
- char buffer[256];
12
+ char buffer[256];
13
13
 
14
- // ・255バイト以内で区切り文字以外を連続するだけ読み取る
14
+ // ・255バイト以内で区切り文字以外を連続するだけ読み取る
15
- // ・255バイトを超えた部分や区切り文字自身は読み捨てる
15
+ // ・255バイトを超えた部分や区切り文字自身は読み捨てる
16
- // ・EOF (-1) が返されるまでの間は読み続ける
16
+ // ・EOF (-1) が返されるまでの間は読み続ける
17
- for (int r; (r = scanf("%255[^\r\n\t ;]%*[^\r\n\t ;]", buffer)) != EOF; scanf("%*c")) {
17
+ for (int r; (r = scanf("%255[^\r\n\t ;]%*[^\r\n\t ;]", buffer)) != EOF; scanf("%*c")) {
18
- // 読み込めた場合のみ r=1 になっている
19
- if (r > 0) {
20
- puts(buffer);
21
- }
22
- }
23
18
 
19
+ // 読み込めた場合のみ r=1 になっている
20
+ if (r > 0) {
21
+ puts(buffer);
22
+ }
23
+ }
24
+
24
- return 0;
25
+ return 0;
25
26
  }
27
+ ```
28
+
29
+ ----
30
+
31
+ 【補足】
32
+
33
+ もし `z = 3` のような式の間に半角スペースが入ってくる場合には `strtok` も絡めてもうひと工夫必要ですね。
34
+
35
+ ```c
36
+ #include <stdio.h>
37
+ #include <string.h>
38
+
39
+ int main(void)
40
+ {
41
+ // 255バイト+NULLバイトのスペースを確保
42
+ char buffer[256];
43
+
44
+ // ・255バイト以内で区切り文字以外を連続するだけ読み取る
45
+ // ・255バイトを超えた部分や区切り文字自身は読み捨てる
46
+ // ・EOF (-1) が返されるまでの間は読み続ける
47
+ for (int r; (r = scanf("%255[^\n;]%*[^\n;]", buffer)) != EOF; scanf("%*c")) {
48
+
49
+ // 読み込めた場合のみ r=1 になっている
50
+ if (r < 1) {
51
+ continue;
52
+ }
53
+
54
+ // 空行判定用変数
55
+ int skip = 1;
56
+
57
+ // 余分な文字を削ぎ落として出力
58
+ for (char *t = strtok(buffer, "\r\n "); t != NULL; t = strtok(NULL, "\r\n ")) {
59
+ skip = 0;
60
+ printf("%s", t);
61
+ }
62
+
63
+ // 空行ではなければ改行コードを出力
64
+ if (!skip) {
65
+ putchar('\n');
66
+ }
67
+ }
68
+
69
+ return 0;
70
+ }
26
71
  ```

12

修正

2019/01/14 05:51

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -11,11 +11,10 @@
11
11
  // 255バイト+NULLバイトのスペースを確保
12
12
  char buffer[256];
13
13
 
14
- // ・255バイト以内で「\r」「\n」「\t」「半角スペース」「;」以外の文字を連続するだけ読み取る
14
+ // ・255バイト以内で区切り文字以外を連続するだけ読み取る
15
- // ・255バイトを超えてる長い文字超えたぶんだけ読み捨てる
15
+ // ・255バイトを超えた部分や区切り文字自身は読み捨てる
16
- // ・ループの終わりに残っている「\r」「\n」「\t」「半角スペース」「;」を読み飛ばす
17
16
  // ・EOF (-1) が返されるまでの間は読み続ける
18
- for (int r; (r = scanf("%255[^\r\n\t ;]%*[^\r\n\t ;]", buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
17
+ for (int r; (r = scanf("%255[^\r\n\t ;]%*[^\r\n\t ;]", buffer)) != EOF; scanf("%*c")) {
19
18
  // 読み込めた場合のみ r=1 になっている
20
19
  if (r > 0) {
21
20
  puts(buffer);

11

修正

2019/01/14 04:54

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,6 +1,8 @@
1
1
  `fscanf` の書式を使って空白文字列の他に `;` も無視するように設定するとラクだと思います!
2
2
  (サンプルは `scanf` を使って標準入力→標準出力の流れにしておきます)
3
3
 
4
+ 備考: [標準入力から安全に文字列を受け取る方法いろいろ - Qiita](https://qiita.com/mpyw/items/aff12a6ff2c7726ed1d8#scanf%E3%81%AE%E5%88%A9%E7%94%A8)
5
+
4
6
  ```c
5
7
  #include <stdio.h>
6
8
 
@@ -9,10 +11,11 @@
9
11
  // 255バイト+NULLバイトのスペースを確保
10
12
  char buffer[256];
11
13
 
12
- // 255バイト以内で「\r」「\n」「\t」「半角スペース」「;」以外の文字を連続するだけ読み取る
14
+ // 255バイト以内で「\r」「\n」「\t」「半角スペース」「;」以外の文字を連続するだけ読み取る
15
+ // ・255バイトを超えてる長い文字列は超えたぶんだけ読み捨てる
13
- // ループの終わりに残っている「\r」「\n」「\t」「半角スペース」「;」を読み飛ばす
16
+ // ループの終わりに残っている「\r」「\n」「\t」「半角スペース」「;」を読み飛ばす
14
- // EOF (-1) が返されるまでの間は読み続ける
17
+ // EOF (-1) が返されるまでの間は読み続ける
15
- for (int r; (r = scanf("%255[^\r\n\t ;]", buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
18
+ for (int r; (r = scanf("%255[^\r\n\t ;]%*[^\r\n\t ;]", buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
16
19
  // 読み込めた場合のみ r=1 になっている
17
20
  if (r > 0) {
18
21
  puts(buffer);

10

コメント

2019/01/14 04:52

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -6,9 +6,14 @@
6
6
 
7
7
  int main(void)
8
8
  {
9
+ // 255バイト+NULLバイトのスペースを確保
9
10
  char buffer[256];
10
11
 
12
+ // 255バイト以内で「\r」「\n」「\t」「半角スペース」「;」以外の文字を連続するだけ読み取る
13
+ // ループの終わりに残っている「\r」「\n」「\t」「半角スペース」「;」を読み飛ばす
14
+ // EOF (-1) が返されるまでの間は読み続ける
11
15
  for (int r; (r = scanf("%255[^\r\n\t ;]", buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
16
+ // 読み込めた場合のみ r=1 になっている
12
17
  if (r > 0) {
13
18
  puts(buffer);
14
19
  }

9

修正

2019/01/14 04:41

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,16 +1,14 @@
1
- [標準入力から安全に文字列を受け取る方法いろいろ - Qiita](https://qiita.com/mpyw/items/aff12a6ff2c7726ed1d8#scanf%E3%81%AE%E5%88%A9%E7%94%A8)
2
- これをベースに `scanf` の代わりに `fscanf` でやのがラクかも?
1
+ `fscanf` の書式を使って空白文字列の他に `;` も無視すように設定するとラクだと思います!
3
- (サンプルは標準入力→標準出力の流れにしておきます)
2
+ (サンプルは `scanf` を使って標準入力→標準出力の流れにしておきます)
4
3
 
5
4
  ```c
6
5
  #include <stdio.h>
7
6
 
8
7
  int main(void)
9
8
  {
10
- const char *format = "%255[^\r\n\t ;]";
11
9
  char buffer[256];
12
10
 
13
- for (int r; (r = scanf(format, buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
11
+ for (int r; (r = scanf("%255[^\r\n\t ;]", buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
14
12
  if (r > 0) {
15
13
  puts(buffer);
16
14
  }

8

修正

2019/01/14 04:34

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -7,10 +7,10 @@
7
7
 
8
8
  int main(void)
9
9
  {
10
- const char *format = "%255[^\r\n\t ;]%*[\r\n\t ;]";
10
+ const char *format = "%255[^\r\n\t ;]";
11
11
  char buffer[256];
12
12
 
13
- for (int r; (r = scanf(format, buffer)) != EOF; scanf("%*c")) {
13
+ for (int r; (r = scanf(format, buffer)) != EOF; scanf("%*[\r\n\t ;]")) {
14
14
  if (r > 0) {
15
15
  puts(buffer);
16
16
  }

7

修正

2019/01/14 04:33

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,19 +1,21 @@
1
+ [標準入力から安全に文字列を受け取る方法いろいろ - Qiita](https://qiita.com/mpyw/items/aff12a6ff2c7726ed1d8#scanf%E3%81%AE%E5%88%A9%E7%94%A8)
1
- `fscanf` を使いましょう!
2
+ これをベースに `scanf` の代わりに `fscanf` でやるのがラクかも?
2
- (サンプルは標準入出力を使うため代わり `scanf` にしておきます)
3
+ (サンプルは標準入力→標準出力の流れにしておきます)
3
4
 
4
5
  ```c
5
6
  #include <stdio.h>
6
7
 
7
8
  int main(void)
8
9
  {
10
+ const char *format = "%255[^\r\n\t ;]%*[\r\n\t ;]";
9
- char buffer[256];
11
+ char buffer[256];
10
12
 
11
- for (int r; (r = scanf("%255[^\r\n\t ;]", buffer)) != EOF; scanf("%*c")) {
13
+ for (int r; (r = scanf(format, buffer)) != EOF; scanf("%*c")) {
12
- if (r > 0) {
14
+ if (r > 0) {
13
- puts(buffer);
15
+ puts(buffer);
14
- }
16
+ }
15
- }
17
+ }
16
18
 
17
- return 0;
19
+ return 0;
18
20
  }
19
21
  ```

6

コメント

2019/01/14 04:31

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -1,17 +1,14 @@
1
+ `fscanf` を使いましょう!
1
- [標準入力から安全に文字列受け取る方法いろいろ - Qiita](https://qiita.com/mpyw/items/aff12a6ff2c7726ed1d8#scanf%E3%81%AE%E5%88%A9%E7%94%A8)
2
+ (サンプルは標準入力を使うため代わりに `scanf` にしておきます)
2
3
 
3
- これをベースに `scanf` の代わりに `fscanf` でやるのがラクかも?
4
- (サンプルは標準入力→標準出力の流れにしておきます)
5
-
6
4
  ```c
7
5
  #include <stdio.h>
8
6
 
9
7
  int main(void)
10
8
  {
11
- const char *format = "%255[^\r\n\t ;]%*[^\r\n\t ;]";
12
9
  char buffer[256];
13
10
 
14
- for (int r; (r = scanf(format, buffer)) != EOF; scanf("%*c")) {
11
+ for (int r; (r = scanf("%255[^\r\n\t ;]", buffer)) != EOF; scanf("%*c")) {
15
12
  if (r > 0) {
16
13
  puts(buffer);
17
14
  }

5

修正

2019/01/14 04:29

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -11,7 +11,7 @@
11
11
  const char *format = "%255[^\r\n\t ;]%*[^\r\n\t ;]";
12
12
  char buffer[256];
13
13
 
14
- for (int r; (r = scanf(format, buffer, &length)) != EOF; scanf("%*c")) {
14
+ for (int r; (r = scanf(format, buffer)) != EOF; scanf("%*c")) {
15
15
  if (r > 0) {
16
16
  puts(buffer);
17
17
  }

4

修正

2019/01/14 04:19

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -8,12 +8,12 @@
8
8
 
9
9
  int main(void)
10
10
  {
11
+ const char *format = "%255[^\r\n\t ;]%*[^\r\n\t ;]";
11
12
  char buffer[256];
12
- size_t length;
13
13
 
14
- for (; scanf("%255[^\r\n\t ;]%zn%*[^\r\n\t ;]", buffer, &length) != EOF; scanf("%*c")) {
14
+ for (int r; (r = scanf(format, buffer, &length)) != EOF; scanf("%*c")) {
15
- if (length > 0) {
15
+ if (r > 0) {
16
- puts(buffer);
16
+ puts(buffer);
17
17
  }
18
18
  }
19
19
 

3

修正

2019/01/14 04:18

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -11,7 +11,7 @@
11
11
  char buffer[256];
12
12
  size_t length;
13
13
 
14
- for (; scanf("%255[^\r\n\t ;]%zn%[^\r\n\t ;]*", buffer, &length) != EOF; scanf("%*c")) {
14
+ for (; scanf("%255[^\r\n\t ;]%zn%*[^\r\n\t ;]", buffer, &length) != EOF; scanf("%*c")) {
15
15
  if (length > 0) {
16
16
  puts(buffer);
17
17
  }

2

修正

2019/01/14 04:07

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -11,7 +11,7 @@
11
11
  char buffer[256];
12
12
  size_t length;
13
13
 
14
- for (; scanf("%255[^\r\n\t ;]%zn%[^\r\n\t ;]*", buffer) != EOF; scanf("%*c")) {
14
+ for (; scanf("%255[^\r\n\t ;]%zn%[^\r\n\t ;]*", buffer, &length) != EOF; scanf("%*c")) {
15
15
  if (length > 0) {
16
16
  puts(buffer);
17
17
  }

1

修正

2019/01/14 04:06

投稿

mpyw
mpyw

スコア5223

answer CHANGED
@@ -9,9 +9,12 @@
9
9
  int main(void)
10
10
  {
11
11
  char buffer[256];
12
+ size_t length;
12
13
 
13
- for (; scanf("%255[^\r\n\t ;]%[^\r\n\t ;]*", buffer) != EOF; scanf("%*c")) {
14
+ for (; scanf("%255[^\r\n\t ;]%zn%[^\r\n\t ;]*", buffer) != EOF; scanf("%*c")) {
15
+ if (length > 0) {
14
- puts(buffer);
16
+ puts(buffer);
17
+ }
15
18
  }
16
19
 
17
20
  return 0;