In my code:
int newEntry()
{
string input;
Client person;
char response = 'y';
//create file object and open file
fstream customer("customer.dat", ios::out | ios::app);
if (!customer)
{
cout << "Error opening file. Program aborting." << endl;
return 0;
}
do
{
cout << "Enter person information:" << endl << endl;
cout << "Name: " << endl;
getline(cin, input);
strcpy(person.name, input.c_str());
cout << endl << "Street Adress (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin, input);
strcpy(person.address1, input.c_str());
cout << endl << "City, State, Zipcode: " << endl;
cin >> person.address2;
getline(cin, input);
strcpy(person.address2, input.c_str());
cout << endl << "Phone: " << endl;
cin >> person.phone;
getline(cin, input);
strcpy(person.phone, input.c_str());
cout << endl << "Account Balance: " << endl;
cin >> person.acctBal;
//input validation to ensure a non neg number
cin.ignore();
cout << endl << "Last Payment: " << endl;
cin >> person.lastPay;
//input validation to ensure a non neg number
customer.write(reinterpret_cast<char *>(&person),
sizeof(person));
cout << endl << "Do you want to enter another record? (Enter Y for Yes, N
for No) " << endl;
cin >> response;
cout << "_______________________________________________" << endl << endl;
if (toupper(response) == 'Y')
{
cin.ignore();
}
} while (toupper(response) == 'Y');
customer.close();
return 1;
}
It seems as though the block:
cout << endl << "Street Address (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin,input);
strcpy(person.address1, input.c_str());
and its neighboring address 2 prompt (identical) are causing bad output to the file when
customer.write(reinterpret_cast<char *>(&person),sizeof(person));
is used to write to the file. The output is missing the very first word . For example if "211 Harvey Road" was entered, 211 would be cut off. Another example, if "Harvey Road" was entered, than it seems as though "harvey" is cut off. When (in another function) the file is read, the structure of arrays is missing the beginning, as well as the file.
On top of that, in the textfile, this is the data being written to it:
Frank Palmasani ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ Harvey Road ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ Haven, Alabama ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ 504617772 ÌÌÌÌ èŽ# èŽ#James Harris ni ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ Street AVEN ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ China. Alabama ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ 546457474 ÌÌÌÌ ð? ð?
As you can see, where the Ì are popping up is where the file and program are somehow losing the first word. I have tried everything I can think of to fix this problem, hopefully someobody else has ran into a similar problem.
I have tried changing methods of saving the data held in the structure of arrays to the file, but found that I couldn't read from the file in one large grouping. In my text book, the method I used to read out to the file is used so that is the one I believe I should follow.
However, I am considering writing each one separately on each line, and saving it precisely in the order so that I can read it in the same order, saving it to a structure of vectors. Again, I'd I would like to avoid that but would love to hear your opinion on the matter whether if you are able to help me here or not.
In case you needed it, here is my structure:
const int NAME_SIZE = 51, ADDR_SIZE = 51, PHONE_SIZE = 14;
struct Client
{
char name[NAME_SIZE];
char address1[ADDR_SIZE];
char address2[ADDR_SIZE];
char phone[PHONE_SIZE];
double acctBal;
double lastPay;
};
Your output file looks like that because you are doing a raw dump of the Client struct. So there will be 51 bytes written for name, 51 for address1, etc. Regardless of string length.
You need to properly write each field individually.
customer << input.name << endl;
customer << input.address1 << endl;
etc.....
cout << endl << "Street Adress (And Apartment Number):" << endl;
cin >> person.address1;
getline(cin, input);
strcpy(person.address1, input.c_str());
You're getting the first token, in the case you mentioned 211 and putting it in address1, then getting the rest of the line and replacing what was in address1 with it. That's where your 211 went.
You should open the file in binary mode if your intent is to write/read entire structures as a binary blob like this. If you want to store the data as text use std::string, avoid the strcpy mess, and write/read each member individually on their own ines.
Related
answer = "George";
cout << "\t\t\t\t\t Who was the first President of United States?" << endl;
cout << "";
cout << "";
cout << "Congrats " << player1_name << " (Player1). Now, type in your answer:";
cin >> player1_answer;
if (player1_answer == answer){
cout << "check";
}else{
cout << "x";
}
This is my code. But when the user inputted the answer as exactly as what was written in the answer variable, it outputs 'x'. But if the user inputted the same answer excluding the space between "George" and "Washington", it outputs 'check'. What should I do so that the program will accept the space in the answer inputted by the user?
I tried searching the web but I can't understand a thing. So please help me
You can simply use getline instead of cin. cin reads the user input up until the first whitespace character (most commonly newlines or spaces), but getline will read user input until they hit enter. Because of this, if you want to get user input that includes spaces, you should use getline (or something similar) instead of cin.
Instead of
cin >> player1_answer;
you should use
getline(cin, player1_answer);
By using getline, the full user input ("George Washington") get assigned to the variable player1_answer. With cin, only "George" was being used, because it stopped listening for input after the first space.
Here is a full, working code example:
#include <iostream>
using namespace std;
string answer = "George Washington";
string player1_name = "Steve";
string player1_answer;
cout << "\t\t\t\t\t Who was the first President of United States?" << endl;
cout << "";
cout << "";
cout << "Congrats " << player1_name << " (Player1). Now, type in your answer:";
getline(cin, player1_answer); //Enter "George Washington"
if (player1_answer == answer){
cout << "check";
}else{
cout << "x";
}
//"check"
return -1;
Hello I am creating a program that has the user enter a ssn based on a text file and then it reports that information and calculates the mean of a grade.
I am struggling to understand how I can allow the user to directly add data to the text file based on a series of questions.
The text file uses this format.
111-11-1111
John Doe
G
85 90 87 95 89
111-11-1112
Jane Doe
P
78 65 71 74 75
111-11-1113
John Smith
G
45.0 43.0 44.0 45.0 43.0
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
int main() {
int selection = 0;
char goagain;
bool again = true;
ifstream fin;
ofstream fout;
string SSNFind, SSN, name, attendance, trash;
int Lab, PA, Quiz, Midterm, Final;
;
cout << "********** GRADE SYSTEM ************" << endl << endl;
while (again) {
while (selection > 4 || selection < 1)
{
cout << setw(30) << left << "1. Add a record" << endl;
cout << setw(30) << left << "2. Find a person by SSN" << endl;
cout << setw(30) << left << "3. Display all records" << endl;
cout << setw(30) << left << "4. Exit " << endl;
cout << "MAKE A CHOICE" << endl;
cin >> selection;
}
switch (selection)
{
case 1:
break;
case 2:
fin.open("data.txt", ios::in);
//check
cout << "what SSN do you want to find? ";
cin >> SSNFind;
getline(fin, SSN);
while (!fin.eof())
{
getline(fin, name);
getline(fin, attendance);
fin >> Lab >> PA >> Quiz >> Midterm >> Final;
getline(fin, trash);
if (SSN == SSNFind)
{
cout << left << setw(12) << SSN << setw(25) << name << setw(3) << attendance << Final;
}
getline(fin, SSN);
}
fin.close();
break;
case 3:
cout << "Display" << endl;
break;
default:
cout << "exit";
exit(1);
break;
}
cout << "again?(Y or N)";
cin >> goagain;
if (toupper(goagain) == 'Y')
{
again = true;
selection = 0;
}
else
{
again = false;
exit(1);
}
}
}
I'm not 100% sure I understand your problem, but if you want to append data to a file, you should open in in "append" mode, instead of "in"/"out" mode:
fin.open("data.txt", ios::in);
to:
fin.open("data.txt", std::ios::app);
see details:
https://en.cppreference.com/w/cpp/io/basic_fstream/open
I wanted to post this as a comment because I'm not sure if this is really an answer.
If you want to append to the end of the file you would open the file in append mode as suggested by Thomas Matthews above.
If you want to insert into the middle or beginning of the file you could open the file in input/output mode and find where you want to insert data at. Then you would buffer from there to the end of the file, return to where you want to insert into file and then write what you need to add then write the buffer back into file. (input/output mode overwrites data in file). If the file is large you should buffer only a portion of the file at a time, two buffers may help here.
Reading from here and looking at the other stream based classes to the left of linked page; I see no way to directly insert into the middle of file without buffering.
I have this programming project on file i/o in c++. I have read up about it but don't understand much of it yet. Regardless, I made this program that allows the user to store the profile ( name, ethnicity etc. ) of a person onto a text file and be able to retrieve it. However, i am encountering some issues with how it works.
what it does is at the start it asks the user if they want to view the previously created file or create a new one.
if view a previous file was selected the program will then spit out the whole text file
if creating a new file is selected the program will ask for the number of people then proceed to ask for the name, age, gender, species, ethnicity and mode of transport for the allocated number of people and save it onto the text file.
the problem is i am unable to set the number of people as the program ignores the variable (i.e. i set 5 people and it ignores it)
and the program ignores the first name entered by skipping it.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char names[100];
char age[100];
char gender[100];
char species[100];
char ethnicity[100];
char transport[100];
char decision[0];
string getcontent;
cout << "Would You Like to Open The Previous File Or View Your Profiles?" << endl << endl;
cout << "Enter 1 For Previous File" << endl;
cout << "Enter Anything Else To View Your Profiles: " << decision;
cin.getline(decision,5);
cout << endl << "==============================================================" << endl;
if(decision[0] == '1')
{
ifstream infile;
infile.open("File of names.txt");
while(! infile.eof())//eof stand for end of file
{
getline(infile, getcontent); //getline requires a string
cout << getcontent << endl;
}
cout << "==============================================================" << endl;
infile.close(); //closes the opened file - good practice
}
else
{
int a;
cout << "Enter The Amount Of People You Would Like To Store: ";
cin >> a;
ofstream namefile;
namefile.open("File of names.txt");
cout << "Please Set Your Team Profile." << endl;
for (int i=0; i<a; i++)
{
cout << "==============================================================" << endl;
cout << "Enter Student " << i+1 << " : ";
cin.getline(names,100);
namefile << names << endl;
cout << "==============================================================" << endl;
cout << "Enter The Age: ";
cin.getline(age,100);
namefile << age << endl;
cout << "Enter The Gender: ";
cin.getline(gender,100);
namefile << gender << endl;
cout << "Enter The Species: ";
cin.getline(species,100);
namefile << species << endl;
cout << "Enter The Ethnicity: ";
cin.getline(ethnicity,100);
namefile << ethnicity << endl;
cout << "What Is The Mode Of Transport: ";
cin.getline(transport,100);
namefile << transport << endl << endl;
}
namefile.close();
}
}
This is the output of the file:
Would You Like to Open The Previous File Or View Your Profiles?
Enter 1 For Previous File
Enter Anything Else To View Your Profiles: g
==============================================================
Enter The Amount Of People You Would Like To Store: 5
Please Set Your Team Profile.
==============================================================
Enter Student 1:==============================================================
Enter The Age:
This is the expected output:
Would You Like to Open The Previous File Or View Your Profiles?
Enter 1 For Previous File
Enter Anything Else To View Your Profiles: g
==============================================================
Enter The Amount Of People You Would Like To Store: 5
Please Set Your Team Profile.
==============================================================
Enter Student 1: John
==============================================================
Enter The Age:
The problem is that for example when you input a value like:
string str;
cin>>str;
and you insert "John", you are not assign "John" to str, but "John\n" (note \n, that is created when you type enter on the keyboard). A possible solution to ignore it, is using cin.ignore();
However probably your homework is to make a very simple "database", so you will have to memorize the data in an orderly way, then i will suggest you to use "struct" (it's easy, not difficult for beginners).
I tried running my code. no error but there's is no output in the data file itself when I reinterpret cast.
May I know what is missing?
Thank you.
I need the dat file to take in all the input provided by the cin
Use securing confined his shutters. Delightful as he it acceptance an solicitude discretion reasonably. Carriage we husbands advanced an perceive greatest. Totally dearest expense on demesne ye he. Curiosity excellent commanded in me. Unpleasing impression themselves to at assistance acceptance my or. On consider laughter civility offended oh.
Spot of come to ever hand as lady meet on. Delicate contempt received two yet advanced. Gentleman as belonging he commanded believing dejection in by. On no am winding chicken so behaved. Its preserved sex enjoyment new way behaviour. Him yet devonshire celebrated especially. Unfeeling one provision are smallness resembled repulsive.
In alteration insipidity impression by travelling reasonable up motionless. Of regard warmth by unable sudden garden ladies. No kept hung am size spot no. Likewise led and dissuade rejoiced welcomed husbands boy. Do listening on he suspected resembled. Water would still if to. Position boy required law moderate was may.
struct task
{
char title[MAX]; // Eg. Assignment ,Exam,Test
int weight; // Weightage of the task
int fullmark; // Upon
float mark; // Obtained marks
};
struct Subject
{
char subCode[MAX]; // CSCI103 MATH STAT
char subTitle[MAX]; // Full title of subject
int noTask; // No. of task for following struct
task Task[MAX]; // Array of tasks
float finalMark; // Final overall mark for subject
Grade finalGrade; // Grade for subject
};
int main()
{
fstream afile;
afile.open ("test.dat", ios::in | ios::binary | ios::app);
int totalWeight = 0;
Subject S;
if(!afile)
{
cout << "Error opening file,please check" << endl;
exit(1);
}
cout << "------------------" << endl
<< "Subject adding system" << endl
<< "------------------" << endl << endl;
cout << "Subject Code: ";
cin >> S.subCode;
cin.clear();
cin.ignore(100,'\n');
cout << "Subject Name: ";
cin.getline (S.subTitle, MAX);
cout << "No of assessment tasks: ";
cin >> S.noTask;
cin.clear();
cin.ignore(100,'\n');
cout << endl;
// Loop for binary file
for(int i = 1;i<=S.noTask;i++)
{
cout << "Task " << i << " Information" << endl
<< "\t Title: ";
cin >> S.Task[i].title;
cin.clear();
cin.ignore(100,'\n');
cout << "\t Weight: ";
cin >> S.Task[i].weight;
cin.clear();
cin.ignore(100,'\n');
cout << "\t Upon: ";
cin >> S.Task[i].fullmark;
cin.clear();
cin.ignore(100,'\n');
totalWeight +=S.Task[i].weight;
}
cout << endl << "Subject " << S.subTitle << " added to system" << endl
<< "Total weight = " << totalWeight << endl;
afile.write (reinterpret_cast <const char*>(&S), sizeof (S));
afile.close();
}
}
You open the file with the flag std::ios::in (therefore you open it for reading), and try to write to it with afile.write(&S, sizeof(S))
If you want to write to the file you can either:
Open it with std::ios::out insteand of std::ios::in
Use an std::ofstream instead of an std::fstream and omit the std::ios::in/out flag
Also, in the future, try to reduce the code in question to the minimum to understand you problem.
I am so lost. I am having an issue with the following code when saving and loading data to a binary file. I have a very similar/exact piece of code that works with a different object. I think it has something to do with the email address and the # symbol in it. Here are the important functions.
/* This is my save to file function */
FILE *file=fopen("patronsave","wb");
fwrite(&buffer,sizeof(buffer),1,file);
for(int i=0;i<3;i++){
Patron_Class *ppointer = new Patron_Class();
cout << "\n" << endl;
ppointer->save(file);
}
fclose(file);
That is the function I use to save my objects to a file.
Here is my code that I am using to load the file:
vector<Patron_Class*> Patron_Entries;
FILE *file=fopen("patronsave","rb");
fread(&buffer,sizeof(buffer),1,file);
printf("Buffer: %d\n",buffer);
for(int i=0;i<buffer;i++){
Patron_Class *pointer2 =new Patron_Class(file);
Patron_Entries.push_back(pointer2);
Patron_Entries[i] -> print();
system("pause");
}
fclose(file);
If I run the save function and then immediatly run the load function it works, but if I only run the load function it crashes when it tried to load the email. Here is my class and object code:
class Patron_Class{
public:
long patron_id;
string F_name;
string L_name;
long phone_num;
string email;
string street_address;
string city;
string state;
int zip_code;
Patron_Class(){
cout << "Please enter a new ID" << endl;
cin >> patron_id;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a First name" << endl;
cin >> F_name;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a last name" << endl;
cin >> L_name;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a phone number" << endl;
cin >> phone_num;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a email" << endl;
cin >> email;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a street address" << endl;
cin >> street_address;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a city" << endl;
cin >> city;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a State via it's initials" << endl;
cin >> state;
cin.ignore(1000, '\n');
system("cls");
cout << "Please enter a zip code" << endl;
cin >> zip_code;
cin.ignore(1000, '\n');
system("cls");
cout << "You have created a new patron named: " << F_name << " " << L_name << endl;
}
Patron_Class(FILE *inputfile){
fread(&patron_id, sizeof(patron_id),1,inputfile);
fread(&F_name, sizeof(F_name),1,inputfile);
fread(&L_name, sizeof(L_name),1,inputfile);
fread(&phone_num, sizeof(phone_num),1,inputfile);
fread(&email, sizeof(email),1,inputfile);
fread(&street_address, sizeof(street_address),1,inputfile);
fread(&city, sizeof(city),1,inputfile);
fread(&state, sizeof(state),1,inputfile);
fread(&zip_code, sizeof(zip_code),1,inputfile);
}
void print(){
cout << patron_id << " " << F_name << " " << L_name << " " << phone_num << " " << email << " " << street_address << " " << city << " " << state << " " << zip_code << "\n" << endl;
}
void save(FILE *inputFile){
fwrite(&patron_id, sizeof(patron_id),1,inputFile);
fwrite(&F_name, sizeof(F_name),1,inputFile);
fwrite(&L_name, sizeof(L_name),1,inputFile);
fwrite(&phone_num, sizeof(phone_num),1,inputFile);
fwrite(&email, sizeof(email),1,inputFile);
fwrite(&street_address, sizeof(street_address),1,inputFile);
fwrite(&city, sizeof(city),1,inputFile);
fwrite(&state, sizeof(state),1,inputFile);
fwrite(&zip_code, sizeof(zip_code),1,inputFile);
}
};
Does anyone know why it might be crashing?
This is CLEARLY wrong:
string F_name;
...
fread(&F_name, sizeof(F_name),1,inputfile);
...
fwrite(&F_name, sizeof(F_name),1,inputFile);
[The same applies to all the other strings in your PatronClass - I'm using the first one for this example]
The class std::string will look something like this (for illustration purposes, the exact implementation involves several layers, some templates, and other stuff, so this is simplified for the purposes of the explanation to follow):
class string
{
char *str;
int len;
public:
...
};
So, when you do fread from the file and fwrite to the file, you are reading/writing the char *str; and int len; members from/to the file.
Let's say we start your program from scratch, with no data in the file, and we use the Patron_Class() constructor. So we read in an id, and then the F_name from the console. Let's say we enter Charles. So somehow the string class will allocate 8 bytes of memory, at the address of 0x600018. So string::str == 0x600018 and len = 8 - at location 6000018 in the heap are the letters C h a r l e s \0 [ spaces just to illustrate they are in separate memory locations]. Now we save this to a file. So the file contains 00600018 00000008. Now we stop the program and start it again, using the PatronClass(file) constructor. The heap is completely empty. We load the file data, so string::str = 0x600018 and len = 8, but that locaton 0x600018 does not contain C h a r l e s \0, but whatever the heap normally is filed with when the heap is initialized [quite likely 0]. So no wonder your name doesn't appear.
Now, the exact behaviour of your actual program is probably not the same as what I've described above, but it will NOT work right. No way, never, ever. No matter what characters you have or haven't got in names, email addresses or any other string in your code. The only reason it may APPEAR to work is that the data is still, for the most part, there in the heap, and it seems to be working because it doesn't get overwritten by something else in your case.