文字の置換の仕方 – プログラミング – Home

通知
すべてクリア

文字の置換の仕方


としや
 としや
(@としや)
ゲスト
結合: 16年前
投稿: 4
Topic starter  

/*入力した文字列で!があったらすべて!?に置換するプログラムを作っています。
insertを使いたいのですが、うまくいかなくて困っています。
insert以外の部分はちゃんんとできていると思います。
c++を勉強し始めたばかりでよくわかっていませんので、ご教授お願いします。
*/

#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;

int main(void) {

string a,s;

cout <<文字列を入力してください<<endl;
getline(cin,s);

int i,j=0;

while( j!= s.npos) {
i=s.find_first_of(!,j);

if(i==s.npos){

cout << s.substr(j) << endl;
break;
}
if( i>0) {
cout << s.substr(j, i-j);
j=i;
}

i=s.find_first_not_of(!,j);

if( i== s.npos) {
a=s.substr(j);
j=i;
}
else{
a=s.substr(j,i-j);
j=i;
}
cout<< s.insert(a.c_str(),!?)<<endl;
} return 0;
}


引用解決済
トピックタグ
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

std::basic_string (std::sting) には replace というメンバーがあるし
std::replace っつ関数もあるわけだが(こっちは語長が変わる目的には使いづらい)

目的が「置換したい」のであれば自作せず素直に replace
目的が「自作したい」「insert が使いたい」のであればそう言ってくれ


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

とりあえず、replaceではなくて?


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

とりあえず、std::string::replaceではなくて?


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

# 書き込みミスった上に、内容かぶりました…すみませんorz


返信引用
としや
 としや
(@としや)
ゲスト
結合: 16年前
投稿: 4
Topic starter  

replaceは使わずにinsertで自分で作りたいです。


返信引用
ryo
 ryo
(@ryo)
ゲスト
結合: 23年前
投稿: 252
 

では、うまくいかないとはどういう状態になってるのか?を説明して


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

テケトー

#include <iostream>
#include <string>

int main()
{
std::string input;
std::cout << 文字列を入力してください << std::endl;
std::getline(std::cin, input);

std::string::size_type index = 0;
while (index != std::string::npos)
{
index = input.find_first_of(!, index);
if (index != std::string::npos)
{
++index;
input.insert(index, ?);
}
}
std::cout << input.c_str() << std::endl;

return 0;
}


返信引用
としや
 としや
(@としや)
ゲスト
結合: 16年前
投稿: 4
Topic starter  

>>ryo

今は、コンパイルは通って表示できるのですが、?を表示するときにループを抜け切れ
てなく、出力が止まらない状態です。

#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;

int main(void) {

string a,s;

cout <<文字列を入力してください<<endl;
getline(cin,s);

int i,j=0;

while( j!= s.npos) {
i=s.find_first_of(!,j);

if(i==s.npos){

cout << s.substr(j) << endl;
break;
}
if( i>0) {
cout << s.substr(j, i-j);
j=i;

}
s.insert(i,?);
cout<<s.c_str()<<endl;
}

return 0;
}


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

今回の要望に対しては find_first_of より find のほうが適切。
find : 与えられたオペランドシーケンスに一致する位置
find_first_of : 与えられたオペランドの要素のどれかに一致する位置

で、なにか難しく考えすぎなような気がする。
・文字列の終わりまでループする
・ ! をみつけたら、その直後に ? を挿入する
だけでいいわけで npos との判定を何度も行ったり substr 取ったりする必要はない。

挿入文字が1文字であり、挿入前文字と同じ文字を含まない前提で単純化したら
int main() {
  string s(WoW!! This!is a Text!);
  for (string::size_type p=0; (p=s.find('!', p))!=string::npos;) {
    ++p;
    s.insert(p, ?);
    ++p;
  }
  cout << s << endl;
  return 0;
}
挿入文字数が1文字より多い場合などは宿題にしておこう。


返信引用
ryo
 ryo
(@ryo)
ゲスト
結合: 23年前
投稿: 252
 

自作したいというので、質問者さんのソースについて

無限ループになってるのは

>i=s.find_first_of(!,j);
ここでみつけた!の位置そのままに?を挿入してるためです。
たとえば

t!t

この例から、!を見つけた場所に挿入すると文字列は

t?!t

となります。

次に
j=i;
をしてから、j(=i)の位置から検索するということは
?を挿入したところから検索するということなので、
右にずれた「!」を再度検索することになります。

以降、これがずーっと繰り返されてしまいます。

ですので、
「見つけた場所」から「挿入すべき場所」に変えないといけません


返信引用
multi
 multi
(@multi)
ゲスト
結合: 16年前
投稿: 1
 

http://oshiete1.goo.ne.jp/qa4990874.html

>発言される前に「使用上の注意」を必ずお読み下さい。
> マルチポストとは、「同じ内容の質問などを複数の掲示板等に書き込むこと」です。
この行為は
> マナー違反として嫌われています。マルチポストは行わないで下さい。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました