I'm using a simple encryption that I found online. Basically, I'm streaming in a file, checking to see if that file is open (if not, display an error message) and putting each line in each element of the array while encrypting the information. Afterwards I stream that encrypted information onto an output file.
However, I'm getting nothing in my output.txt file. The encryption works fine if you test it by itself.
Here is my code:
#include <string>
#include <fstream>
#include <sstream> // for ostringstream
#include <iostream>
#include <stdio.h>
#include <algorithm>
/* Credits to kylewbanks.com */
string encrypt (string content) {
char key[3] = {'K'}; //Any chars will work
string output = content;
for (int i = 0; i < content.size(); i++)
output[i] = content[i] ^ key[i % (sizeof(key) / sizeof(char))];
return output;
}
int main() {
string input, line;
string content[10000];
string encryptedContent[10000];
int counter = 0, innerChoice = 0, i, finalCounter;
cout << "\tPlease enter the file name to encrypt!\n";
cout << "\tType '0' to get back to the menu!\n";
cout << "Input >> ";
cin >> input;
/* Reads in the inputted file */
ifstream file(input.c_str());
//fopen, fscanf
if(file.is_open()) {
/* Counts number of lines in file */
while (getline(file, line)) {
counter++;
}
cout << counter;
finalCounter = counter;
for (i = 0; i < finalCounter; i++) {
file >> content[i];
encryptedContent[i] = encrypt(content[i]);
cout << encryptedContent[i];
}
} else {
cout << "\tUnable to open the file: " << input << "!\n";
}
/* Write encryption to file */
ofstream outputFile("output.txt");
for (i = 0; i < finalCounter ; i++) {
outputFile << encryptedContent;
}
outputFile.close();
}
Any clue what is wrong?
string content[10000];
string encryptedContent[10000];
This is wrong because it is creating 20000 strings (you probably think it is creating a large enough character array to read the data).
string content; is enough. It can be resized to handle any length of strings.
You just need to read/write the file in binary:
int main()
{
string input = "input.txt";
ifstream file(input, ios::binary);
if (!file.is_open())
{
cout << "\tUnable to open the file: " << input << "!\n";
return 0;
}
string plaintext;
//read the file
file.seekg(0, std::ios::end);
size_t size = (size_t)file.tellg();
file.seekg(0);
plaintext.resize(size, 0);
file.read(&plaintext[0], size);
cout << "reading:\n" << plaintext << "\n";
//encrypt the content
string encrypted = encrypt(plaintext);
//encrypt again so it goes back to original (for testing)
string decrypted = encrypt(encrypted);
cout << "testing:\n" << decrypted << "\n";
/* Write encryption to file */
ofstream outputFile("output.txt", ios::binary);
outputFile.write(encrypted.data(), encrypted.size());
return 0;
}
Related
when appending a file to another weird symbols appear at the end and it's ascii is -1, and if there another way to add a file to the other please share
void AddFile(char old_name[],char old_content[]) {
ofstream old_file;
ifstream new_file;
char new_name[255];
int len, f_begin, f_end;
cout << "Enter the file name: ";
cin.ignore();
cin.getline(new_name,255,'\n');
strcat(new_name, ".txt");
new_file.open(new_name);
f_begin = new_file.tellg();
new_file.seekg(0,ios::end);
f_end = new_file.tellg();
new_file.seekg(0);
len = f_end - f_begin;
char new_content[len+1];
new_content[len] = '\0';
for (int i=0; i< len; ++i) {
new_content[i] = new_file.get();
}
new_file.close();
strcat(old_content,"\n");
strcat(old_content,new_content);
old_file.open(old_name);
cout << old_content;
old_file << old_content;
old_file.close();
}
the .tellg() function gives the correct size
I have written just a snippet of code to help you in the right direction. You can use it or modify as needed.
#include <iostream>
#include <fstream>
using namespace std;
void AddFile(char old_name[], char old_content[]) {
ofstream old_file;
ifstream new_file;
char new_name[255];
int len, f_begin, f_end;
cout << "Enter the file name: ";
/*cin.ignore();
cin.getline(new_name, 255, '\n');*/
cin >> new_name;
strcat(new_name, ".txt");
new_file.open(new_name);
old_file.open(old_name, ios::ios_base::app);
char line[65535];
while (new_file.getline(line, 65535))
{
old_file << endl << line;
}
new_file.close();
old_file.close();
//verify new data
new_file.open(old_name);
while (new_file.getline(line, 65535))
{
cout << line << endl;
}
}
void main()
{
AddFile("hello.txt", "old data");
}
I might be able to better help if you can share your use case for it.
I am trying to store strings from a file into a vector containing an array. The following is my way of getting information into the vector:
{
string line;
int nooflines = 0;
ifstream myFile("SongListFile.txt");
while (getline(myFile, line)) {
nooflines++;
}
song temp;
myFile.open("SongListFile.txt");
for (int i = 0; i < nooflines; i++) {
myFile >> temp.title;
myFile >> temp.artist;
myFile >> temp.genre;
songs.push_back(temp);
}
myFile.close();
}
And this is how im trying to print this information:
void SongList::ViewSongList() {
int last_element_position = songs.size() - 1;
for (int i = last_element_position; i >= 0; i--)
{
cout << "\"" << songs[i].title << "\" by " << songs[i].artist << " (" << songs[i].genre << ")" << endl;
}
Why are the strings printing as if they contain nothing? Two of the templates print when there are two lines of text, so my problem is the strings not being stored in my array.
}
Apart that you could do the reading in one pass, as indicated in comments and other answers, the way you are "re-opening" the file is not correct. After the first pass a flag of your ifstream has been set when reaching the end of the file. Opening again the file (without closing) wont clear the flag.
You need either to myFile.close() before re-opening, or alternatively clear the flags then seek to the beginning:
myFile.clear(); // clear the flags
myFile.seekg(0, ios::beg); // seek back to beginning for the second pass
You don't need to count the number of lines in the file at all. You can do it in one pass :
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct Song { string title, artist, genre; };
int main() {
ifstream myFile;
myFile.open("songList.txt");
string aLine;
vector<Song> songs;
while(getline(myFile, aLine)) {
stringstream sin(aLine);
Song aSong;
sin >> aSong.title >> aSong.artist >> aSong.genre;
songs.push_back(aSong);
}
for(int i = 0; i < songs.size(); i++)
cout << "\"" << songs[i].title << "\" by " << songs[i].artist << " ("
<< songs[i].genre << ")" << endl;
return 0;
}
I'm working on a code that reads in a C++ source file and converts all ‘<’ symbols to “<” and all ‘>’ symbols to “>”. I wrote out the main method and everything compiled nicely but now that I'm actually writing out my convert function at the top of the program, I'm stuck in an infinite loop and I'm hitting a wall on what the culprit is. Could someone help me out?
I included the whole program in case the problem lies in my I/O coding but I surrounded the function with slashes. Hopefully I won't get flamed.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
//FUNCTION GOES THROUGH EACH CHARACTER OF FILE
//AND CONVERTS ALL < & > TO < or > RESPECTIVELY
//////////////THIS IS THE FUNCTION IN QUESTION//////////
void convert (ifstream& inStream, ofstream& outStream){
cout << "start" << endl;
char x;
inStream.get(x);
while (!inStream.eof()){
if (x == '<')
outStream << "<";
else if (x == '>')
outStream << ">";
else
outStream << x;
}
cout << "end" << endl;
};
///////////////////////////////////////////////////////////////////////////
int main(){
//FILE OBJECTS
ifstream inputStream;
ofstream outputStream;
string fileName;
//string outFile;
//USER PROMPT FOR NAME OF FILE
cout << "Please enter the name of the file to be converted: " << endl;
cin >> fileName;
//outFile = fileName + ".html";
//ASSOCIATES FILE OBJECTS WITH FILES
inputStream.open(fileName.c_str());
outputStream.open(fileName + ".html");
//CREATES A CONVERTED OUTPUT WITH <PRE> AT START AND </PRE> AT END
outputStream << " <PRE>" << endl;
convert(inputStream, outputStream);
outputStream << " </PRE>" << endl;
inputStream.close();
outputStream.close();
cout << "Conversion complete." << endl;
return 0;
}
It isn't a good approach to manipulate a file while you're reading it. The right way is, first read the whole file, store the data, manipulate the stored data, and then update the file. Hope this code will help you :)
void convert()
{
int countLines = 0; // To count total lines in file
string *lines; // To store all lines
string temp;
ifstream in;
ofstream out;
// Opening file to count Lines
in.open("filename.txt");
while (!in.eof())
{
getline(in, temp);
countLines++;
}
in.close();
// Allocating Memory
lines = new string[countLines];
// Open it again to stroe data
in.open("filename.txt");
int i = 0;
while (!in.eof())
{
getline(in, lines[i]);
// To check if there is '<' symbol in the following line
for (int j = 0; lines[i][j] != '\0'; j++)
{
// Checking the conditon
if (lines[i][j] == '<')
lines[i][j] = '>';
}
i++;
}
in.close();
// Now mainuplating the file
out.open("filename.txt");
for (int i = 0; i < countLines; i++)
{
out << lines[i];
if (i < countLines - 1)
out << endl;
}
out.close();
}
Where I am stuck at is the EncryptString function. The EncryptFile function will take a .txt file and convert the .txt to a C string equivalent, then pass that into the EncrpytString function. When I pass it in, the Substitution function will do its work with the cipher string and encrypt the individual characters, then spit that back out into a new string called encrypted_string. However, I cannot get this function to accept the argument passed into it. Any guidance?
This is where the program currently is:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
char substitution_cipher(string cipher_key, char char_to_encrypt);
char reverse_substitution_cipher(string cipher_key, char char_to_encrypt);
string EncryptString(string &cipher_key, string string_to_be_encrypted);
string DecryptString(string &cipher_key, string string_to_be_decrypted);
void RotateCipherKey(string &cipher_key);
void DisplayFile(string filename);
void EncryptFile(string cipher_key, string filename_from, string filename_to);
void DecryptFile(string cipher_key, string filename_from, string filename_to);
int main()
{
string cipher_key = "qwertyuiopasdfghjklzxcvbnm";
EncryptFile(cipher_key, "test.txt", "test-encrypted.txt");
DecryptFile(cipher_key, "test-encrypted.txt", "test-ed.txt");
DisplayFile("test.txt");
DisplayFile("test-encrypted.txt");
DisplayFile("test-ed.txt");
system("PAUSE");
return 0;
}
// Rotate the cipher key. Example: abcdef becames bcdefa
void RotateCipherKey(string &cipher_key)
{
rotate(cipher_key.begin(), cipher_key.begin() + 1, cipher_key.end());
}
// Perform a substitution cipher on a single character
// using the specified cipher key
char SubstitutionCipher(string cipher_key, char char_to_encrypt)
{
for (int iii = 0; iii < cipher_key.length(); iii++)
{
RotateCipherKey(cipher_key);
char_to_encrypt = cipher_key[iii];
}
return char_to_encrypt;
}
// Perform a "reverse" substitution cipher on a single character
// using the specified cipher key
char ReverseSubstitutionCipher(string cipher_key, char char_to_decrypt)
{
for (int iii = 0; iii < cipher_key.length(); iii++)
{
RotateCipherKey(cipher_key);
char_to_decrypt = cipher_key[iii];
}
return char_to_decrypt;
}
// Encrypt String and return it
// You will use the SubstitutionCipher() function to encrypt the
// individual characters
//
// Note: We will call RotateCipherKey() after each time we encrypt
// a character.
string EncryptString(string &cipher_key, string string_to_be_encrypted)
{
char *y = string_to_be_encrypted.c_str();
{
//SubstitutionCipher(cipher_key, string_to_be_encrypted);
}
cout << " " << string_to_be_encrypted;
string encrypted_string = string_to_be_encrypted;
return encrypted_string;
}
// Decrypt String and return it
// You will use the ReverseSubstitutionCipher() function to decrypt the
// individual characters
//
// Note: We will call RotateCipherKey() after each time we encrypt
// a character.
string DecryptString(string &cipher_key, string string_to_be_decrypted)
{
string decrypted_string = string_to_be_decrypted;
return decrypted_string;
}
// Display file specified by the filname parameter
void DisplayFile(string filename)
{
string str;
ifstream infile;
infile.open(filename);
infile >> str;
while (infile)
{
cout << " " << str;
infile >> str;
}
cout << endl;
}
// Encrypt the specified file using the specified cipher key and
// write the output to a different file
// This function is complete
void EncryptFile(string cipher_key, string filename_from, string filename_to)
{
string input;
ifstream infile;
ofstream outfile;
infile.open(filename_from.c_str());
outfile.open(filename_to.c_str());
if (!infile)
{
cout << "Can not open input file " + filename_from << endl;
exit(0);
}
if (!outfile)
{
cout << "Can not open Output file " + filename_to << endl;
exit(0);
}
while (getline(infile, input))
{
outfile << EncryptString(cipher_key, input) << endl;
}
infile.close();
outfile.close();
}
// Decrypt the specified file using the specified cipher key and
// write the output to a different file
// This function is complete
void DecryptFile(string cipher_key, string filename_from, string filename_to)
{
string input;
ifstream infile;
ofstream outfile;
infile.open(filename_from.c_str());
outfile.open(filename_to.c_str());
if (!infile)
{
cout << "Can not open input file " + filename_from << endl;
exit(0);
}
if (!outfile)
{
cout << "Can not open Output file " + filename_to << endl;
exit(0);
}
while (getline(infile, input))
{
outfile << DecryptString(cipher_key, input) << endl;
}
infile.close();
outfile.close();
}
EDIT//
string EncryptString(string &cipher_key, string string_to_be_encrypted)
{
char new_char;
for (int iii = 0; iii < string_to_be_encrypted.length(); iii++)
{
new_char = SubstitutionCipher(cipher_key, string_to_be_encrypted[iii]);
RotateCipherKey(cipher_key);
}
string encrypted_string = string_to_be_encrypted;
cout << " " << encrypted_string;
return encrypted_string;
}
Ok here is new code now with some modifications.
The problem you have is that c_str() returns a pointer to const, const char*, which you can not assign to a char* in the line
char* y=string_to_be_encrypted.c_str(); // cannot assign a `const char*` to `char*`
Use directly the string to perform your work. There is no other way of getting a pointer to non-const char to the data of a std::string.
So what I did was this;
ifstream infile("warehouse.txt"); ffile("updated.txt");
ofstream outfile("updated.txt");
basically what I want to do is read from the inputfile 'warehouse.txt' and store contents in an array and then add this array and an extra array to outputfile 'updated.txt'.
Then I want to use 'updated.txt' as an input file as shown in the code above is this allowed, I basically want to store all the data on updated.txt into one big array i.e combine the two arrays, is this allowed? I tried it and my compiler seemed to screw up and I was reading about using vectors instead but am struggling to understand them. thanks.
here is my overall code what I wanted to do was basically take from an input file the 'fruitname' and its corresponding quantity from an input file. store extra entries in an extraarray and then put both these arrays in an output file as stated above and then use that output as an input file so I can aggreagte the data.
THE PROBLEM:
When I try to store from the updated.txt to array my cout's show that I get random numbers in place of what should be the fruitname and its number.
#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
typedef struct items {
string name;
int quantity;
} items_t;
void fileopenchecker (ifstream &FILE);
int readfromfile (ifstream &FILE, items_t fruit[]);
int extrarray (items_t fruit[]);
void writetooutputfile (ofstream &OFILE, items_t fruit[], int size);
void combinearrays (ifstream &final, items_t overallfruit[], int total);
int main()
{
const int MAX_SIZE = 150;
int Nfruit = 0;
int Nextrafruit = 0;
int total;
std::ifstream infile("warehouse.txt");
std::ofstream outfile("updated.txt");
std::ifstream ffile("updated.txt");
items_t extrafruit[MAX_SIZE], fruit[MAX_SIZE], overallfruit[MAX_SIZE];
fileopenchecker(infile);
Nextrafruit = extrarray(extrafruit);
Nfruit = readfromfile(infile, fruit);
total = Nextrafruit + Nfruit;
infile.close();
writetooutputfile(outfile, fruit, Nfruit);
writetooutputfile(outfile, extrafruit, Nextrafruit);
combinearrays (ffile, overallfruit, total);
ffile.close();
return 0;
}
void combinearrays (ifstream &final, items_t overallfruit[], int total){
int i;
for(i=0; i<total; i++){
final >> overallfruit[i].name >> overallfruit[i].quantity;
cout << overallfruit[i].name << overallfruit[i].quantity << endl;
}
}
void fileopenchecker (ifstream &FILE){
if(!FILE.is_open()){
cout << "Your file was NOT detected!" << endl;
exit(1);
}
else{
cout << "Your file was detected" << endl;
}
}
int readfromfile (ifstream &FILE, items_t fruit[]){
int entries = 0;
while(!FILE.eof()){
FILE >> fruit[entries].name >> fruit[entries].quantity;
cout << fruit[entries].name << fruit[entries].quantity << endl;
entries++;
}
return entries;
}
int extrarray (items_t fruit[]){
int runner=1, exentries =0;
while(runner==1){
cout << "Would you like to add entries to your file? (YES-->1 NO-->0)" << endl;
cin >> runner;
if(runner==0){
break;
}
//take the itemname and quantity and stores it in the array.
cout << "Enter the name of the fruit and its quantity" << endl;
cin >> fruit[exentries].name >> fruit[exentries].quantity;
//debugging:
cout << fruit[exentries].name << fruit[exentries].quantity << endl;
exentries++;
}
return exentries;
}
void writetooutputfile (ofstream &OFILE, items_t fruit[], int size){
int entries = 0;
while(entries < size){
cout << fruit[entries].name << fruit[entries].quantity << endl;
OFILE << fruit[entries].name << fruit[entries].quantity << endl;
entries++;
}
}
"I want to do is read from the inputfile 'warehouse.txt'"
{
std::ifstream ifs("warehouse.txt");
// reading from ifs ...
... "to outputfile 'updated.txt'"
std::ofstream ofs("updated.txt");
// writing to ofs ...
}
... "Then I want to use 'updated.txt' as an input file" ~> create another instance of ifstream:
{
std::ifstream ifs2("updated.txt");
// reading from ifs2 ...
}
Yes, and it's possible to to use just two file streams if you use std::fstream. For example:
#include <fstream>
#include <iostream>
#include <string>
int main(void)
{
std::ifstream infile("a.txt");
// create file for both reading and writing
std::fstream ffile("b.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
// read contents of file a and write to file b
std::string line;
while (std::getline(infile, line))
{
std::cout << line << std::endl;
ffile << line << std::endl;
}
// flush the output to disk
ffile.flush();
// go back to the start of the output file before reading from it
ffile.seekg(0);
// read contents of output file again.
while (std::getline(ffile, line))
{
std::cout << line << std::endl;
}
return 0;
}