Câu trả lời:
std::string
không chứa chức năng như vậy nhưng bạn có thể sử dụng replace
chức năng độc lập từ algorithm
tiêu đề.
#include <algorithm>
#include <string>
void some_func() {
std::string s = "example string";
std::replace( s.begin(), s.end(), 'x', 'y'); // replace all 'x' to 'y'
}
std::string::replace()
thay vì std::replace()
! 'x' ( char
) được truyền ngầm thành size_t
[giá trị 120], do đó toàn bộ chuỗi hoặc một phần của chuỗi sẽ được lấp đầy với 120 bản sao của 'y'.
Tôi nghĩ tôi cũng sẽ sử dụng giải pháp tăng cường :
#include <boost/algorithm/string/replace.hpp>
// in place
std::string in_place = "blah#blah";
boost::replace_all(in_place, "#", "@");
// copy
const std::string input = "blah#blah";
std::string output = boost::replace_all_copy(input, "#", "@");
-I
cờ cho trình biên dịch của mình để nó tìm thấy các thư viện Boost trên hệ thống của bạn. Có lẽ bạn cần phải cài đặt nó trước.
Câu hỏi tập trung vào character
thay thế, nhưng, vì tôi thấy trang này rất hữu ích (đặc biệt là nhận xét của Konrad ), tôi muốn chia sẻ cách triển khai tổng quát hơn này, cho phép giải quyết substrings
tốt:
std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) {
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
return str;
}
Sử dụng:
std::cout << ReplaceAll(string("Number Of Beans"), std::string(" "), std::string("_")) << std::endl;
std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("X")) << std::endl;
std::cout << ReplaceAll(string("ghghjghugtghty"), std::string("gh"), std::string("h")) << std::endl;
Đầu ra:
Số_Of_Beans
XXjXugtXty
hhjhugthty
BIÊN TẬP:
Những điều trên có thể được thực hiện theo cách phù hợp hơn, trong trường hợp các màn trình diễn là mối quan tâm của bạn, bằng cách trả về không có gì ( void
) và thực hiện các thay đổi trực tiếp trên chuỗi str
được cung cấp dưới dạng đối số, được truyền theo địa chỉ thay vì theo giá trị . Điều này sẽ tránh việc sao chép chuỗi gốc vô ích và tốn kém, trong khi trả về kết quả. Cuộc gọi của bạn, sau đó ...
Mã số:
static inline void ReplaceAll2(std::string &str, const std::string& from, const std::string& to)
{
// Same inner code...
// No return statement
}
Hy vọng điều này sẽ hữu ích cho một số người khác ...
from
chuỗi có trống không, nếu không một vòng lặp vô tận sẽ xảy ra.
Hãy tưởng tượng một blob nhị phân lớn trong đó tất cả 0x00 byte sẽ được thay thế bằng "\ 1 \ x30" và tất cả 0x01 byte bằng "\ 1 \ x31" vì giao thức truyền tải không cho phép \ 0 byte.
Trong trường hợp:
các giải pháp được cung cấp không thể được áp dụng (vì chúng chỉ thay thế các ký tự đơn) hoặc có vấn đề về hiệu năng, vì chúng sẽ gọi chuỗi :: thay thế nhiều lần để tạo ra các bản sao kích thước của blob nhiều lần. (Tôi không biết giải pháp tăng cường, có thể nó ổn từ quan điểm đó)
Điều này đi dọc theo tất cả các lần xuất hiện trong chuỗi nguồn và xây dựng từng chuỗi mới một lần :
void replaceAll(std::string& source, const std::string& from, const std::string& to)
{
std::string newString;
newString.reserve(source.length()); // avoids a few memory allocations
std::string::size_type lastPos = 0;
std::string::size_type findPos;
while(std::string::npos != (findPos = source.find(from, lastPos)))
{
newString.append(source, lastPos, findPos - lastPos);
newString += to;
lastPos = findPos + from.length();
}
// Care for the rest after last occurrence
newString += source.substr(lastPos);
source.swap(newString);
}
Một tìm kiếm đơn giản và thay thế cho một nhân vật sẽ đi một cái gì đó như:
s.replace(s.find("x"), 1, "y")
Để làm điều này cho toàn bộ chuỗi, điều dễ dàng sẽ là lặp cho đến khi bạn s.find
bắt đầu quay lại npos
. Tôi cho rằng bạn cũng có thể bắt range_error
để thoát khỏi vòng lặp, nhưng điều đó hơi xấu.
{
nhân vật. Tôi không biết "cú đúp" là gì. Có lẽ bạn có một số loại vấn đề phông chữ?
Nếu bạn đang tìm cách thay thế nhiều hơn một ký tự và chỉ xử lý std::string
, thì đoạn mã này sẽ hoạt động, thay thế sNeedle trong sHaystack bằng sReplace và sNeedle và sReplace không cần phải có cùng kích thước. Thường trình này sử dụng vòng lặp while để thay thế tất cả các lần xuất hiện, thay vì chỉ lần đầu tiên được tìm thấy từ trái sang phải.
while(sHaystack.find(sNeedle) != std::string::npos) {
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
}
find
cuộc gọi hai lần. Xem xét làm cho kết quả đó là một biến tạm thời.
Như Kirill đã đề xuất, hãy sử dụng phương thức thay thế hoặc lặp lại dọc theo chuỗi thay thế từng char một cách độc lập.
Ngoài ra, bạn có thể sử dụng find
phương pháp hoặc find_first_of
tùy thuộc vào những gì bạn cần làm. Không có giải pháp nào trong số này sẽ thực hiện công việc trong một lần, nhưng với một vài dòng mã bổ sung bạn phải làm cho chúng hoạt động cho bạn. :-)
#include <iostream>
#include <string>
using namespace std;
// Replace function..
string replace(string word, string target, string replacement){
int len, loop=0;
string nword="", let;
len=word.length();
len--;
while(loop<=len){
let=word.substr(loop, 1);
if(let==target){
nword=nword+replacement;
}else{
nword=nword+let;
}
loop++;
}
return nword;
}
//Main..
int main() {
string word;
cout<<"Enter Word: ";
cin>>word;
cout<<replace(word, "x", "y")<<endl;
return 0;
}
word
dài, có thể có rất nhiều chi phí trong khi gọi hàm. Bạn có thể tối ưu hóa điều này bằng cách đi qua word
, target
và replacement
như const-tài liệu tham khảo.
Thế còn Abseil StrReplace ALL ? Từ tệp tiêu đề:
// This file defines `absl::StrReplaceAll()`, a general-purpose string
// replacement function designed for large, arbitrary text substitutions,
// especially on strings which you are receiving from some other system for
// further processing (e.g. processing regular expressions, escaping HTML
// entities, etc.). `StrReplaceAll` is designed to be efficient even when only
// one substitution is being performed, or when substitution is rare.
//
// If the string being modified is known at compile-time, and the substitutions
// vary, `absl::Substitute()` may be a better choice.
//
// Example:
//
// std::string html_escaped = absl::StrReplaceAll(user_input, {
// {"&", "&"},
// {"<", "<"},
// {">", ">"},
// {"\"", """},
// {"'", "'"}});
Trường cũ :-)
std::string str = "H:/recursos/audio/youtube/libre/falta/";
for (int i = 0; i < str.size(); i++) {
if (str[i] == '/') {
str[i] = '\\';
}
}
std::cout << str;
Kết quả:
H: \ recursos \ audio \ youtube \ libre \ falta \
Những công việc này! Tôi đã sử dụng một cái gì đó tương tự như thế này cho một ứng dụng hiệu sách, nơi kho lưu trữ được lưu trữ trong CSV (như tệp .dat). Nhưng trong trường hợp của một char duy nhất, có nghĩa là trình thay thế chỉ là một char duy nhất, ví dụ '|', nó phải nằm trong dấu ngoặc kép "|" để không ném một chuyển đổi không hợp lệ const char.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count = 0; // for the number of occurences.
// final hold variable of corrected word up to the npos=j
string holdWord = "";
// a temp var in order to replace 0 to new npos
string holdTemp = "";
// a csv for a an entry in a book store
string holdLetter = "Big Java 7th Ed,Horstman,978-1118431115,99.85";
// j = npos
for (int j = 0; j < holdLetter.length(); j++) {
if (holdLetter[j] == ',') {
if ( count == 0 )
{
holdWord = holdLetter.replace(j, 1, " | ");
}
else {
string holdTemp1 = holdLetter.replace(j, 1, " | ");
// since replacement is three positions in length,
// must replace new replacement's 0 to npos-3, with
// the 0 to npos - 3 of the old replacement
holdTemp = holdTemp1.replace(0, j-3, holdWord, 0, j-3);
holdWord = "";
holdWord = holdTemp;
}
holdTemp = "";
count++;
}
}
cout << holdWord << endl;
return 0;
}
// result:
Big Java 7th Ed | Horstman | 978-1118431115 | 99.85
Hiện tại tôi đang sử dụng CentOS, vì vậy phiên bản trình biên dịch của tôi ở bên dưới. Phiên bản C ++ (g ++), C ++ 98 mặc định:
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Nếu bạn sẵn sàng sử dụng std::string
s, bạn có thể sử dụng strsub
chức năng của ứng dụng mẫu này hoặc cập nhật nó nếu bạn muốn nó lấy một loại hoặc bộ tham số khác để đạt được cùng một mục tiêu. Về cơ bản, nó sử dụng các thuộc tính và chức năng của std::string
để nhanh chóng xóa bộ ký tự trùng khớp và chèn các ký tự mong muốn trực tiếp vào trong std::string
. Mỗi lần thực hiện thao tác thay thế này, phần bù sẽ cập nhật nếu nó vẫn có thể tìm thấy các ký tự trùng khớp để thay thế và nếu không thể thay thế thêm, nó sẽ trả về chuỗi ở trạng thái từ bản cập nhật cuối cùng.
#include <iostream>
#include <string>
std::string strsub(std::string stringToModify,
std::string charsToReplace,
std::string replacementChars);
int main()
{
std::string silly_typos = "annoiiyyyng syyyllii tiipos.";
std::cout << "Look at these " << silly_typos << std::endl;
silly_typos = strsub(silly_typos, "yyy", "i");
std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl;
silly_typos = strsub(silly_typos, "ii", "y");
std::cout << "There, no more " << silly_typos << std::endl;
return 0;
}
std::string strsub(std::string stringToModify,
std::string charsToReplace,
std::string replacementChars)
{
std::string this_string = stringToModify;
std::size_t this_occurrence = this_string.find(charsToReplace);
while (this_occurrence != std::string::npos)
{
this_string.erase(this_occurrence, charsToReplace.size());
this_string.insert(this_occurrence, replacementChars);
this_occurrence = this_string.find(charsToReplace,
this_occurrence + replacementChars.size());
}
return this_string;
}
Nếu bạn không muốn dựa vào việc sử dụng std::string
s làm tham số của mình để thay vào đó bạn có thể chuyển qua chuỗi kiểu C, bạn có thể xem mẫu được cập nhật bên dưới:
#include <iostream>
#include <string>
std::string strsub(const char * stringToModify,
const char * charsToReplace,
const char * replacementChars,
uint64_t sizeOfCharsToReplace,
uint64_t sizeOfReplacementChars);
int main()
{
std::string silly_typos = "annoiiyyyng syyyllii tiipos.";
std::cout << "Look at these " << silly_typos << std::endl;
silly_typos = strsub(silly_typos.c_str(), "yyy", "i", 3, 1);
std::cout << "After a little elbow-grease, a few less " << silly_typos << std::endl;
silly_typos = strsub(silly_typos.c_str(), "ii", "y", 2, 1);
std::cout << "There, no more " << silly_typos << std::endl;
return 0;
}
std::string strsub(const char * stringToModify,
const char * charsToReplace,
const char * replacementChars,
uint64_t sizeOfCharsToReplace,
uint64_t sizeOfReplacementChars)
{
std::string this_string = stringToModify;
std::size_t this_occurrence = this_string.find(charsToReplace);
while (this_occurrence != std::string::npos)
{
this_string.erase(this_occurrence, sizeOfCharsToReplace);
this_string.insert(this_occurrence, replacementChars);
this_occurrence = this_string.find(charsToReplace,
this_occurrence + sizeOfReplacementChars);
}
return this_string;
}
Đối với các tình huống đơn giản, nó hoạt động khá tốt mà không cần sử dụng bất kỳ thư viện nào khác sau đó std :: string (đã được sử dụng).
Thay thế tất cả các lần xuất hiện của ký tự a bằng ký tự b trong some_ chuỗi :
for (size_t i = 0; i < some_string.size(); ++i) {
if (some_string[i] == 'a') {
some_string.replace(i, 1, "b");
}
}
Nếu chuỗi lớn hoặc nhiều cuộc gọi để thay thế là một vấn đề, bạn có thể áp dụng kỹ thuật được đề cập trong câu trả lời này: https://stackoverflow.com/a/29752943/3622300
Đây là một giải pháp tôi đã triển khai, với tinh thần DRI tối đa. nó sẽ tìm kiếm sNeedle trong sHaystack và thay thế nó bằng sReplace, nTimes nếu không 0, khác với tất cả các lần xuất hiện của sNeedle. nó sẽ không tìm kiếm lại trong văn bản thay thế.
std::string str_replace(
std::string sHaystack, std::string sNeedle, std::string sReplace,
size_t nTimes=0)
{
size_t found = 0, pos = 0, c = 0;
size_t len = sNeedle.size();
size_t replen = sReplace.size();
std::string input(sHaystack);
do {
found = input.find(sNeedle, pos);
if (found == std::string::npos) {
break;
}
input.replace(found, len, sReplace);
pos = found + replen;
++c;
} while(!nTimes || c < nTimes);
return input;
}
std::string
là một container được thiết kế đặc biệt để hoạt động với các chuỗi ký tự. liên kết