⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 substitute.cpp

📁 软件工程学生-系统级编程课程实验
💻 CPP
字号:
/* substitute -- substitute strings in a list of files

  This program operates on a set of files listed on 
  the command line. The first file specifies a list of
  string substitutions to be performed on the remaining
  files. The list of string substitutions has the form:

  "string 1" "replacement 1"
  "string 2" "replacement 2"
  ...

  If a string contains a double quote character or
  a backslash character, escape the character with 
  backslash: "\"" denotes the string with one double
  quote character. "\\" contains one backslash.
  Each file is searched for instances of "string 1".
  Any occurences are replaced with "replacement 1".
  In a similar manner, all "string 2"s are replaced
  with "replacement 2"s, and so on.

  The results are written to the input file. Be sure
  to keep a backup of files if you do not want to lose
  the originals when you run this program.
*/

#include "afx.h"
#include "iostream.h"

// parse a quoted string from buffer
// return final index in string
int parse1(CString *buffer, int start, CString *str)
{
	// look for initial quote:
    int i = buffer->Find("\"", start);
	if (i != -1) {
		// copy to result string
		str->Empty();
		int j = 0;	// index into str
		i++; // skip over the opening double-quote
		// scan and copy up to the closing double-quote:
		while ((*buffer)[i] != 0) {
			if ((*buffer)[i] == '\\') {
				// read next char to see what to do
				i++;
				if ((*buffer)[i] != 0) {
					str->Insert(j++, CString((*buffer)[i]));
				}
			} else if ((*buffer)[i] == '\"') {
				return i + 1;
			}
			str->Insert(j++, CString((*buffer)[i]));
			i++;
		}
	}
	return -1;
}


// parse two quoted strings from buffer; return false on failure
//
bool parse(CString *buffer, CString *pattern, CString *replacement)
{
	int start = parse1(buffer, 0, pattern);
	if (start < 0) {
		return false;
	}
	start = parse1(buffer, start, replacement);
	return (start >= 0);
}



void substitute(CString *data, CString *pattern, CString *replacement)
{
	int loc;
	// find every occurrence of pattern:
	for (loc = data->Find(*pattern, 0); loc >= 0;
		 loc = data->Find(*pattern, 0)) {
	    // delete the pattern string from loc:
		data->Delete(loc, pattern->GetLength());
		// insert each character of the replacement string:
		for (int i = 0; i < replacement->GetLength(); i++) {
			data->Insert(loc + i, (*replacement)[i]);}
	}
}



void do_substitutions(CString *data, CString *subs_filename)
{
	TRY {
		CStdioFile file(*subs_filename, CFile::modeRead);
		while (true) {
			CString buffer;   // holds line from file
			CString pattern;
			CString replacement;
			file.ReadString(buffer);
			// handle end of file
			if (buffer.GetLength() == 0) break;
			if (parse(&buffer, &pattern, &replacement)) {
				substitute(data, &pattern, &replacement);
			} else {
				cout << "Bad pattern/replacement line: " << buffer << endl;
				return;
			}
		}	
	}
	CATCH(CFileException, e ) {
		cout << "File could not be opened or read " << e->m_cause << endl;
	}
	END_CATCH
}


void process_file(CString *filename, CString *subs_filename)
{
	// read in filename to a CString
	TRY {   
		CFile file(*filename, CFile::modeRead);
		int size = file.GetLength();
		// read the data, allocate more than we need
		char *data = new char[size + 16];
		file.Read(data, size);
		// files are not zero-terminated but string should be:
		data[size] = 0;
		// now we can make a CString from the data:
		CString content(data);
		delete data; // data is no longer needed
		do_substitutions(&content, subs_filename);
		// write the data
		file.Close();
		file.Open(*filename, CFile::modeWrite);
		file.Write(content, content.GetLength());
		file.SetLength(content.GetLength());
		file.Close();
	}
	CATCH(CFileException, e ) {
		cout << "File could not be opened or read " << 
			    e->m_cause << " " << *filename << endl;
	}
	END_CATCH

}




int main(int argc, char *argv[])
{
	if (argc < 3) {
		cout << "Not enough input arguments" << endl;
		cout << "Usage: substitute subs-file src1 src2 ..." << endl;
	} else {
		CString subs_filename(argv[1]);
		for (int i = 2; i < argc; i++) {
			CString filename(argv[i]);
			process_file(&filename, &subs_filename);
		}
	}
	return 0;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -