Getting specific data from a text file in c++ - c++

Im doing a login/registration system and the thing Im struggling with is checking whether the password is correct. So I have a text file with the user data that looks like this.
email: email#email.com
username: user123
password: 1234
In order to check if the password given by the user is correct I need to compare it to the one in the file. So how do I extract the password from the *.txt file. I really have no idea where to start.

You could take a look at this answer I found:
Reading file line by line
I think this can be a good start!
Then you can try to keep just the password: Get substring after specific character

Reading a configuration file like that is something useful that you will quickly benefit from. Usually it is a pretty standard code where you iterate through all the lines of your file, reading key-value pairs and storing them (for example, in a std::map<std::string, std::string>), to use them later.
Here you have a commented example of how such code would be:
#include <fstream> // ifstream
#include <sstream> // stringstream
#include <iostream> // cout, endl
#include <iomanip> // ws
#include <map> // map
using namespace std;
int main(){
map<string, string> configuration;
ifstream fin("your_file.txt");
string line;
while(getline(fin, line)){ // loop through every line in the file
string key;
string value;
stringstream ss(line); // make a stream from the line
getline(ss, key, ':'); // read key until :
ss >> ws; // ignore whitespaces
getline(ss, value); // read value until newline
// Store them
configuration[key] = value;
}
cout << "PW: " << configuration["password"] << endl;
return 0;
}

If the words "email" "username" and "password" are written in the text document, start by removing them so it looks like this.
email#email.com
user123
1234
Then if you put the text file in the same folder as the source, this basic program should be a start.
#include <iostream>
#include <fstream>
#include <string>
using std::cout;
using std::cin;
using std::ifstream;
using std::getline;
using std::endl;
using std::string;
int main()
{
ifstream input("info.txt"); //open the text document
string line;
//int lineCounter;
string mail;
string password;
string username;
cout << "Enter your mail: " << endl;
cin >> mail;
cout << "Enter your password: " << endl;
cin >> password;
int compareResult;
if (input.is_open())
{
while(getline (input,line)) //loop through input file line by line
{
if (line.length() > 0) //skip empty lines
{
//lineCounter++; //keeps track of what line you're at
compareResult = line.compare(mail); //compare each line of the document with the entered mail
if (compareResult == 0) //if match..
{
getline (input,line); //get next line (username)
username = line; //store username in a variable
getline (input,line); //get next line (password)
compareResult = line.compare(password); //compare password with entered password
if (compareResult == 0) //if match..
{
cout << "Logged in as " << username << endl;
}
}
}
}
input.close();
}
return 0;
}
Just change the code to match the name of your textfile or vice versa, just tried it and got logged in as user123.
Next time you need to find the answer to something similar, search for something like "searching text file for a particular string c++"
I haven't done anything in c++ in ages, but this question was the first I saw after signing up so I felt compelled,
THANK YOU!

Related

Need to read a line of text from an archive.txt until "hhh" its found and then go to the next line

My teacher gave me this assignment, where I need to read words from a file and then do some stuff with them. My issue is that these words have to end with "hhh", for example: groundhhh, wallhhh, etc.
While looking for a way to do this, I came up with the getline function from the <fstream> library. The thing is that getline(a,b,c) uses 3 arguments, where the third argument is to read until c is found but c has to be a char, so it doesn't work for me.
In essence, what I'm trying to achieve is reading a word from a file, "egghhh" for example, and make it so if "hhh" is read then it means the line finishes there and I receive "egg" as the word. My teacher used the term "sentinel" to describe this hhh thing.
This is my try:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
ifstream read_archive;
void showListWords(){
string word;
string sentinel = "hhh";
while (getline(read_archive,word,sentinel)){
cout << word << endl;
}
}
void openReadArchive(){
read_archive.open("words.txt");
if(read_archive.fail())
cout << "There is something wrong with the archive" << endl;
}
As you discovered, std::getline() allows you to specify only 1 char for the "sentinel" that it stops reading on, where '\n' (line break) is the default.
What you can do is use this default to read an entire line of text from the file into a std::string, then put that string into an std::istringstream and read words from that stream until the end of the stream is reached or you find a word that ends with "hhh", eg:
#include <sstream>
#include <limits>
void showListWords()
{
string line, word;
string sentinel = "hhh";
while (getline(read_archive, line))
{
istringstream iss(line);
while (iss >> word)
{
if (word.length() > sentinel.length())
{
string::size_type index = word.length() - sentinel.length();
if (word.compare(index, sentinel.length(), sentinel) == 0)
{
word.resize(index);
iss.ignore(numeric_limits<streamsize>::max());
}
}
cout << word << endl;
}
}
}
In which case, you could alternatively just read words from the original file stream, stopping when you find a word that ends with "hhh" and ignore() the rest of the current line before continuing to read words from the next line, eg:
#include <limits>
void showListWords()
{
string word;
string sentinel = "hhh";
while (read_archive >> word)
{
if (word.length() > sentinel.length())
{
string::size_type index = word.length() - sentinel.length();
if (word.compare(index, sentinel.length(), sentinel) == 0)
{
word.resize(index);
read_archive.ignore(numeric_limits<streamsize>:max, '\n');
}
}
cout << word << endl;
}
}

Read every line from text file to a vector C++

I have a text file where I need to be able to add or delete certain lines using functions. Everything is read from the file so when I open the file and write something then it deletes everything else in that file. I've understood that this can be done by using vectors. As I am new to C++ and especially vectors, I haven't figured out how I can read every line to a vector and then rewrite the lines to the text file.
Maybe someone can recommend me some kind of web-page or sth where I could learn how to do it.
Function for adding a line so far but it does not add the new line.
It should read the existing lines in the text file to vector<string> lines and then output it to the file while ignoring the first line with lines[i+1] and then add the new contact info to the end outside of the for loop.
void add contact(string filename, string*& names, string*& emails,
string*& numbers, unsigned int& quantity, string name, string email,
string number){
string str;
vector<string> lines;
ifstream input(filename);
while(getline(input, str)){
lines.push_back(str);
}
input.close();
ofstream output("contacts.txt");
output << quantity;
for(unsigned int i = 0; i < quantity; i++){
output << endl << lines[i+1];
}
output << endl << name << " | " << email << " | " << number << endl;
}
It's not that tough. You just have to get each line and push it to the std::vector.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::string str ;
std::vector<std::string> file_contents ;
std::fstream file;
file.open("test.txt",std::ios::in);
while(getline(file, str))
{
file_contents.push_back(str) ;
}
// You can access it using vector[i]
}

Problem reading a tab delimited file in C++

Right now I am trying to read in a list of books that have tab separated information and just printing the title. Eventually I will add each piece of info to a vector with their names. When I switched the delimiter to a tab from nothing or a one character space, suddenly nothing was outputted.I've look over stack exchange, but most of these solutions aren't telling me why mine doesn't work.
Here is my code
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
int main() {
ifstream DataFile;
string str;
string title;
string author;
string publisher;
string date;
string ficornon;
if(!DataFile)
{
cout<<"error";
}
DataFile.open("/Users/Kibitz/Desktop/bestsellers.txt",ios::in);
getline(DataFile,title);
while(!DataFile.eof()) // To get you all the lines.
{
cout<<title<<endl;
getline(DataFile,author);
getline(DataFile,publisher);
getline(DataFile,date);
getline(DataFile,ficornon);
getline(DataFile,title);
}
DataFile.close();
return 0;
}
First two lines of input file:
1876 Gore Vidal Random House 4/11/1976 Fiction
23337 Stephen King Scribner 11/27/2011 Fiction
There is a piece of code that reads your file example correctly and print out to stdout. Please notice delimiters used in 'getline' funcion: tab (character '\t') is used to mark end of data fields, and new line character '\n' is used to mark end of line. Check your data file to see it really contains tab delimiters.
The 'peek' function checks for next character in stream, and if there is not more chars, it sets 'eof' flag of the stream. Because there could be more conditions that can invalidate stream for reading I use good() function as the condition in 'while' loop.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
using namespace std;
int main() {
std::ifstream DataFile;
string str;
string title;
string author;
string publisher;
string date;
string ficornon;
DataFile.open("bestsellers.txt",std::ifstream::in);
// getline(DataFile,title); // don't need this line
DataFile.peek(); // try state of stream
while(DataFile.good())
{
getline(DataFile,str, '\t'); // you should specify tab as delimiter between filelds
getline(DataFile,author, '\t'); // IMO, better idea is to use visible character as a delimiter, e.g ',' or ';'
getline(DataFile,publisher, '\t');
getline(DataFile,date,'\t');
getline(DataFile,ficornon,'\n'); // end of line is specified by '\n'
std::cout << str << " " << author << " " << publisher << " " << date << " " << ficornon << std::endl;
DataFile.peek(); // set eof flag if end of data is reached
}
DataFile.close();
return 0;
}
/*
Output:
1876 Gore Vidal Random House 4/11/1976 Fiction
23337 Stephen King Scribner 11/27/2011 Fiction
(Compiled and executed on Ubuntu 18.04 LTS)
*/

How to read names into a pointer array and output them?

Here is what I got so far:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int characterList = 0;
char* dynamo = new char[1000];
char* buffer = dynamo;
ifstream input("wordlist.txt");
if (input.is_open())
{
input >> dynamo[characterList];
while (input.eof())
{
characterList++;
input >> dynamo[characterList];
cout << dynamo[characterList];
}
}
else
{
cout << "File not opened" << endl;
}
return;
}
I'm a beginner so I do apologize if this looks like terrible coding practice. I created a text file with a quote from Bill Cosby that I'm trying to read one word at a time. The quote is "I don't know the key to success, but the key to failure is trying to please everybody." I'm trying to read one word at a time from a text document ignoring punctuation. I know there are a lot of questions similar to this, but they are using code that I have not learned so I'm sorry for having a repeating question. I have not learned getline (I used cin.getline) and #include <string>.
Edit: I forgot to mention, so I'm sorry for not doing so earlier, but I'm studying dynamic memory allocation which is why I'm using the new char[1000].
I'd suggest you to use std::string instead of manually allocating buffers on the heap with new[] and trying to read text manually from the file into those buffers (and don't forget to free the buffer with proper delete[] calls!).
C++ input stream classes like std::ifstream can simply read text into std::string instances thanks to a proper overload of operator<<.
The syntax is as simple as:
string word;
while (inFile >> word)
{
cout << word << endl;
}
Here's a complete compilable sample code for you to experiment and learn:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream inFile("test.txt");
if (inFile.is_open())
{
string word;
while (inFile >> word)
{
cout << word << endl;
}
}
else
{
cout << "Can't open file." << endl;
}
}
This is the output I got on a test text file having the content specified in your question:
I
don't
know
the
key
to
success,
but
the
key
to
failure
is
trying
to
please
everybody.
NOTE
Of course, once you have your words read into a std::string instance, you can store them in a container like std::vector<std::string>, using its push_back() method.
I would do something like this:
#include <iostream>
#include <string>
#include <fstream>
int main() {
std::string array[6];
std::ifstream infile("Team.txt");
std::string line;
int i = 0;
while (std::getline(infile, line)) {
array[i++] = line;
}
return 0;
}
based on this answer.
Here, we assume we have to read 6 lines from the file "Team.txt". We use std:::getline() and we put inside a while so that we read all the file.
At every iteration, line holds the current line of the file read. Inside the body we store it in array[i].

C++ Processing file freezes program

I am working on a small program that takes a input file and processors the data in the file. With my current code (see below) when you enter a valid file name it just freezes the command line (drops down a line and just shows a flashing _ ) and I have to kill the program to get out. If you enter a invalid file name the if(!file) gets called and runs fine.
Whats really odd is that if I put a debugging cout above that if statement it will not get called if the file name is correct. Hope you can help and if you need more info let me know!
This is my current code:
using namespace std;
#include <iostream>
#include <stdexcept>
#include <string>
#include <fstream>
#include <vector>
#include <cctype>
#include "Student.h"
int main(){
string filename, name;
char *inputfile;
ifstream file;
vector<Student> students;
const int SIZE = 200;
char buffer [SIZE];
int regno, i;
cout << "Enter file name: ";
cin >> filename;
inputfile = const_cast<char*> (filename.c_str());
file.open(inputfile);
if (!file){
cout << "Failed to open " << filename << endl;
exit(1);
}
while (!file.eof()){
file.getline(buffer, SIZE);
i = 0;
regno = 0;
while (isdigit(buffer[i])){
regno = (regno*10)+buffer[i];
}
cout << regno;
}
file.close();
}
Your problems is that you never increase i in the cycle.
Here:
i = 0;
regno = 0;
while (isdigit(buffer[i])){
regno = (regno*10)+buffer[i];
}
You go into infinite cycle as i always stays 0.
Also why do you do the const_cast? You can open using a const char * too. So you can write this:
cin >> filename;
file.open(filename.c_str());
And code will still work.
There's another problem in your code concerning the use of getline() and eof(). The idiomatic way to read a file line-by-line is this:
std::string line;
while(getline(in, line)) {
// handle line here
}
in refers to some input stream like a std::ifstream or std::cin. The point is that reading a line can fail (e.g. due to EOF), which you check in above loop. Your version only checks if EOF was encountered before but not that the subsequent getline() call actually yielded any data.