This is the last part of the program I am working on. I want to output a tabular list of songs to cout. And then I want to output a specially formatted list of song information into fout (which will be used as an input file later on).
Printing to cout works great. The problem is that tons of extra character are added when printing to fout.
Any ideas?
Here's the code:
void Playlist::printFile(ofstream &fout, LinkedList<Playlist> &allPlaylists, LinkedList<Songs*> &library)
{
fout.open("music.txt");
if(fout.fail())
{
cout << "Output file failed. Information was not saved." << endl << endl;
}
else
{
if(library.size() > 0)
fout << "LIBRARY" << endl;
for(int i = 0; i < library.size(); i++) // For Loop - "Incremrenting i"-Loop to go through library and print song information.
{
fout << library.at(i)->getSongName() << endl; // Prints song name.
fout << library.at(i)->getArtistName() << endl; // Prints artist name.
fout << library.at(i)->getAlbumName() << endl; // Prints album name.
fout << library.at(i)->getPlayTime() << " " << library.at(i)->getYear() << " ";
fout << library.at(i)->getStarRating() << " " << library.at(i)->getSongGenre() << endl;
}
if(allPlaylists.size() <= 0)
fout << endl;
else if(allPlaylists.size() > 0)
{
int j;
for(j = 0; j < allPlaylists.size(); j++) // Loops through all playlists.
{
fout << "xxxxx" << endl;
fout << allPlaylists.at(j).getPlaylistName() << endl;
for(int i = 0; i < allPlaylists.at(j).listSongs.size(); i++)
{
fout << allPlaylists.at(j).listSongs.at(i)->getSongName();
fout << endl;
fout << allPlaylists.at(j).listSongs.at(i)->getArtistName();
fout << endl;
}
}
fout << endl;
}
}
}
Here's a sample of the output to music.txt (fout):
LIBRARY
sadljkhfds
dfgkjh
dfkgh
3 3333 3 Rap
sdlkhs
kjshdfkh
sdkjfhsdf
3 33333 3 Rap
xxxxx
PayröÈöè÷÷(÷H÷h÷÷¨÷È÷èøø(øHøhøø¨øÈøèùù(ùHùhùù¨ùÈùèúú(úHúhúú¨úÈúèûû(ûHûhûû¨ûÈûèüü(üHühüü¨üÈüèýý(ýHýhý
! sdkjfhsdf!õüöýÄõ¼5!
sadljkhfds!þõÜö|ö\
þx þ þÈ þð ÿ ÿ# ÿh ÿ ÿ¸ ÿà 0 X ¨ Ð ø
enter code here
enter code here
Most likely, one of your methods returns an improper char * string (not null terminated).
Edit: actually, not just one: getPlaylistName(), getSongName() and getArtistName().
Related
for(int i = 0; i < arr; i++)
{
cout << left << setw(25);
cout << names[i] << " " << age[i];
cout << setw(25);
cout << fname[i] << endl;
}
Here the arrays names,age and fname contain name, age and father's name, respectively.
Output of my code is:
zeel dev 18r k sanghai
amar singh 25r k sanghai
alex pandit 52s n vardhan
After the agecolumn, I want a gap of another 25 columns. How can I do that?
setw() is not working properly.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have an assignment using a version of Ceasar cipher but it shifts characters in a file based on user input. For instance, if the user enters the shift value as 1, it would change 'a' to 'b'. I've tried typing to the out file and adding the shift value to the characters but it doesnt output anything to the out1 file and I can't figure out the right way to type this so the code does what I want it to do. Any info would help, here's my code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cctype>
using namespace std;
double Percent(double&, double&);
int main()
{
//Declare user variables
int shift;
char ifilename[25], ofilename[25], ch;
ifstream in1;
ofstream out1;
double other = 0, letter, nums = 0;
//Attach files
do {
in1.clear(); //clear status flags
//Prompt user to enter name of input file and amount of shift
cout << "Please enter the name of the input file." << endl;
cout << "Filename: ";
cin >> ifilename;
//Open file name
in1.open(ifilename);
//Error message if no file
if (!in1)
cout << "That is not a valid file. Try again\n";
}
while (!in1);
do {
out1.clear(); //clear status flags
cout << "Please enter the name of the output file." << endl;
cout << "Filename: ";
cin >> ofilename;
out1.open(ofilename);
//Error message if no file
if (!out1)
cout << "That is not a valid file. Try again\n";
}
while (!out1);
//prompt user to enter shift
cout << "Please intput the shift amount: ";
cin >> shift;
cout << "Processing complete" << endl;
double count = 0;
int sum = 0, i = 0;
while (!in1.eof()) // while not end of input file
{
in1.get(ch); // read a character from input file using get()
out1 << ch; //print to output
count++; //count how many characters
i = ch;
if (i > 47 && i < 58) //count number of numbers
nums++;
else if ((i > 31 && i < 48) || (i > 57 && i < 65) || (i > 90 && i < 97) || (i > 122 && i < 127))
other++; // count number of other characters
else if ((i > 64 && i < 91) || (i > 96 && i < 123))
letter++; // count number of letters
// type to output file and shift characters
out1 << ch + shift;
}
//Tell user file input is complete and is now printing statistics
cout << "\nShifted input file Complete. Now printing statistics " << endl;
//Show statistics for file
cout << "\nStatistics for file: " << ifilename << endl;
cout << "------------------------------------------------";
//Show characters in file and stats before shift
cout << "\n\nTotal # of characters in file: " << count << endl;
cout << "Statistics before shift: " << endl;
cout << "\n\nCategory" << setw(30) << "How many in file" << setw(20) << "% of file" << endl;
cout << "----------------------------------------------------------------" << endl;
cout << "Letters" << setw(25) << letter << setw(20) << setprecision(4) << letter / count * 100 << " %" << endl;
cout << "Digits" << setw(26) << nums << setw(20) << setprecision(4) << nums / count * 100 << " %" << endl;
cout << "Other" << setw(27) << other << setw(20) << setprecision(4) << other / count * 100 << " %" << endl;
//Show user stats after shift
cout << "\nStatistics after shift: " << endl;
cout << "\n\nCategory" << setw(30) << "How many in file" << setw(20) << "% of file" << endl;
cout << "----------------------------------------------------------------" << endl;
cout << "Letters" << setw(25) << letter << setw(20) << setprecision(4) << Percent(letter, count) << " %" << endl;
cout << "Digits" << setw(26) << sum << setw(20) << setprecision(4) << nums / count * 100 << " %" << endl;
cout << "Other" << setw(27) << nums << setw(20) << setprecision(4) << other / count * 100 << " %" << endl;
//Close files
out1.close();
in1.close();
return 0;
}
double Percent(double&, double&)
{
double sum, letter, count;
sum = letter / count * 100;
return sum;
}
A simple implementation of the Caesar Cipher is to use a string of valid characters and the remainder operator, %.
char Encrypt_Via_Caesar_Cipher(char letter, unsigned int shift)
{
static const std::string vocabulary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const std::string::size_type position = vocabulary.find(letter);
char c = letter;
if (position != std::string::npos)
{
const std::string::size_type length = vocabulary.length();
c = vocabulary[(position + shift) % length];
}
return c;
}
for(int x = 4999; x >= 0; x--)
{
outFile <<left<<setw(9)<< arr[x].Rank << "\t";
outFile <<setw(6)<< arr[x].id << "\t";
outFile << setw(37) << arr[x].names << "\t";
outFile << arr[x].pointSum << "\r\n";
}
for(int x = 4999; x >= 0; x--)
{
outFile <<left<<setw(9)<< arr[x].Rank << "\t";
//outFile <<setw(6)<< arr[x].id << "\t";
outFile << setw(37) << arr[x].names << "\t";
outFile << arr[x].pointSum << "\r\n";
}
The first loop outputs this on all of its lines:
275
160760 lcucujuyeikljuikg HighSchool 11
The second one outputs this:
275 lcucujuyeikljuikg HighSchool 11
For some reason getting rid of that one line somehow gets rid of a new line character. What could be causing this? I am at a complete loss here. I get the same results from cout as well
Im having an issue with the last section of coding on here. The // Copy files from infile to outfile. The program transfers my infile which is simply a an 8 digit number , 20392207,splits it up into individual digits using the .at method; and is supposed to save that output to an outfile. I cant figure out how to save the output to the outfile. Any advice?
infile looks as follows
20392207
program output looks like this
The input number :20392207
The number 1:2
The number 2:0
The number 3:3
The number 4:9
The number 5:2
The number 6:2
The number 7:0
The number 8:7
outfile is supposed to look like the program out put, but instead just looks like an exact copy of the infile.
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
int main()
{
string ifilename, ofilename, line, line2;
ifstream inFile, checkOutFile;
ofstream outFile;
char response;
int i;
// Input file
cout << "Please enter the name of the file you wish to open : ";
cin >> ifilename;
inFile.open(ifilename.c_str());
if (inFile.fail())
{
cout << "The file " << ifilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Output file
cout << "Please enter the name of the file you wish to write : ";
cin >> ofilename;
checkOutFile.open(ofilename.c_str());
if (!checkOutFile.fail())
{
cout << "A file " << ofilename << " exists.\nDo you want to continue and overwrite it? (y/n) : ";
cin >> response;
if (tolower(response) == 'n')
{
cout << "The existing file will not be overwritten. " << endl;
exit(1);
}
}
outFile.open(ofilename.c_str());
if (outFile.fail())
{
cout << "The file " << ofilename << " was not successfully opened." << endl;
cout << "Please check the path and name of the file. " << endl;
exit(1);
}
else
{
cout << "The file is successfully opened." << endl;
}
// Copy file contents from inFile to outFile
while (getline(inFile, line))
{
cout << "The input number :" << line << endl;
for (i = 0; i < 8; i++)
{
cout << "The number " << i + 1 << ":";
cout << line.at(i);
cout << endl;
}
outFile << line << endl;
}
// Close files
inFile.close();
outFile.close();
} // main
Here we can see that outFile is only written to outside of the while loop:
while (getline(inFile, line))
{
cout << "The input number :" << line << endl;
for (i = 0; i < 8; i++)
{
cout << "The number " << i + 1 << ":";
cout << line.at(i);
cout << endl;
}
}
outFile << line << endl;
It has no chance of containing the same output as the console
Solution: Write inside the loop the same stuff that was written to the console:
while (getline(inFile, line))
{
cout << "The input number :" << line << endl;
outFile << "The input number :" << line << endl;
blah blah blah
}
But this looks like crap and a function makes like a better solution by eliminating duplication and upping re-usability.
void output(std::ostream & out,
const std::string & line)
{
out << "The input number :" << line << endl;
for (int i = 0; i < 8; i++)
{
out << "The number " << i + 1 << ":";
out << line.at(i);
out << endl;
}
}
and called:
while (getline(inFile, line))
{
output(cout, line);
output(outFile, line);
}
You need to write to outFile inside the while(getline(inFile, line)) loop.
[edit] see user4581301's answer for a more thorough treatment.
I have a very simple program where I ask the user if they want to print to screen or a file. Rather than create two sets of output sections, I thought I could switch a stream to either cout or an ofstream and then output to that stream. However, I'm getting screen output no matter what.
ostream &out = cout;
do
{
cout << "Write to file (f) or screen (s)?";
cin >> yes_or_no;
} while (yes_or_no != 'f' && yes_or_no !='s');
if (yes_or_no=='f')
{
ofstream out;
out.open("Report.txt");
cout << "Writing report to Report.txt" << endl;
system("pause");
}
out << "Day: Current Value ROI" << endl;
out << "------------------------------------------" << endl;
out << setw(5) << 0;
out << "$" << setw(20) << setprecision (2) << fixed << initial_value;
out << setw(12) << "1.00" << endl;
for (int day = 1 ; day < number_of_days ; day++)
{
current_value = generateNextStockValue(current_value, volatility, trend);
out << setw(5) << day;
out << setw(20) << setprecision (2) << fixed << current_value;
out << setw(12) << setprecision (2) << fixed << current_value / initial_value;
out << endl;
}
You could put all the writing logic inside a function, and let the caller decide which output stream to write to:
void do_the_stuff(std::ostream& os)
{
// write to os
os << "blah blah" ....
}
then
if (yes_or_no=='f')
{
ofstream out("Report.txt");
do_the_stuff(out);
} else {
do_the_stuff(std::cout);
}