C++ using a variable from an external file - c++

I am new to C++ but I like it so far.
Recently I have been making better and better builds of a console application that is just like a sign in thing, however you would give the password string and the username string in the same session.
I am trying to make it so that you open the application and checks for a certain file, and if it is not there it will create it and ask you to give it a value. I'm hoping this would make it so that I could have a user created password and username that is already set, rather than a couple of strings that already have a value but are not user created.
My code for my best version (its not great code) also not gonna post all of it just the part where they create the pass.
#include "stdafx.h"
#include "iostream"
#include "string"
#include "windows.h"
using namespace std;
int main() {
string user;
string pass;
string entry;
cout << "Make your username\n";
cin >> user;
cout << "Make your password\n";
cin >> pass;
return 0;
}
There is much more to this code (about 80 lines) but I don't feel like most of that information is needed.

Use std::ifstream to manage the file
std::ifstream f("path_to_file");
if (f.fail()) {
// we can't us the file (doesn't exist, incorrect permissions, etc.)
// instead, ask the user to enter their credentials
} else {
// read the file and extract necessary information
}

Related

Have user type file they want read & appending filenames C++

Disclosure: I am a student right now, so if you see any bad habits in my code, feel free to point them out. I have questions about both the ofstream and ifstream portions of my code.
In the ofstream, the user can create their own shopping list and name it (which will end up being the file name). Once their list is created, the file will save with the data.
Here my question: How do I automatically assign a file type to a file a user named? Here is my current code for it:
void createList(double price[100], double quantity[100], string item[100], double tax, int list_size) {
ofstream saved_list;
string listname;
string fileApplicator = ".txt";
cout << "What would you like to save this list as?: ";
getline(cin, listname.append(fileApplicator));
saved_list.open(listname.c_str());
As for the ofstream part of my code, I want the user to be able to select which file they want read based on the name of the file.
Here's my question: When I run the code, the file fails to open every time. I have a current file saved as safeway.txt but it will not open when I attempt it. Here is the code for it:
void reviewList(void) {
ifstream saved_list;
string listname;
string fileApplicator = ".txt";
char viewAnother = 'Y';
do {
cout << "Which list would like to open: ";
getline(cin, listname.append(fileApplicator));
saved_list.open(listname.c_str());
if (saved_list.is_open()) {
......//other code
}
cout << "Would you like to view a different list (Y/N): ";
cin >> viewAnother;
viewAnother = toupper(viewAnother);
if (viewAnother == 'N')
break;
}
else {
cout << "List not found. Please try again.\n";
}
} while (viewAnother == 'Y');
}
Solution to this problem:
getline(cin,listname.append(fileApplicator)); is the error. The append needs to be processed AFTER the getline, like this:
getline(cin,listname);
listname.append(fileApplicator);
This will allow the user to not only name a file and have it automatically saved as the programmer's desired file type but will also automatically select the desired file to be read without the user needing to enter the extension (at least on Windows OS's). I.E.: User can enter "Filename" rather than "Filename.txt".
Thank you #user4581301 and #drescherjm for helping to solve this issue!

file only saves one time data when use in loop

I have made a code in which data is taken from one whole file and only part of it is stored in the other file. But when I put it in loop it does not work has it should and I am having trouble locating the error can someone guide me where I am doing mistake.
Here is the things what my below written code does:
Takes user name from the user and creates the user name file then asks user if he wants to choice how many books from English book shelf he wants to choice.
NOW THE ERROR:
it does not take multiple inputs if user press 2 it only takes 1 input and copies one book no name to user file but does not do it for the next time
I MAY HAVE SOME CLUE MAYBE:
I think it maybe the get-line in using in the code, which may not be working for the second time the loop executes.
I have tried modifying my code in mostly each possible way I could, but I think may be I'm still new to programming field. So my logical thinking may be not so good. That is why I need little guidance only.
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;
string user;
int main()
{
cout<<"enter your name to create your Libaray file for book record\n";
getline(cin,user);
ofstream outFile(user.c_str(),ios::app); //user named file
string line;
ifstream inFile("English_book_shelf.txt"); //file with books name and
//number(labels)
int count,c;
cout<<"How many books do you want to buy?\n";
cin>>c;
for(int j=0;j<c;j++)
{
cout<<"Enter your choices:\n";
cin>>count;
while(count)
{
getline(inFile, line);
if (--count == 0)
{
outFile << line <<endl;
break;
}
}
}
}
I want my code to take multiple input from the user and store it in the user file.
Like if he want 3 books, the code should run copy 3 books from the book shelf file and copy it in the user file.
If he want 5 books, the code should run copy 5 books from the book shelf file and copy it in the user file and so own.
The line
if (--count == 0)
is the culprit. Simplify your code and you won't have to worry about such silly errors.
while(count >= 0)
{
getline(inFile, line);
outFile << line <<endl;
--count;
}

Launching a Script from C++

What I want to do is create a program to prompt the user for input. If they select yes I want to terminate the rest of the program. If they select no I want to immediately run a script. If there is no input for 5 minutes I want the script to automatically run. The only reason I want to use the script or batch file is I previously created it and it is already done.
The problems I am having is I am not sure how to declare the file system and file so it can be called. Then, I am not sure how to call the script to run. I am also not sure how to count down the 5 minutes to auto launch the script when ready. Below is my file in all it's current form.
//Program Name Apex Database Backup
//Written 8/3/2016
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include <windows.h>
#include <stdio.h>
using namespace std;
int main()
{
//Declarations
bool yes;
bool no;
char yesOrno;
string open;
FILE *C$;
//Prompt the User for Input
cout << "Are You Currently Loading Out? If Not This Program Will Execute in 5 Minutes. " << endl;
cout << "You Will Lose Your Connection to Apex! " << endl;
cout << "Enter yes or no: " << endl;
//Get User Input
cin >> yesOrno;
//Open the File
public FILE *DatabaseBackup.bat fopen(*C$)
//Process the Selection
if (no)
{
ShellExecute (DatabaseBackup.bat);
}
return 0;
}
The problems I am having is I am not sure how to declare the file system and file so it can be called.
I'm not sure what you mean by "declare the file system". If you want to open a file, take a look at C++ File IO
Then, I am not sure how to call the script to run
Running the script is a OS related function. See this answer on how to do this.
I am also not sure how to count down the 5 minutes to auto launch the script when ready.
You need to use a timer/clock with a signal/interrupt.

Why My Language translator program in Visual C++ overwriting a file with nothing instead of the translation

I have developed a program for translating words in english to my native language.Everything works fine with no errors, except that I am not getting the desired output.
The program asks a user for an input file in which there are english words, then it will read the file and write the translations in my native language to an output file specified by the user. My problem is that the program writes nothing to the output file. I even chose a non-empty output file but all I have seen and understood is that the program overwrits all what are in the output file with nothing.
Please I am asking for someone's help in this difficult time because I have exhausted all my thinking.
Below is the complete program:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h >
#include <conio.h>
#include <iomanip>
#include <cctype>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
string Identifier;
ofstream outfile;
ifstream infile;
static string fname1, fname2;
char a = (char)infile.get();
void Display(){
outfile << "Nuna";
}
void gettok(){
Identifier = "";
if (isalnum(a)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
Identifier = a;
while (isalnum(a = (char)infile.get()))
Identifier += a;
while (isspace(a = (char)infile.get())){
if (Identifier == "Display"){
Display();
a = (char)infile.get();
}
}
}
}
int main(){
cout << "Enter name of the file to be translated ";
cin >> fname1;
cout << "Enter new file name";
cin >> fname2;
infile.open(fname1);
if (infile.fail())
{
cerr << " No such a file Exist";
exit(1);
}
outfile.open(fname2);
if (outfile.fail())
{
cerr << "Unable to create a file";
exit(1);
}
while (!infile.eof())
{
gettok();
}
infile.close();
outfile.close();
}
Thank you sir, #TimStraubinger for your guide.
1. Firstly, based on my definition of the Display() function, I just want the program to be in such a way that whenever the english word
Display is read in the input file, then the Display() function is called whose job is to write the translation of the word display as "Nuna" to the output file. I want to have a function for translating each english word as I have done for the word Display. But if there is a better way, help me out.
2. I used "char a = (char)infile.get() " because i want to declare "a" as global variable to be known and used by all of my functions and furthermore, I can't open a file outside the "main" function. So, I searched and thought of ways but all failed!
Please any one's help is welcomed!
There are many things wrong with this, here are my main suggestions. Firstly, your code is hard to read and confusing and defies lots of good convention. I recommend you follow a few textbook examples with C++ and learn to organize your code better so that we can better help you. As for your code, some more obvious problems are as follows:
char a = (char)infile.get()
Here, you're trying to access the file before it is opened. This needs to be called after infile is opened.
And to see something written to the file, you have the condition:
if (Identifier == "Display"){
Display();
a = (char)infile.get();
}
Why does the accumulator string, Identifier, need to have "Display" stored in order to write something to the file? (I highly recommend you find a better function name for Display(), which suggests you're writing something to the screen.) Also, inside the while (isspace(a = (char)infile.get())) loop, infile.get() will be called twice every loop, once to check the loop condition and once because you wrote it in additionally. This will cause every other character to be skipped in that loop.

For loops and inputing data?

trying to figure out how to make a little inventory program and I can't for the life figure out why it isn't working.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct record
{
int item_id;
string item_type;
int item_price;
int num_stock;
string item_title;
string item_author;
int year_published;
};
void read_all_records(record records[]);
const int max_array = 100;
int main()
{
record records[max_array];
read_all_records(records);
cout << records[2].item_author;
return 0;
}
void read_all_records(record records[])
{
ifstream invfile;
invfile.open("inventory.dat");
int slot = 0;
for (int count = 0; count<max_array; count++);
{
invfile >> records[slot].item_id >> records[slot].item_type >> records[slot].item_price >> records[slot].num_stock >> records[slot].item_title >> records[slot].item_author >> records[slot].year_published;
slot++;
}
invfile.close();
}
I'm testing it by having it print the second item from records author. When I run it, it doesn't show the authors name at all. The .dat file is located in just about every folder where the project is (I forgot which folder it needs to be in) so it's there.
The issue isn't that the file isn't working. It's the array not printing off anything.
my inv file is basically:
123456
book
69.99
16
title
etc
etc
and repeats for different books/cds etc all on one line, all without spaces. Should just next in.
You should check to see that the file is open.
invfile.open("inventory.dat");
if (!invfile.is_open())
throw std::runtime_error("couldn't open inventory file");
You should check to seen that your file reads are working and breaks when you hit the end of file.
invfile >> records[slot].item_id >> records[slot].item_type ...
if (invfile.bad())
throw std::runtime_error("file handling didn't work");
if (invfile.eof())
break;
You probably want to read each record at time, as it isn't clear from this code how the C++ streams are supposed to differentiate between each field.
Usually you'd expect to use std::getline, split the fields on however you delimit them, and then use something like boost::lexical_cast to do the type parsing.
If I were doing this, I think I'd structure it quite a bit differently.
First, I'd overload operator>> for a record:
std::istream &operator>>(std::istream &is, record &r) {
// code about like you had in `read_all_records` to read a single `record`
// but be sure to return the `stream` when you're done reading from it.
}
Then I'd use an std::vector<record> instead of an array -- it's much less prone to errors.
To read the data, I'd use std::istream_iterators, probably supplying them to the constructor for the vector<record>:
std::ifstream invfile("inventory.dat");
std::vector<record> records((std::istream_iterator<record>(invfile)),
std::istream_iterator<record>());
In between those (i.e., after creating the file, but before the vector) is where you'd insert your error handling, roughly on the order of what #Tom Kerr recommended -- checks for is_open(), bad(), eof(), etc., to figure out what (if anything) is going wrong in attempting to open the file.
Add a little check:
if (!invfile.is_open()) {
cout<<"file open failed";
exit(1);
}
So that way, you don't need to copy your input file everywhere like you do now ;-)
You are reading in a specific order, so your input file should have the same order and required number of inputs.
You are printing 3rd element of the struct records. So you should have at least 3 records. I don't see anything wrong with your code. It would a lot easier if you can post your sample input file.