以下のプログラムを作成したのですが、実行するとき、一応求めていた物を得ることはできるのですが、実行結果の最後に、一定数の文字数を超えると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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答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
総合スコア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
総合スコア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総合スコア1095
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/13 06:00
2020/11/14 01:38
2020/11/14 01:42
2020/11/15 23:31
0
まず、
scanf("%s",ip2);
文字列を入力した場合の格納先が、1文字分しか存在してません。これではダメです
C言語での文字列というのはどういうものなのかを確認しよう
投稿2020/11/13 05:33
編集2020/11/13 05:35総合スコア87774
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/13 05:36
2020/11/13 05:38
2020/11/13 05:39
2020/11/13 05:43
2020/11/13 05:44
2020/11/13 05:51
2020/11/13 06:43
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。