質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

1177閲覧

Segmentation fault: 11というエラーが出ます・・・

TSUNA-omarilove

総合スコア3

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/11/13 05:31

以下のプログラムを作成したのですが、実行するとき、一応求めていた物を得ることはできるのですが、実行結果の最後に、一定数の文字数を超えるとSegmentation fault: 11と表示されてしまいます・・・
結果は一応正しいものが得れるのですが、これが表示されるのはあまり良くない気がします・・・
どなたかご教授いただけると嬉しいです。
#include <stdio.h>
#include <stdlib.h>

int main(void){
char ip1;
char ip2;
char IP1;
char IP2;
ip2 = &ip1;
IP2 = &IP1;
int i = 0;
int I = 0;
int counter = 0;
printf("英単語を入力>>");
scanf("%s",ip2);
printf("入力された英単語は");
while(
(ip2 + i) != '\0'){
printf("%c",
(ip2 + i));
i++;
counter++;
}
printf("です。\n");
printf("逆方向に英単語を出力>>");
for(i = counter - 1;i >= 0;i--){
*(IP2 + I) = (ip2 + i);
printf("%c",
(IP2 + I));
}
printf("\n");

return 0;

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

上限をなくすためにはどのようにしたら良いのでしょうか。

C

1#include <stdio.h> // getchar, putchar, printf 2 3struct S { int c; struct S *p; } t; 4 5void g(struct S *p) 6{ 7 struct S s = { getchar() }; 8 p->p = &s; 9 if (s.c == EOF || s.c == '\n') { 10 printf("入力された英単語は: "); 11 for (p = t.p; p != &s; p = p->p) putchar(p->c); 12 printf("\n逆方向に単語を出力: "); 13 } 14 else g(&s), putchar(s.c); 15} 16 17int main(void) 18{ 19 printf("英単語を入力: "), g(&t), putchar('\n'); 20}

投稿2020/11/13 09:12

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

動的メモリ確保についてあまり詳しくはありませんが、
while文の中で、動的確保するのは難しいのでしょうか。

c

1#include <stdio.h> 2#include <stdlib.h> 3 4int main(void){ 5 char* t; 6 int n = 1; 7 t = (char*)malloc(n* sizeof(char)); 8 9 10 char c; 11 int idx = 0; 12 13 do { 14 scanf("%c", &c); 15 if (idx+1 == n) { 16 n*=2; 17 char* s = (char*)malloc(n* sizeof(char)); 18 for (int i = 0;i < idx;++i) s[i] = t[i]; 19 free(t); 20 t = s; 21 } 22 t[idx] = c; 23 idx++; 24 } while (c != '\n'); 25 printf("%s\n", t); 26 free(t); 27 28 return 0; 29}

投稿2020/11/13 06:31

Kose-i

総合スコア26

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。
突っ込みどころ満載のコードですね。

  • 先ずコードはマークダウンで記載しましょう。
  • C言語はcase-sensitiveなのでip1とIP1は別物ですが、紛らわしいので目視ではっきり区別できる変数名にしましょう。
  • ポインタ変数ip2とIP2に割り当てられているメモリ実体はchar変数ip1,IP1で共に1バイトの領域しかありません。

短い文字列入力で動いたのはたまたま(運が良かったから)です。
scanfはnull終端するので、実際には1バイト文字入力した時点でバッファオーバーフローが発生します。

これが表示されるのはあまり良くない気がします・・・

あまり良くないではなく絶対ダメなコードです。
配列やポインタをもっと学習することを強くお勧めします。

### ■追記
余裕のあるバッファを確保して、かつscanfの結果を保護するのであれば、
上記なら80バイトまでの文字列はNULL終端されますし、
入力が80バイトを超えた場合、80バイトで打ち切ってnull終端した文字列を返却してくれます。
これならバッファーオーバーフローを心配しなくて済みます。
※scanfのフォーマット指定子で文字列%sに小数を指定すると小数の値が最大文字列となります。

### ■追記2
文字列を入力させる前に、何文字入力するか問い合わせてその文字数+1の領域を動的に確保する。
という方法を思いつきましたが、もうすこしマシな方法がありました。
Cのコンパイル環境がないのでエラーが出たらごめんなさい。

■追記3

辞書に載っている最大長の英単語が45文字(pneumonoulttamicroscopicsilicovolcanoconiosis)なので、46バイト以上の配列を確保すれば、一応命題はクリアできると思います。

投稿2020/11/13 05:43

編集2020/11/15 23:38
DreamTheater

総合スコア1095

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TSUNA-omarilove

2020/11/13 05:54

ご回答ありがとうございます。 先の回答者様にも同様に返信させていただいたのですが、私も初めは解答者様のおっしゃるように1バイトではなくip[256]のようにしてプログラムを作成していたのですが、問に英単語の文字数はプログラム上で上限がないように作成しろ、とありました。おそらく動的メモリの確保を用いて解答していくのだろうなとは見当がついたのですがそこから全くわからなくなってしまい、このようなめちゃくちゃなコードになってしまいました。 どのようにすれば題意に沿ってプログラムが作成できるのか、お忙しいとは思いますがお時間ある時にでもご回答いただけると嬉しいです。
DreamTheater

2020/11/13 06:00

成程、追記が参考になるかと思いましたが、そもそも命題に無理がありますね。 『英単語の文字数はプログラム上で上限がないように作成しろ』 malloc関数で動的に巨大なメモリを確保すること自体は可能ですが、そもそも入力が終わらなければ何文字(何バイト)入力されたかわからない訳で、問題作成者の意図を測りかねます。 まあ命題が「英単語」ということなので実存する英単語の最大長+1の配列を定義すれば要件を満足していると主張できますねWw 他には無理やりな方法ですが、回答に「追記2」として掲載します。
kazuma-s

2020/11/14 01:38

> ※scanfのフォーマット指定子で文字列%sに小数を指定すると小数の値が最大文字列となります。 これは間違いです。scanf の書式に "." はありません。"%80s" です。 コンパイル環境を用意して確かめてみてください。
kazuma-s

2020/11/14 01:42

> (void)scanf("%c", wordBuff + pos); > if (*(wordBuff + pos) = '\0') break; scanf でキーボードから '\0' を読み込むことは通常ありません。
DreamTheater

2020/11/15 23:31

kazuma-sさんご指摘ありがとうございます。 回答を修正します。
guest

0

まず、

scanf("%s",ip2);

文字列を入力した場合の格納先が、1文字分しか存在してません。これではダメです
C言語での文字列というのはどういうものなのかを確認しよう

投稿2020/11/13 05:33

編集2020/11/13 05:35
y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TSUNA-omarilove

2020/11/13 05:36

無知で申し訳ありません。 ip2 = &ip1; を入力すれば格納先が存在することにはなりませんか...?
y_waiwai

2020/11/13 05:38

ip1というのは、char変数です。 そのアドレスを入れたところで、1文字分の格納先しか存在しません。
y_waiwai

2020/11/13 05:39

どーにかするなら、 char ip1[100]; ぐらいのサイズの配列にしましょう
tatsu99

2020/11/13 05:43

>ip2 = &ip1; >を入力すれば格納先が存在することにはなりませんか...? 1バイトの格納先になりますね。 格納先はたっぷりとっておいた方が安全です。 char ip1[256]; ip2 = ip1;
TSUNA-omarilove

2020/11/13 05:44

ご丁寧に解説して下さり、ありがとうございます。 私も初めそのようにサイズを指定して作成していたのですが、扱える英単語の文字数にプログラム上の上限があってはいけない(メモリや環境による上限はok)プログラムを作成しろ、という問題をといておりましてそこで完全にわからなくなってしまいこのようなプログラムにしてしまいました。 上限をなくすためにはどのようにしたら良いのでしょうか。 お時間がある時にご回答いただけると嬉しいです。
y_waiwai

2020/11/13 05:51

上限があってはいけないというテーマであるなら、scanfで入力を行うというのはほとんど不可能です まあ、初心者のうちは、あまりこういう事を考えないで、取りあえず動くコードを組んでいけばいいかとはおもいますが。。 こういう制限のないコードを組もうとするとかなりレベルが高くなります やり口としては、一定サイズのバッファを用意して、そのサイズ分の文字列を順番に読み出していくというコードになりますね
Daregada

2020/11/13 06:43

提示されたプログラムを見る限り、質問者のレベルは「扱える英単語の文字数にプログラム上の上限があってはいけない」プログラムを作成できるレベルに達していないので、まずはサイズに上限のあるプログラムを問題なく作成することを目指してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問