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

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

ただいまの
回答率

89.96%

文字列挿入

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 5,649

ikuo-biyori

score 54

いつもお世話になっています。プログC初心者です。文字列について質問させて頂きます。
[Wakamatsu]
0 Aizu
[Aizu][Wakamatsu]
11 young
[Aizu][Waka[young]matsu]
文字列のn文字目の後ろに、標準入力から入力した単語を挿入するプログラムを作成したいんです。でも[Aizu]の部分がうまくいかず[izu]と出てしまいます。どうすれば[Aizu]というように出力できますか?以下がコードです。

コード

include <stdio.h>

include <string.h> /* 文字列操作関数用ヘッダファイル */

include<stdlib.h>

define  MAX 1024

int main()
{
char buf[MAX]="[Wakamatsu]"; 
char str[MAX];
char rbuf[MAX];
int n,i,len;
printf("%s\n",buf);
while(1)
if( scanf("%d %s",&n,str)!=EOF){
for(i=n+1;str[i]!='\0';i++){
strcpy(rbuf,str);
}
len=strlen(rbuf);
// printf("lenは%d\n",len);
for(i=n+1;i<=len+n+2;i++){
buf[i]=rbuf[i];
// printf("bufは%s\n",buf);

}

//  printf("rbufは%s\n",rbuf);
//   len=strlen(rbuf);
// rbuf[len+2]=']';
// }
printf("bufは%s\n",buf);

}

// printf("[%s]%s",kaki,buf);

return 0;
}

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • PineMatsu

    2016/10/31 17:20

    プログラムコードは、```C言語 コード ```のコードの部分に書くようにします。つまり、```~```のブロックの中に書くということです。そうすると、見やすくなります。の

    キャンセル

回答 3

checkベストアンサー

0

詳しく原因は調べていませんが、strcpyなどを安易に使っているのが原因でしょう。
C言語では文字列の挿入関数はありませんから、自力で組み込む必要があります。
手順としては以下になります。
入力が "2 Aizu" の場合。

(1) 元のバッファを用意
buf="[Wakamatsu]"

(2) 挿入位置以降の文字列を入力文字列長分ずらしておく。[]の分を含めて+2文字。
buf="[W------akamatsu]"

(3) 空けた場所に入力文字列を入れる
buf="[W[Aizu]akamatsu]"

これをコード化したのが以下です(ループ内のみ抜粋)

scanf("%d %s",&n,str);
sprintf(rbuf,"[%s]",str);
/* ずらす */
for(i = strlen(buf)-1; i >= n; i--){
    buf[i + strlen(rbuf)] = buf[i];
}
/* 入れる */
for(i = 0; i < strlen(rbuf); i++){
    buf[n + i] = rbuf[i];
}
printf("bufは%s\n",buf);


上記を更に標準関数を利用したのが以下です(memmoveを使っているところがポイントです)

scanf("%d %s",&n,str);
sprintf(rbuf,"[%s]",str);
/* ずらす */
memmove(&buf[n + strlen(rbuf)], &buf[n], strlen(&buf[n]));
/* 入れる */
memcpy(&buf[n],rbuf,strlen(rbuf));
printf("bufは%s\n",buf);

C言語はNULL文字までで一つの文字列を解釈されますから、文字列を編集するときはNULLを意識して処理するようにしてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ご提示のコードでは無いので参考としてください。

#include <stdio.h>
#include <string.h> /* 文字列操作関数用ヘッダファイル */
#include<stdlib.h>
#define  MAX 1024

int main()
{
    char buf[MAX]="[Wakamatsu]";
    char str[MAX];
    char rbuf[MAX];
    char p[2] = "[";
    char q[2] = "]";
    int n;
    printf("%s\n",buf);
    while(scanf("%d %s",&n,str)!=EOF){
        strcpy(rbuf,p);
        strcat(rbuf,str);
        strcat(rbuf,q);
        strcat(rbuf,buf+n);
        strcpy(buf+n,rbuf);
        printf("%s\n",buf);
    }
    return 0;
}

尚、表示している有効桁数より大きい数字入力の場合のエラーが入っておりません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

まず、なぜそう言った不具合になっているかですが、

for(i=n+1;str[i]!='\0';i++){ 
    strcpy(rbuf,str); 
}


for文でiというカウンタを使っているにもかかわらず、    
strcpy(rbuf,str); 
という同じ処理をloopさせている。

for文でなく
strcpy(rbuf,str); 
だけでOK

不具合を引き起こしているのはこの部分

for(i=n+1;i<=len+n+2;i++){ 
    buf[i]=rbuf[i]; 
    // printf("bufは%s\n",buf);

}


最初の引数 0 Aizu で考えてみると

n=0
lenはAizuの文字数

for(i=1;i<=6;i++){ 
    buf[i]=rbuf[i]; 
}


と等価、そして今rbufは
rbuf = 'Aizu';(strcpyでコピーしたので一番後ろに'\0'が入っている)
buf = '[Wakamatsu]'

bufのindex 1にrbufのindex1からコピー
bufのindex 2にrbufのindex2からコピー
bufのindex 3にrbufのindex3からコピー
bufのindex 4にrbufのindex4からコピー
bufのindex 5にrbufのindex5からコピー
bufのindex 6にrbufのindex6からコピー

つまりbufは

buf[0]='[';
buf[1]='i';
buf[2]='z';
buf[3]='u';
buf[4]='\0';
buf[5]='\0'; // ここは初期化されてないので実際は不明
buf[6]='\0'; // ここは初期化されてないので実際は不明
buf[7]='t';
buf[8]='s';
buf[9]='u';
buf[10]=']';
buf[11]='\0';


となるのでprintfすると最初の'\0'までの

[izu

が出力されている

やり方としては
strcpy等使わずfor文で1文字づつしょりするのでも良いし、
strcpy
strncpy
strcat
などなど便利な関数使って作るなど無数にやり方あると思いますが、とりあえず、strcatのサンプルは他の方が載せられていらっしゃるので
strncpyを使って、

処理としては

1.入力された文字を挿入する事で後ろにずらされる文字列を退避
2.入力された文字を追記(前後のカッコも)
3.退避した文字列を後ろに追記

というサンプル置いておきます

int main()
{
        char buf[MAX]="[Wakamatsu]";
        char str[MAX];
        char rbuf[MAX];

        int idx,widx,intsertlen, mvlen;

        printf("%s\n",buf);

        while(1)
        {

                if( scanf("%d %s",&idx,str)!=EOF){

                        // 1.後ろにずらす文字列を退避
                        // 退避する文字列の長さ
                        mvlen = strlen(buf) - idx;

                        // bufの指定された挿入箇所以降の文字列退避
                        strncpy(rbuf,&buf[idx],mvlen);
                        rbuf[mvlen] = '\0';

                        widx = idx;


                        // 2.文字列挿入

                        buf[widx++] = '[';

                        // 挿入したい文字列の文字数
                        intsertlen=strlen(str);

                        strncpy(&buf[widx],str,intsertlen);

                        widx = widx + intsertlen;

                        buf[widx++] = ']';

                        // 3.退避していた文字列をもどす
                        strncpy(&buf[widx],rbuf,mvlen);

                        widx = widx + mvlen;

                        buf[widx] = '\0';

                        printf("bufは%s\n",buf);
                }

        }

        return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.96%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る