I am trying to figure out how to correctly make a File I/O Function in C++, however I can not seem to get it to work properly. I am currently not at the level to use vectors yet.
How would I go about changing this code to make it into a working function?
If anyone could point me in the right direction I would be grateful.
Here is the Prototype:
string obtain_inFileName(void);
The Function Call:
inputFileName = obtain_inFileName();
The Function:
string obtain_inFileName(void)
{
string inFile;
cout<<"Enter the name of the input file: ";
cin >> inFile;
cout << endl;
return (inFile);
}
Well, the closest thing I could consider working for your case would be
string obtain_inFileName (ifstream &inFileName) {
std::string inputFileName;
cout<<"Enter the name of the input file: ";
cin>>inputFileName;
inFileName.open(inputFileName.c_str());
return inputFileName;
}
Not claiming, that this is a good implementation!
Related
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
string name, choice;
int age;
cout << "Enter a name: ";
//Getline will allow to take an entire line as an input and not a char
getline(cin, name);
cout << "Enter choice of meal: ";
getline(cin, choice);
cout << "Enter age: ";
**getline(cin, age);**
cout << "My name is " << name << endl;
return 0;
}
This is my code
The problem is in the bold line can anyone please tell me why the error is coming and the solution for it?
The answer why you code doesn't work is that getline() online allows you to read strings but not integers. Interestingly, there are no facilitien provided for reading other types in the C++ IOStreams library. This is so interesting, because line-based and delimiter-based stream processing, and in particular mixing them, is always a source for problems. Being able to use the approach you tried would be much easier and safer, I would say.
There's a simple solution (untested):
template<typename value_type>
istream&
getline(std::istream& in, value_type& val)
{
std::string line;
if (!getline(in, line)) {
return in;
}
std::istringstream iss(line);
if (!(iss >> val)) {
in.setf(std::ios::failbit);
}
return in;
}
Basically, it reads a line and then converts it to the according target type in two steps.
When you get errors like this, it's time to look up the signature of the function you use. E.g. look at this documentation std::getline. All of the overloads only accept a (template version of) std::basic_string&, there is no version accepting an int. So you need to look for another way of going from a string input an to an integer value. In this case you might want to check the documentation of the <string> header.
This is my first time programming with C++ after taking 3 classes in Java (so, definite beginner here). The homework is prompting me to append to a text file and then to search within the text file for a name (in this case, my name). It was working perfectly then I was trying to get it to show my whole name rather than just my last name, so I tinkered with it. Now I can't figure out why the result is always "Name not found" despite me putting in my name to get the "Name found is: " result. (Also, the homework wanted the "Name not found" added to a different .txt file, so that's why they're named differently. That works just fine.) Thanks so much!
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (){
ifstream inFile("/Users/katelynwalker/Documents/CSC450_CT5_mod5.txt");
ofstream outFile;
outFile.open("/Users/katelynwalker/Documents/CSC450_CT5_mod5.txt", ios::app);//appends instead of overwrites
outFile<<"Katelyn Walker";
cout<<"Name has been added to the file. ";
outFile.close();
string search;
cout<<"Please enter a name: ";
cin>>ws;
cin>>search;
bool isFound = 0;
string name = " ";
while(getline(inFile, name)){
for(int i=0; i<search.size(); i++){
if(name[i]==search[i]){
isFound = 1;
}
else{
isFound = 0;
}
}
if(isFound){
cout<<"Name found is: ";
for(int i=search.size()+1;i<name.size();i++)
cout << name[i];
break;
}
}
if(inFile.eof()&&(!isFound)){
outFile.open("/Users/katelynwalker/Documents/CSC450-not-found_CT5_mod5.txt", ios::app);
outFile<<"Name not found.";
cout<<"Name not found.";
}
inFile.close();
return 0;
}
If you want your name to be written on a single line, you should write a complete line, including a newline:
outFile<<"Katelyn Walker" << std::endl;
And when asking for a name to search for, std::cin >> search wont let you enter spaces. If you don't want spaces, then that is ok, otherwise you should probably use std::getline(std::cin, search);
Unrelated to your question, don't use using namespace std; it is a bad habit.
I am writing a program that is to convert text that a user gives. I have tried this method by itself in a test program and it works perfectly; however when I try to implement it into the larger program, the user cannot give the program an input to store. The relevant code is as follows:
int main()
{
string str = "NULL";
int mappings = 0;
readMappings(mappings);
receiveInput(str);
displayInput(mappings, str);
return 0;
}
void readMappings(int &count)
{
ifstream readMappings; // Creates the function "readMappings"
string filename; // Generates the filename variable to search for mapping document
cout << "Enter the filename of the mapping document: ";
cin >> filename; // User enters filename
readMappings.open(filename); // "readMappings" function opens the given mappings document
while (!readMappings.is_open())
{
cout << "Unsble to open file. Please enter a valid filename: "; // If the user enters an invaled filename, the program will ask again
cin >> filename;
readMappings.open(filename);
}
if (readMappings.good()) // Mapping document is successfully opened
{
readMappings >> count; // Reads first line
}
readMappings.close(); // If everything fails in this function, the document will close
}
void receiveInput(string &input)
{
char correctness;
do {
cout << "\nPlease enter the text you would like to be converted to NATO:\n";
getline(cin, input);
cout << "You are about to convert: \"" << input << "\".\nIs this correct? (Y/N)" << endl;
cin >> correctness;
} while (correctness == 'N' || correctness =='n');
}
I thought it may have been the program waiting for another input from the user so I added a variable I assumed it would already fill, but it did not fix my solution. In my opinion, the problem is in the receiveInput function, but I could be wrong. Thanks in advance for any assistance.
Also, I am using function prototypes with correct reference variables.
I see two problems:
1) You're not checking for an EOF condition, after invoking std::getline().
2) You are mixing together both std::getline and the >> operator. Now, there's actually nothing technically wrong with that, but both std::getline and the >> operator have very nuanced semantics, when it comes to error checking and input consuming, that you need to get 100% right, in order to correctly use them together.
Just replace your usage of the >> operator with std::getline, so you're using std::getline exclusively, and make sure to check for fail() or eof(). You will find plenty of examples of how to correctly check for end of file and failure conditions, with std::getline, here on stackoverflow.com.
I want to write a constant string to a text file. I know it can be done by using put-to operator(<<), but I want to write that constant string in the block of data entered through cin, gets, etc. I need it for my school project. Please be nice and help me out. If the question isn't clear to you, let me know.
cout<<"Enter your name";
gets(name);
cout<<"Enter your roll number";
cin>>rollno;
char string[]="Student of XYZ School";
fout.write((char*)&student,size(student));
Note that char string can't be written with other data entered, but I want it to be written in the file with other data only.
If you have already done #include <iostream>, as you must have, why are you using gets() and write() and C-style strings? It would be much simpler, since this is C++, to use
#include <fstream>
string name;
string rollno;
ofstream outfile;
cout << "Enter your name";
cin >> name;
cout << "Enter your roll number";
cin >> rollno;
string str = "Student of XYZ School";
student.write(outfile);
You didn't say what type "student" is. In the example above, I assume that it is its own class. If it is, then you can define a member function for it
Student::write(ofstream &outfile) {
outfile << "blah blah blah";
// etc.
}
Whatever you do, DO NOT keep gets() in your program: it leaves your program open to a buffer overflow attack. If you can use cout, you can use cin.
Code:
#include<iostream.h>
#include<fstream.h>
#include<string.h>
int n = 0, flag = 0,i;
struct bac
{
char name[10];
char amt[5];
} s;
void main()
{
ofstream f("C:\\TC\\1.dat");
for(i=0;i<10;i++)
{
cout << "\nenter the details ";
cin >> s.name >> s.amt;
f.write((char *)&s, sizeof(bac));
}
}
sometimes the code works fine
but at the other times , when i look at the output file,it is empty , the problem has come up many times , and i ant to know whether there is a precaution regarding loops with file handling
for eg. in other program
.....
while(ch!=4)
{
cout << "\nBANK MANAGEMENT SYSTEM \n";
cout << "enter choice ";
cout << "\n1.add\n2.search\n3.delete and overwrite ";
cin >> ch;
if (ch == 1)
{
cout << "\nenter the details ";
cin >> s.name >> s.amt;
f.write((char *)&s, sizeof(bac));
}
.....
the file is empty
I guess you may have used a very old compiler older than gcc 4.5.3.
I tried your code and it has no problem.
#include <iostream> //use header file without using deprecated iostream.h
#include <fstream> //same reason as above
#include <string>
using namespace std;
int n = 0, flag = 0,i;
struct bac
{
char name[10];
char amt[5];
} s;
int main() //usually main returns int. void was kind of old now
{
ofstream f("test.txt");
for(i=0;i<10;i++)
{
cout << "\nenter the details ";
cin >> s.name >> s.amt;
f.write((char *)&s, sizeof(bac));
}
f.flush();
f.close();
return 0;
}
I compiled the code in gcc 4.5.3 and ran it. the file has all the stuff I entered.
However, it will be better to use the << operator when you use file i/o stream to write to file.
You can find more information about and from top of this link:
http://members.gamedev.net/sicrane/articles/iostream.html
Another point, wen you have done writing to a file, remember to flush and close the file handle, otherwise, sometimes it will cause some annoying problems.
The code doesn't seem very C++-like to me...
To answer the last question, there aren't any gotchas about fstreams in loops specifically, no.
I suggest first trying to do f.write with the members name and amt themselves—compilers might add padding between name and amt, creating unwanted garbage output.
Are you sure you have write permission to the filepath all the time? Try opening a local file, as in the path being simply "1.dat".
Also try opening the file as f("/* file name */", ofstream::out | ofstream::app). "out" sets it as an output stream, and "app" makes it add to the end of the file. www.cplusplus.com/ofstream details more flags.
since you are using c++, I suggest you use a formal way to use ofstream, in your code, it should be f << s.name << s.amt.
remember, you are using c++, so keep using i/o stream.