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

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

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

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

Q&A

解決済

3回答

9349閲覧

文字列挿入

ikuo-biyori

総合スコア56

C

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

0グッド

0クリップ

投稿2016/10/30 23:05

編集2016/10/30 23:12

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

C言語

1コード 2```#include <stdio.h> 3#include <string.h> /* 文字列操作関数用ヘッダファイル */ 4#include<stdlib.h> 5#define MAX 1024 6int main() 7{ 8 char buf[MAX]="[Wakamatsu]"; 9 char str[MAX]; 10 char rbuf[MAX]; 11 int n,i,len; 12 printf("%s\n",buf); 13 while(1) 14 if( scanf("%d %s",&n,str)!=EOF){ 15 for(i=n+1;str[i]!='\0';i++){ 16 strcpy(rbuf,str); 17 } 18 len=strlen(rbuf); 19 // printf("lenは%d\n",len); 20 for(i=n+1;i<=len+n+2;i++){ 21 buf[i]=rbuf[i]; 22 // printf("bufは%s\n",buf); 23 24 } 25 26 27 28 // printf("rbufは%s\n",rbuf); 29 // len=strlen(rbuf); 30 // rbuf[len+2]=']'; 31 // } 32 printf("bufは%s\n",buf); 33 34 35 } 36 37 // printf("[%s]%s",kaki,buf); 38 39 return 0; 40}

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

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

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

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

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

PineMatsu

2016/10/31 08:20

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

回答3

0

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

c

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

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

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

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

c

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

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

n=0
lenはAizuの文字数

c

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

と等価、そして今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は

c

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

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

[izu

が出力されている

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

処理としては

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

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

c

1int main() 2{ 3 char buf[MAX]="[Wakamatsu]"; 4 char str[MAX]; 5 char rbuf[MAX]; 6 7 int idx,widx,intsertlen, mvlen; 8 9 printf("%s\n",buf); 10 11 while(1) 12 { 13 14 if( scanf("%d %s",&idx,str)!=EOF){ 15 16 // 1.後ろにずらす文字列を退避 17 // 退避する文字列の長さ 18 mvlen = strlen(buf) - idx; 19 20 // bufの指定された挿入箇所以降の文字列退避 21 strncpy(rbuf,&buf[idx],mvlen); 22 rbuf[mvlen] = '\0'; 23 24 widx = idx; 25 26 27 // 2.文字列挿入 28 29 buf[widx++] = '['; 30 31 // 挿入したい文字列の文字数 32 intsertlen=strlen(str); 33 34 strncpy(&buf[widx],str,intsertlen); 35 36 widx = widx + intsertlen; 37 38 buf[widx++] = ']'; 39 40 // 3.退避していた文字列をもどす 41 strncpy(&buf[widx],rbuf,mvlen); 42 43 widx = widx + mvlen; 44 45 buf[widx] = '\0'; 46 47 printf("bufは%s\n",buf); 48 } 49 50 } 51 52 return 0; 53}

投稿2016/10/31 02:28

編集2016/10/31 02:31
hiim

総合スコア1689

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

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

0

ベストアンサー

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

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

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

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

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

c

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

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

c

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

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

投稿2016/10/31 00:08

編集2016/10/31 00:10
ttyp03

総合スコア16998

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

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

0

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

c

1#include <stdio.h> 2#include <string.h> /* 文字列操作関数用ヘッダファイル */ 3#include<stdlib.h> 4#define MAX 1024 5 6int main() 7{ 8 char buf[MAX]="[Wakamatsu]"; 9 char str[MAX]; 10 char rbuf[MAX]; 11 char p[2] = "["; 12 char q[2] = "]"; 13 int n; 14 printf("%s\n",buf); 15 while(scanf("%d %s",&n,str)!=EOF){ 16 strcpy(rbuf,p); 17 strcat(rbuf,str); 18 strcat(rbuf,q); 19 strcat(rbuf,buf+n); 20 strcpy(buf+n,rbuf); 21 printf("%s\n",buf); 22 } 23 return 0; 24}

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

投稿2016/10/31 00:06

編集2016/10/31 00:13
A.Ichi

総合スコア4070

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問