文字列を格納するバッファの長さ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
a

文字列を格納するバッファの長さ

#1

投稿記事 by a » 15年前

基本課題 12..2
文字列yを文字列xの最後に連結する関数stringcat(char [/url], char [/url])を作成せよ.この関数を用いて、入力された2つの文字列を連結するプ ログラムを作成せよ。

注意: stringcat()を呼び出すときは,連結後の文字列がxの 配列長を超えないように注意すること.

% ./catenate
文字列x (20字まで)? Ritsumeikan
文字列y (20字まで)? BKC
連結後のx: RitsumeikanBKC ←全部で20字以内なので連結可能
% ./catenate
文字列x (20字まで)? Ritsumeikan
文字列y (20字まで)? BiwakoKusatsuCampus
字数超過のため連結不可 ←20字を超えるので連結不可能
%
という問題で、

#include<stdio.h>

#define BUFFER_SIZE 260

void string_cat(char x[/url],char y[/url]){
int i,j,k;
for(i=0;x='\0';i++){
k++;
}
for(j=0;y[j]='\0';j++){
x[k] = y[j];
}
if(i+j<=20){
printf("連結後のx :%s",x);

}
else{
printf("字数超過のため連結不可");
}
}

int main(void){
char x[BUFFER_SIZE];
char y[BUFFER_SIZE];
printf("文字列x (20字まで)? ");
fgets(x,BUFFER_SIZE,stdin);
printf("文字列y (20字まで)? ");
fgets(y,BUFFER_SIZE,stdin);
string_cat(x, y);

}
というソースを書いてコンパイルして実行してみると、
文字列x (20字まで)? (入力) 
文字列y (20字まで)? (入力)
しか表示されず、2つの文字列を連結した関数が表示されません。なぜでしょうか?
どこをなおすべきでしょうか?

へろりくしょん

Re:文字列を格納するバッファの長さ

#2

投稿記事 by へろりくしょん » 15年前

>しか表示されず、2つの文字列を連結した関数が表示されません。なぜでしょうか?

2つの文字列を連結した関数が表示されないというのが今一つ意味不明ですが、
関数 string_cat() はちゃんと呼び出されています。

for(i=0;x='\0';i++)
の文ですが、x に '\0' を代入しているためループ条件が真になることはありません。

for(j=0;y[j]='\0';j++)
の文も同じですね。

それより、ソースを書く場合は
タグで囲むようにしてください。


追記です。
この手のバグは1行1行処理を追っていけばすぐに分かります。
ソースレベルデバッガの導入を強く強くお勧めします。 画像

バグ

Re:文字列を格納するバッファの長さ

#3

投稿記事 by バグ » 15年前

というか、別の問題で同じミスをしてましたよね…
まぁ、2回やらかせば、強く印象に残りますよね。

パコネコ

Re:文字列を格納するバッファの長さ

#4

投稿記事 by パコネコ » 15年前

for(i=0;x='\0';i++){
k++;
}
for(j=0;y[j]='\0';j++){
x[k] = y[j];
}
これって…x[k]にいっぱい代入されてる気がします…
[k+j-1]とかに変えてみたほうがいいと思います…

ココナ

Re:文字列を格納するバッファの長さ

#5

投稿記事 by ココナ » 15年前

他トピで規約について指摘されていましたよね。規約を読んでから利用しましょう。

MAY

Re:文字列を格納するバッファの長さ

#6

投稿記事 by MAY » 15年前

このコードをコンパイルすると

> for(i=0;x='\0';i++){
> for(j=0;y[j]='\0';j++){

この行に問題があると表示されたはずですが…
メッセージ読みました?

a

Re:文字列を格納するバッファの長さ

#7

投稿記事 by a » 15年前

すいません。利用規約読んでなかったです。
次からはオリジナルな名前にします。それから、似たような質問を2回もしてすいません。
for(i=0;x!='\0';i++){
for(j=0;y[j]!='\0';j++){
に直すとコンパイルはとおりました。
しかし、セグメントエラーがでます。デバッガで調べたいのですが、デバッガがインストールされておらず、調べられません。ちなみに、仮想でネットにつながらないVMwareを使っています。
どうすればインストールできるでしょうか?

初級者

Re:文字列を格納するバッファの長さ

#8

投稿記事 by 初級者 » 15年前

k を初期化していないのは、大いに問題ありです。

他にも問題があるかもしれません。

a

Re:文字列を格納するバッファの長さ

#9

投稿記事 by a » 15年前

パコネコさんが言うとおりx[k+j-1]にして、初級者さんのいうとおりにk=0で初期化するとコンパイルは通るのですが、実行すると2つの文字列を連結した関数が表示されず、セグメンテーションエラーがでます。
これ以上どこを直せばよいのでしょうか?

パコネコ

Re:文字列を格納するバッファの長さ

#10

投稿記事 by パコネコ » 15年前

今のコードはどうなっているのですか?
どこが変更されたのか、わからないのですが…
皆様がおっしゃっている他にどこが間違ってるのかわからないのですが…
エラーのメッセージはありますか?

a

Re:文字列を格納するバッファの長さ

#11

投稿記事 by a » 15年前

#include<stdio.h>

#define BUFFER_SIZE 260

void string_cat(char x[/url],char y[/url]){
int i,j,k;
k=0; ←ーーーーーーーーーーーーーーーーーーーー変更

 for(i=0;x!='\0';i++){←ーーーーーーーーーーーーー|
k++;                       | 
}                          |
for(j=0;y[j]!='\0';j++){ ←ーーーーーーーーーーーーー
x[k+j-1] = y[j]; ←ーーー
k++;
}
if(i+j<=20){
printf("連結後のx :%s",x);

}
else{
printf("字数超過のため連結不可");
}
}

int main(void){
char x[BUFFER_SIZE];
char y[BUFFER_SIZE];
printf("文字列x (20字まで)? ");
fgets(x,BUFFER_SIZE,stdin);
printf("文字列y (20字まで)? ");
fgets(y,BUFFER_SIZE,stdin);
string_cat(x, y);

}

そして、実行すると
文字列x (20字まで)? (入力) 
文字列y (20字まで)? (入力)
セグメンテーションエラーになります

パコネコ

Re:文字列を格納するバッファの長さ

#12

投稿記事 by パコネコ » 15年前

エラーについては私では見つけれないかも…
起動した結果、矢印と大文字空欄とk++以外に間違いは見つけれませんでした。
起動できましたし…(エラーの出るような)ソース上のミスは見つけれませんでした。
すいません。

MAY

Re:文字列を格納するバッファの長さ

#13

投稿記事 by MAY » 15年前

> for(j=0;y[j]!='\0';j++){ ←ーーーーーーーーーーーーー
> x[k+j-1] = y[j]; ←ーーー
> k++;

ここなんですがなぜkを増やすようにしたのですか。

パコネコ

Re:文字列を格納するバッファの長さ

#14

投稿記事 by パコネコ » 15年前

セグメンテーションエラーについて調べてみたところ(さっきからわからなかった…)
「領域破壊」もしくはそれと勘違いした時に出るとのことなので、
string_cat(x, y);
これのx,yを受け止めきれてないかもしれません…(char x[/url],char y[/url])こっちが…
というか(関係ないかもですが)
#define BUFFER_SIZE 260
これってこんなに大きい必要あるのでしょうか?
getsならともかくfgetsならここまででかくする必要があるのでしょうか?

うしお

Re:文字列を格納するバッファの長さ

#15

投稿記事 by うしお » 15年前

fgetsだとどうやら改行文字も取得してしまうようですね
なので入力は
scanf("%s",x);
scanf("%s",y);
に変更し
void string_cat(char x[/url],char y[/url]){
int i,j,k;
k=0;

for(i=0;x!='\0';i++){
k++;
}
for(j=0;y[j]!='\0';j++){
x[k+j] = y[j];
}
x[k+j] = '\0';

if(i+j<=20){
printf("連結後のx :%s",x);

}
else{
printf("字数超過のため連結不可");
}
}
となおすと正しく出ます

また、文字列連結後に調べて配列外にアクセスしていました、という事後報告は
良くないので、
あらかじめサイズを確認してから、連結、の流れが望ましいと思われます

a

Re:文字列を格納するバッファの長さ

#16

投稿記事 by a » 15年前

k++を消せばうまくいきました。みなさんありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る