I'm trying to learn about the fstream class and I'm having some trouble. I created a couple of txt files, one with a joke and the other with a punchline (joke.txt) and (punchline.txt) just for the sake of reading in and displaying content. I ask the user for the file name and if found it should open it up, clear the flags then read the content in. but I cant even test what it reads in because I'm currently getting errors regarding a deleted function but I don't know what that means
error 1:
"IntelliSense: function "std::basic_ifstream<_Elem, _Traits>::basic_ifstream(const std::basic_ifstream<_Elem, _Traits>::_Myt &) [with _Elem=char, _Traits=std::char_traits<char>]" (declared at line 818 of "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\fstream") cannot be referenced -- it is a deleted function
the second error is the exact same but for the 2nd function (displayLastLine())
and error 3:
Error 1 error C2280: 'std::basic_ifstream<char,std::char_traits<char>>::basic_ifstream(const std::basic_ifstream<char,std::char_traits<char>> &)' : attempting to reference a deleted function
and here's my code:
#include "stdafx.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
void displayAllLines(ifstream joke);
void displayLastLine(ifstream punchline);
int main()
{
string fileName1, fileName2;
ifstream jokeFile, punchlineFile;
// Desribe the assigned project to the User
cout << "This program will print a joke and its punch line.\n\n";
cout << "Enter the name of the joke file (ex. joke.txt): ";
cin >> fileName1;
jokeFile.open(fileName1.data());
if (!jokeFile)
{
cout << " The file " << fileName1 << " could not be opened." << endl;
}
else
{
cout << "Enter name of punch line file (ex. punchline.txt): ";
cin >> fileName2;
punchlineFile.open(fileName2.data());
if (!punchlineFile)
{
cout << " The file " << fileName2 << " could not be opened." << endl;
jokeFile.close();
}
else
{
cout << endl << endl;
displayAllLines(jokeFile);
displayLastLine(punchlineFile);
cout << endl;
jokeFile.close();
punchlineFile.close();
}
}
// This prevents the Console Window from closing during debug mode
cin.ignore(cin.rdbuf()->in_avail());
cout << "\nPress only the 'Enter' key to exit program: ";
cin.get();
return 0;
}
void displayAllLines(ifstream joke)
{
joke.clear();
joke.seekg(0L, ios::beg);
string jokeString;
getline(joke, jokeString);
while (!joke.fail())
{
cout << jokeString << endl;
}
}
void displayLastLine(ifstream punchline)
{
punchline.clear();
punchline.seekg(0L, ios::end);
string punchString;
getline(punchline, punchString);
while (!punchline.fail())
{
cout << punchString << endl;
}
}
You do call a deleted function, being the copy constructor of the class std::ifstream.
If you take a look at the reference you notice, that the copy constructor is not allowed.
so instead of using:
void displayAllLines(ifstream joke);
void displayLastLine(ifstream punchline);
you should work with calls by reference:
void displayAllLines(ifstream& joke);
void displayLastLine(ifstream& punchline);
Using a reference will behave just like calling the method with a copy, but in fact you are operating on the original object instead of a new copy-constructed object. Keep that in mind for further use of the call by reference.
Related
I have a class where I store a filename that a user has provided:
string EMNfn; // IDF file EMN name
// IDF file EMN name
void CcaAna::put_EMNfn(string s)
{
CcaAna::EMNfn = s;
}
string CcaAna::get_EMNfn()
{
return EMNfn;
}
However, when I try to open the file, and I know it exists in the current directory that I am using with the following:
femn.open(cCCA.get_EMNfn());
I get a compile error C2664 ...cannot convert parameter 1 from 'class std::basic_string,class std::allocator >' to 'const char *'
When I try using:
femn.open(cCCA.get_EMNfn().c_str());
it compiles but trips my error code:
if(!femn)
{
cout << "Open of Original EMN file failed\n";
cout << "EMN file: " << cCCA.get_EMNfn() << endl;
cout << "Press any key to exit" << endl;
ch = getchar();
return 1;
}
However when I type it in directly everthing works fine:
femn.open("262-003841-7-23.emn");
running out of ideas is there another way to open the stream?
molbdnilo - I think you are on to something (see below)
OK I added the two COUT lines after and I have included the OUTPUT below the code:
cout << "EMN file: " << cCCA.get_EMNfn() << endl;
// THIS WORKS
// femn.open("262-003841-7-23.emn");
femn.open(cCCA.get_EMNfn().c_str());
// femn.open(cCCA.get_EMNfn());
cout << "this works: " << "262-003841-7-23.emn" << endl;
cout << "*****" << cCCA.get_EMNfn() << "*****" << endl;
OUTPUT:
PROCESSING USER INPUT FILE ...
EMN file: "262-003841-7-23.emn"
this works: 262-003841-7-23.emn
*****"262-003841-7-23.emn"*****
Open of Original EMN file failed
EMN file: "262-003841-7-23.emn"
Press any key to exit
What I am seeing is that the stored string has " around it. Is there a C++ way to remove those?
You are not assigning strings correctly!string variables should not be assigned with = operator . Here is a reference for working with strings.
There are lots of ways for doing your task here is one:
#include <string.h>
...
strcpy(CcaAna::EMNfn,s);//instead of CcaAna::EMNfn=s;
maybe this might work,if not check the link and use a correct way to work with strings.
cheers
I am receiving the following debug error when attempting to run the first part of my program:
Debug Error!
Program:
...\user\desktop\PunchLineProgram\Debug\PunchLineProgram.exe
Module:
...\user\desktop\PunchLineProgram\Debug\PunchLineProgram.exe
File:
Run-Time Check Failure #3 - T
(Press Retry to debug the application)
I am attempting to have the user select whether they want to hear a joke, running and if\else statement that will output a message to the user, based on their response. If I comment out these statements, I do not receive the error when attempting to run the program. I know I'm probably missing something simple, as I am a novice. Here is the code that I have so far:
/*Include Section*/
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>
/*Namespace Section*/
using namespace std;
/*Function Prototypes Section*/
void displayAllLines(ifstream &infile);
void displayLastLine(ifstream &infile);
/*Main section: this is the entry point of the program, which controls the flow of execution*/
int main()
{
string file1;
string file2;
ifstream joke;
ifstream punchline;
int decision;
char y;
char n;
cout << "*******************************************************************************" << endl;
cout << setw(48) << "Punchline Program" << endl;
cout << "*******************************************************************************" << endl;
cout << endl;
cout << "Welcome to the Punchline Program!" << endl;
cout << "Are you ready to hear a joke? (y or n): ";
cin >> decision;
if (decision == y)
{
cout << "Great! Let's get started!" << endl;
}
else if (decision == n)
{
cout << "Ah, no sense of humor, I see. Time to make like a tree and leaf (queue rimshot)!" << endl;
}
system("PAUSE");
}
Any help would be greatly appreciated!
When comparing to char you should use '':
char answer
if (answer == 'y') { *//this only checks for LOWER case y*
cout << "You selected Yes" << endl;
}
when comparing to a string use ""
int/float/double... you can just use the variable.
Besides that, your decision variable as int when it should be char, and you don't need char y nor n. (you yourself never even used it in that code)
I'd suggest looking up c++ tutorials, most show and explain the different between char/string, ' and ".
I've had a lot of problems with this code and i've fixed most of them but i dont know whats wrong here.
1>------ Build started: Project: molar mass, Configuration: Debug Win32 ------
1> Source.cpp
1>c:\users\heliz_000\documents\visual studio 2013\projects\molar mass\molar mass\source.cpp(54): error C3867: 'std::basic_ifstream<char,std::char_traits<char>>::close': function call missing argument list; use '&std::basic_ifstream<char,std::char_traits<char>>::close' to create a pointer to member
1>c:\users\heliz_000\documents\visual studio 2013\projects\molar mass\molar mass\source.cpp(55): error C3867: 'std::basic_ofstream<char,std::char_traits<char>>::close': function call missing argument list; use '&std::basic_ofstream<char,std::char_traits<char>>::close' to create a pointer to member
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
That is the build output for visual studio 2013
#include <iostream>
#include <iomanip>
#include <fstream>
#include <Windows.h>
using std::basic_ofstream;//Thought it would help
using namespace std;
using std::basic_ifstream;//Thought it would help
using std::char_traits;//Thought it would help
/**
* Author: Alex M.
* Date: 3/12/2015
* Desc: Calculates the molar
* mass of compounds,
* elements and
* substances.
*/
void nor();
void tut();
void calc();
int i;
double m;
ifstream inFile;//Is this how to do if/ofstream?
ofstream outFile;
int main()
{
char ele;
bool a;
a = true;
if (i<1)
tut();
nor();
while (a = true)
{
cout << "Enter your compound or type 'Help': ";
cin >> ele;
calc();
while (ele != '\n')//This part is unfinished but seems to work
{
}
}
system("pause");
}
void nor()//This is where i think the problem is
{
inFile.open("runs.dat");
outFile.open("runs.dat");
inFile >> i;
i++;
outFile << i;
inFile.close;
outFile.close;
}
void tut()
{
cout << "Enter your equation with each " << endl << "element seperated by a space." << endl;
cout << "Example: HCl -> H Cl" << endl;
cout << "If theres more than one ion of each " << endl << "element per equation, enter that " << endl << "ion as many time as it appears." << endl;
cout << "Example: NaSO4 -> Na S O O O O" << endl;
system("pause");
}
I've already looked all over forums but no one else seems to be having my problem.
I commented all over the code with where i think the problem is.
I'm very new to C so please don't judge my simplistic coding skills.
In the error message where it says:
source.cpp(54)
source.cpp(55)
that means those errors are on line 54 and 55 respectively. You'll find that those lines are:
inFile.close;
outFile.close;
You probably meant to call those functions:
inFile.close();
outFile.close();
It's an error to mention the name of a member function in that way if you are not calling the function (and function calls require parentheses).
However, a better design would be to make inFile and outFile be local objects inside the function where you are using them. Then the files will automatically be closed when those objects go out of scope.
This very well could be a syntax error on my part since I am rather new with using multiple files and structs in C++ (in particular, passing structs to functions). Here are the three files:
main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include "common.h"
using namespace std;
void honorStatus(int, student studentList[]);
int main(void)
{
int header;
string filename;
ifstream inputFile;
student studentList[MAX_STUDENTS];
// Get filename from user and try to open file
cout << "Please enter a filename: ";
cin >> filename;
inputFile.open(filename.c_str());
// If file cannot be opened, output error message and close program
if (inputFile.fail())
{
cout << "Input file could not be opened. Please try again." << endl;
return 1;
}
// Get header number from file. If header is larger than max number
// of students, error is output and program is closed
inputFile >> header;
if (header > MAX_STUDENTS)
{
cout << "Number of students has exceeded maximum of " << MAX_STUDENTS
<< ". Please try again." << endl;
return 1;
}
// Read file information (student ID, hours, and GPA) into struct array
for (int i = 0; i < header; i++)
{
inputFile >> studentList[i].ID >> studentList[i].hours >> studentList[i].GPA;
}
// Close the file
inputFile.close();
// Calls function honorStatus
honorStatus(header, studentList);
return 0;
}
functs.cpp:
#include <iostream>
#include "common.h"
using namespace std;
// Function to determine classification and honors society eligibility requirements
// of each student, outputting this information and the number of students eligible
void honorStatus(int fheader, student fstudentList[])
{
int cnt = 0;
for (int i = 0; i < fheader; i++)
{
if (fstudentList[i].hours < 30)
{
cout << "Student #" << fstudentList[i].ID << " is a freshman with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
else if (fstudentList[i].hours > 29 && fstudentList[i].hours < 60)
{
if (fstudentList[i].GPA >= 3.75)
{
cout << "Student #" << fstudentList[i].ID << " is a sophomore with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a sophomore with GPA of "
<< fstudentList[i].GPA << ". Not Eligible." << endl;
}
}
else if (fstudentList[i].hours > 59 && fstudentList[i].hours < 90)
{
if (fstudentList[i].GPA >= 3.5)
{
cout << "Student #" << fstudentList[i].ID << " is a junior with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a junior with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
}
else
{
if (fstudentList[i].GPA >= 3.25)
{
cout << "Student #" << fstudentList[i].ID << " is a senior with GPA of "
<< fstudentList[i].GPA << ". Eligible." << endl;
cnt++;
}
else
{
cout << "Student #" << fstudentList[i].ID << " is a senior with GPA of "
<< fstudentList[i].GPA << ". Not eligible." << endl;
}
}
}
cout << "\nTotal number of students eligible for the Honor Society is " << cnt << "." << endl;
}
common.h:
// Maximum number of students allowed
const int MAX_STUDENTS = 10;
// Struct for student info
struct student
{
int ID;
int hours;
float GPA;
};
When using TextPad/G++, I get the following error:
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccxq9DAh.o:p7b.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccLa96oD.o:test.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o: bad reloc address 0x1b in section `.text$_ZNSt11char_traitsIcE7compareEPKcS2_j[__ZNSt11char_traitsIcE7compareEPKcS2_j]'
collect2: error: ld returned 1 exit status
When using an online C++ compiler (CompileOnline), I get:
/tmp/ccIMwHEt.o: In function `main':
main.cpp:(.text+0x1cf): undefined reference to `honorStatus(int, student*)'
collect2: error: ld returned 1 exit status
I wasn't able to find a guide on how to set up TextPad/G++ to compile and link multiple files, but my instructor gave a short set of instructions that I followed. Here is how it's set up:
So this could a two-parter question (how do I set up TextPad to correctly compile/link files? why is my honorStatus() function undefined in main.cpp?) or it could just be that my syntax is wrong. I'm honestly not sure. Sorry if this is a bit long; I wanted to include as much detail as possible. Any help is greatly appreciated.
The problem is that you are compiling "*.cpp" all together. Given this
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccxq9DAh.o:p7b.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccLa96oD.o:test.cpp:(.text+0x0): multiple definition of `main'
/cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o:p5.cpp:(.text+0x0): first defined here
/usr/lib/gcc/i686-pc-cygwin/4.8.2/../../../../i686-pc-cygwin/bin/ld: /cygdrive/c/Users/Korina/AppData/Local/Temp/ccmtzOP2.o: bad reloc address 0x1b in section `.text$_ZNSt11char_traitsIcE7compareEPKcS2_j[__ZNSt11char_traitsIcE7compareEPKcS2_j]'
collect2: error: ld returned 1 exit status
we can see that the the compiler has been trying to combine p5.cpp, p7b.cpp and test.cpp into one executable (possibly other .cpp files too).
You need to actually tell the compiler exactly which files you want to build together to one program. E.g.
g++ main.cpp functs.cpp -o main.exe
(I would suggest also adding -Wall -Wextra -Werror to the compile line, as that allows the compiler to detect the small mistakes that aren't strictly errors, but where you probably got something wrong)
From the linker output you can see that main function is found in these files: p7b.cpp, p5.cpp and test.cpp. As there's no main.cpp file listed in the linker output, I guess that current directory is setup to be where p7b.cpp and other files are located.
Try to change Initial Folder to be where your main.cpp file is set (something like /cygdrive/c/Users/Korina/programming/). Also, remove all unrelevant files from that directory, as you're compiling all cpp files.
The error message is clear enough. Your project contains the following files
p7b.cpp, p5.cpp, test.cpp
where in each file there is defined function main. Put a place in order with your project files.
As for the error message when you use the inline compiler then it seems module functs.cpp is not included in the project. So the compiler does not see the function definition.
Im working on my homework assignment and I stuck because in the assignment we have to ask the user to enter a file name but also to type in either wc cc or lc (word count, character count, and line count of a file. For example, wc filename.txt. Im suppose to check the file to see if its valid or not which i understand and I know how to compare the users input to determine the different kind of function to run, but I dont understand how you could do it together. Any ideas? This is what I have so far.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string line;
string file;
ifstream input; //input file stream
int i;
cout << "Enter a file name" << endl;
while(true){
cout << ">" ;
getline(cin,file);
input.open(file.c_str());
if (input.fail()) {
cerr << "ERROR: Failed to open file " << file << endl;
input.clear();
}
else {
i = 0;
while (getline(input, line))
if(line == "wc"){
cout << "The word count is: " << endl;
}
else if(line == "cc"){
cout << "The character count is: " << endl;
}
else if(line == "lc"){
cout << "The line count is: " << endl;
}
else if(line == "exit"){
return 0;
}
else{
cout << "----NOTE----" << endl;
cout << "Available Commands: " << endl;
cout <<"lc \"filename\"" << endl;
cout <<"cc \"filename\"" << endl;
cout <<"wc \"filename\"" << endl;
cout <<"exit" << endl;
}
}
}
return 0;
}
void wordCount(){
//TBD
}
void characterCount(){
//TBD
}
void lineCount(){
//TBD
}
You have to find the space between the command and the file name in the users input and then split the string where you find the space. Something like this
cout << "Enter a command\n";
string line;
getline(cin, line);
// get the position of the space as an index
size_t space_pos = line.find(' ');
if (space_pos == string::npos)
{
// user didn't enter a space, so error message and exit
cout << "illegal command\n";
exit(1);
}
// split the string at the first space
string cmd = line.substr(0, space_pos);
string file_name = line.substr(space_pos + 1);
This is untested code.
You could do better than this, for instance this would not work if the user entered two spaces between the command and the file name. But this kind of work rapidly gets very tedious. As this is an assignment I would be tempted to move on to more interesting things. You can always come back and improve things later if you have the time.
I think you are asking how to validate multiple arguments: the command and the file.
A simple strategy is to have function like the following:
#include <fstream> // Note: this is for ifstream below
bool argumentsInvalid(const string& command, const string & command) {
// Validate the command
// Note: Not ideal, just being short for demo
if("wc" != command && "cc" != command && "lc" != command) {
std::cout << "Invalid command" << std::endl;
return false;
}
// Validate the file
// Note: This is a cheat that uses the fact that if its valid, its open.
std::ifstream fileToRead(filename);
if(!fileToRead) {
std::cout << "Invalid file: \"" << filename << "\"" << std::endl;
return false;
}
return true;
// Note: This does rely on the ifstream destructor closing the file and would mean
// opening the file twice. Simple to show here, but not ideal real code.
}
If you want to evaluate ALL arguments before returning an error, insert a flag at the top of that function, like:
// To be set true if there is an error
bool errorFound = false;
and change all of the returns in the conditions to:
errorFound = true;
and the final return to:
return !errorFound;
Usage:
....
if(argumentsInvalid(command, filename)) {
std::cout << "Could not perform command. Skipping..." << std::endl;
// exit or continue or whatever
}
// Now do your work
Note: The specific validity tests here are over simplified.