ファイル内の文字列を見つけて、ユーザー入力に置き換えたい。
これが私の大まかなコードです。
#include <iostream>
#include <fstream.h>
#include <string.h>
int main(){
istream readFile("test.txt");
string readout,
search,
replace;
while(getline(readFile,readout)){
if(readout == search){
// How do I replace `readout` with `replace`?
}
}
}
[〜#〜] update [〜#〜]
これが私の問題を解決したコードです
test.txt:
id_1
arfan
haider
id_2
saleem
haider
id_3
someone
otherone
C++コード:
#include <iostream>
#include <fstream>
#include <string>
using namesapce std;
int main(){
istream readFile("test.txt");
string readout,
search,
firstname,
lastname;
cout << "Enter the id which you want to modify";
cin >> search;
while(getline(readFile,readout)){
if(readout == search){
/*
id remains the same
But the First name and Last name are replaced with
the user `firstname` and `lastname` input
*/
cout << "Enter new First name";
cin >> firstname;
cout << "Enter Last name";
cin >> lastname;
}
}
}
仮定:
ユーザーがIDid_2
を検索します。その後、ユーザーは姓名Shafiq
とAhmed
を入力します。このコードを実行した後、test.txt
ファイルは次のようにレコードを変更する必要があります。
…
id_2
Shafiq
Ahmad
…
id_2
レコードのみが変更され、残りのファイルは同じままになります。
これはうまくいくはずです。 string::find
を使用して各行内の目的の部分文字列を検索し、string::replace
を使用して何かが見つかった場合はそれを置き換えました。
編集: Wordが1行に複数回出現する場合を忘れてしまいました。これを修正するためにwhile
を追加しました。
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
ifstream in(argv[1]);
ofstream out(argv[2]);
string wordToReplace(argv[3]);
string wordToReplaceWith(argv[4]);
if (!in)
{
cerr << "Could not open " << argv[1] << "\n";
return 1;
}
if (!out)
{
cerr << "Could not open " << argv[2] << "\n";
return 1;
}
string line;
size_t len = wordToReplace.length();
while (getline(in, line))
{
while (true)
{
size_t pos = line.find(wordToReplace);
if (pos != string::npos)
line.replace(pos, len, wordToReplaceWith);
else
break;
}
out << line << '\n';
}
}
私は@stefaanvが言ったことをします:
#include <iostream>
#include <fstream.h>
#include <string.h>
int main(){
ostream outFile("replaced.txt");
istream readFile("test.txt");
string readout;
string search;
string replace;
while(getline(readFile,readout)){
if(readout == search){
outFile << replace;
}
else {
outFile << readout;
}
}
}
編集:上記の解決策は、各行の情報が他の行の情報から独立している場合に機能します。更新では、名前行の情報はID行の情報に依存しています。したがって、上記の手法を拡張するには、1つのデータブロックの終わりに到達したことを示すwhileループの状態を維持する必要があります。
#include <iostream>
#include <fstream.h>
#include <string.h>
int main(){
ostream outFile("replaced.txt");
istream readFile("test.txt");
string readout;
string search, Fname, Lname;
unsigned int skipLines = 0;
cout << "Enter id which you want Modify";
cin >> search;
cout << "Enter new First name";
cin >> Fname;
cout << "Enter Last name";
cin >> Lname;
while(getline(readFile,readout)) {
if (skipLines != 0) {
skipLines--;
continue;
}
else if (readout == search) {
outFile << search << endl;
outFile << Fname << endl;
outFile << Lname << endl;
skipLines = 2;
}
else {
outFile << readout;
}
}
}
もう少し洗練されたアプローチは、各データブロックを構造体に格納することです。これにより、オーバーロードされた演算子<<&>>を使用できます。これにより、ファイルの読み取りと書き込みのコードがより明確になります。これは、「各行のデータが独立している」状況のコードと実質的に同じです。
#include <iostream>
#include <fstream.h>
#include <string.h>
struct NameRecord {
string id;
string fname;
string lname;
friend std::ostream& operator<<(std::ostream &os, const NameRecord &src);
friend std::istream& operator>>(std::istream &is, NameRecord &dst);
};
std::ostream& operator <<(std::ostream &os, const NameRecord &src) {
os << src.id << endl << src.fname << endl << src.lname << endl;
return os;
}
std::istream& operator >>(std::istream &is, NameRecord &dst) {
// may need to have more code to ignore whitespace, I'm not sure
if (is.good ()) {
is >> dst.id;
}
if (is.good ()) {
is >> dst.fname;
}
if (is.good ()) {
is >> dst.lname;
}
return is;
}
int main(){
ostream outFile("replaced.txt");
istream readFile("test.txt");
NameRecord inRecord, replaceRecord;
cout << "Enter id which you want Modify";
cin >> replaceRecord.id;
cout << "Enter new First name";
cin >> replaceRecord.Fname;
cout << "Enter Last name";
cin >> replaceRecord.Lname;
while (readFile.good()) {
// the >> operator reads the whole record (id, fname, lname)
readFile >> inRecord;
// the << operator writes the whole record
if (inRecord.id == replaceRecord.id) {
outFile << replaceRecord;
}
else {
outFile << inRecord;
}
}
}
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char **argv) {
if (argc < 4) {
cout << "Invalid input" << endl;
cout << "\tchange <old_Word> <new_Word> <file_list>";
}
fstream fs;
string tmp;
string oldw = argv[1];
string neww = argv[2];
for (int i = 3; i < argc; i++) {
fs.open(argv[i] , ios::in);
while (!fs.eof()) {
getline(fs, tmp);
while (tmp.find(oldw) != string::npos)
tmp.replace(tmp.find(oldw), sizeof(oldw), neww);
cout << tmp << endl;
}
}
fs.close();
return 0;
}
使用法:
./a.out old_Word new_Word filename