How to read a .txt file in C++ - c++

We have this .txt that has this inside
PR-ATT-2 Sep 5 2018 Dec 15 2020
LE-GE-3 Oct 15 2019 Jan 20 2021
With our code, we're trying to set the first line to a string
#include <string>
#include <array>
#include <cstdlib>
#include <fstream>
#include <istream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
ifstream projin;
projin.open(argv[1], ios::in);
// Making sure the file opened correctly
if ((projin.is_open()) == false) {
cout << "There was an error opening the file";
return 1;
} else {
string projectline;
getline(projin, projectline);
cout << projectline << " ";
projin.close();
return 2;
}
return 0;
}
This returns nothing. But if the code looks like this
#include <string>
#include <array>
#include <cstdlib>
#include <fstream>
#include <istream>
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
ifstream projin;
projin.open(argv[1], ios::in);
// Making sure the file opened correctly
if ((projin.is_open()) == false) {
cout << "There was an error opening the file";
return 1;
} else {
string projectline;
getline(projin, projectline);
cout << "Hello my name is Alejandro, and my favorite word is
pneumonoultramicroscopicsilicovolcanoconiosis " << projectline << " ";
projin.close();
return 2;
}
return 0;
}
This returns "Hello my name is Alejandro, and my favorite word is pneumonoultramicroscopicsilicovolcanoconiosis PR-ATT-2 Sep 5 2018 D".
We can not figure out for the life of us what is going on.

We changed it to a while loop that prints the line until the end of the file, and that gave us our intended output.
ifstream projin;
projin.open(argv[1], ios::in);
// Making sure the file opened correctly
if ((projin.is_open()) == false) {
cout << "There was an error opening the file";
return 1;
} else {
string projectline;
while (getline(projin, projectline)) {
cout << projectline << endl;
}
projin.close();
return 2;
}

Related

Program to read from file line by line

I've been trying to write a code to read from a file line by line:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream jin("Story.txt");
// ins.open("Story.txt", ios::in);
if (!jin)
{
cout << "File not opened" << endl;
return 1;
}
else{
char a[100];
do
{
jin.getline(a, 100);
cout << a << endl;
}
while (!jin.eof());
jin.close();
return 0;
}
}
However, on executing this program on Visual Studio Code on Windows, it behaves as infinite loop.
Can someone tell what's wrong?
(I am sure that the file Story.txt exists, no doubt about that)
When std::istream::getline has read 100-1 characters (without finding a newline,\n), it will set the failbit on the stream. This prevents further reading on the stream (unless you reset that state). It does however not set eofbit so you are now in a bit of a pickle. The failbit prevents further reading, and eof() returns false, because eofbit is not set - it will therefore loop indefinitely.
If at least one of the lines in Story.txt is longer than 99 chars, the above is what will happen.
The easiest way out is to use a std::string and std::getline instead:
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream jin("Story.txt");
if(!jin) {
std::cerr << "File not opened: " << std::strerror(errno) << std::endl;
return 1;
}
std::string a;
while(std::getline(jin, a)) {
std::cout << a << '\n';
}
return 0;
}
If you really do not want to use std::getline and std::string, you can, but it's much harder:
#include <cerrno>
#include <cstring>
#include <fstream>
#include <iostream>
int main() {
std::ifstream jin("Story.txt");
if(!jin) {
std::cerr << "File not opened: " << std::strerror(errno) << std::endl;
return 1;
}
char a[100];
while(true) {
jin.getline(a, 100);
std::cout << a; // output what we got
if(jin) {
// got a complete line, add a newline to the output
std::cout << '\n';
} else {
// did not get a newline
if(jin.eof()) break; // oh, the end of the file, break out
// reset the failbit to continue reading the long line
jin.clear();
}
}
}
jin.eof() will only return true if a eof-token is found, and this will not happend unless the file is open. That is what causing your infinite loop.
Then you would probably want something like this:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream jin{"Story.txt"};
if (!jin)
{
cout << "File not opened" << endl;
return 1;
}
for (std::string a; std::getline(jin, a);) { // Read every line
cout << a << "\n";
}
// jin is closed when going out of scope so no need for close();
return 0;
}

Read multiple files with C++

I would like to edit the below code to look at and read several other files in the proc directory. May I get some guidance on how to improve this code to look at other proc files other than just the uptime. Thank you.
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib> // for exit()
int main()
{
using namespace std;
// ifstream is used for reading files
// We'll read from a file called Sample.dat
ifstream inf("/proc/uptime");
// If we couldn't open the input file stream for reading
if (!inf)
{
// Print an error and exit
cerr << "Uh oh, file could not be opened for reading!" << endl;
exit(1);
}
// While there's still stuff left to read
while (inf)
{
// read stuff from the file into a string and print it
std::string strInput;
getline(inf, strInput);
cout << strInput << endl;
}
return 0;
// When inf goes out of scope, the ifstream
// destructor will close the file
}
Here it is written with a function instead
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib> // for exit()
using namespace std;
void readfile(string file)
{
ifstream inf (file.c_str());
if (!inf)
{
// Print an error and exit
cerr << "Uh oh, file could not be opened for reading!" << endl;
exit(1);
}
while (inf)
{
std::string strInput;
getline(inf, strInput);
cout << strInput << endl;
}
}
int main()
{
cout << "-------------------obtaining Totaltime and Idletime----------------" << endl;
readfile("/proc/uptime");
return 0;
}

Expression invalid null pointer

I am having some issues with my program, what I want to do is generate a md5 password which then save it to a text file and this part is not working for me, ("Expression invalid null pointer") any help would be greatly appreciated.
C++ Visual Studio 2015
main.cpp
#include <iostream>
#include <istream>
#include <string>
#include <sstream>
#include <fstream>
#include <iterator>
#include "s_encrypt.h"
#include "encrypt_copy.h"
using namespace std;
int main(int argc, char *argv[])
{
string password = "";
cout << "Please enter a password to be encrypted\n";
getline(cin, password);
cout << "MD5 Encryption of " << password << " " << "is this" << " " << md5(password);
cout << "Saving MD5 generated password to text file";
std::string p = md5(password);
CopyEncryptedPw(p);
return 0;
}
encrypt_copy.cpp
#include <istream>
#include <iostream>
#include <fstream>
#include <string>
#include "encrypt_copy.h"
using namespace std;
std::string CopyEncryptedPw(std::string pass)
{
fstream outfile;
outfile.open("C:\encrypted_pass.txt", ios::out);
outfile << pass;
return 0;
}
encrypt_copy.h
#pragma once
#ifndef ENCRYPT_H
#define ENCRYPT_H
std::string CopyEncryptedPw(std::string pass);
#endif
There are two issues with your code:
Issue 1:
outfile.open("C:\encrypted_pass.txt", ios::out);
If we assume that your OS is Windows, this should be:
outfile.open("C:\\encrypted_pass.txt", ios::out);
Also, the forward slash can be used for the standard stream functions:
outfile.open("C:/encrypted_pass.txt", ios::out);
Issue 2:
You're returning 0 for a function that is supposed to return a std::string.
std::string CopyEncryptedPw(std::string pass)
{
//...
return 0; // <-- This is bad
}
This code exhibits undefined behavior on return, since what will happen is that a 0 is assigned to the std::string return value, and assigning 0 to a std::string is undefined behavior.
Either return a string type (or a type that is convertible to a std::string), or return int:
int CopyEncryptedPw(std::string pass)
{
fstream outfile;
outfile.open("C:\\encrypted_pass.txt", ios::out);
outfile << pass;
return 0;
}
You could also have a void function that doesn't return anything, but you probably want an int return value for example, to return an error code (or OK indicator).

Splitting read file C++

Lets start with that I have absolutely no experience with C++ , but I got this project to connect a POS with a verifone. We do not have the standard verifone SDK but something custom.
At fist I needed to prepair data to send to C++ and C++ will send it to the Verifone. This is where I am getting stuck, I have a .txt file, which I can read with C++ but now I need to split the data.
This is my current code:
#include "stdafx.h"
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
string file_get_contents(const char *filename)
{
ifstream in(filename);
if (in.fail())
{
cerr << "File not found: " << filename << endl;
return "";
}
std::stringstream buffer;
buffer << in.rdbuf();
in.close();
return buffer.str();
}
int main(int argc, char **argv)
{
vector<string> strings;
string contents = file_get_contents("C:/wamp/www/cmd/config.txt");
string s;
while (contents, s, '||') {
cout << s << endl;
strings.push_back(s);
}
cout << s; // ECHO CONTENTS
std::cin.ignore(); // pause
return 0;
}
With this code my console just stays blank, no data is being displayed.
The full string I am splitting is:
"notepad://amount=10320.53||session_id=7946548443287465/"
The result that I want is to get an array that uses "amount" and "session_id" as keys and their values as value.
What is the best way of achieving this?
I used the following code to actually display the string in my console which was working:
int main(int argc, char **argv)
{
string contents = file_get_contents("config.txt");
cout << contents; // ECHO CONTENTS
std::cin.ignore(); // pause
return 0;
}
This shows how to use a regex to extract the information you want, there are a lot of online resources on how to read files properly so I left that part out.
#include <iostream>
#include <regex>
#include <unordered_map>
#include <string>
int main(int argc, char **argv)
{
std::regex pattern("amount=([[:digit:]\\.]*)\\|\\|session_id=([[:digit:]]*)");
std::smatch results;
std::unordered_map<std::string, std::string> data;
std::string contents = "notepad://amount=10320.53||session_id=7946548443287465/";
//string contents = file_get_contents("C:/wamp/www/cmd/file.txt");
if(std::regex_search(contents, results, pattern))
{
data["amount"] = results[1];
data["session_id"] = results[2];
}
std::cout << "Amount: " << data["amount"] << std::endl;
std::cout << "Seesion ID: " << data["session_id"] << std::endl;
return 0;
}

How to write to and read from a file simultaneously in C++

I need to write two programs write.cpp & read.cpp to run simultaneously. One of them write(overwrite) to a file and the other one reads from it.
Basically, there is always only one line in the file.
write.cpp performs the operation successfully but read.cpp doesn't show anything. Using tail -f also shows incorrect result.
write.cpp:
#include <stdio.h>
#include <ctime>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
ofstream myfile;
int i = 70;
char c;
while(i <85)
{
myfile.open ("example.txt");
c = i++;
myfile << c << endl;
myfile.close();
sleep(1);
}
return 0;
}
read.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
sleep(1);
getline (myfile,line);
cout << line << endl;
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
May I know which part of both programs causes the problem and how may I solve it?
You're doing the right thing in the writer, but once you've read to end of file, the input stream becomes unusable until the fail condition is set. The best solution is probably to do exactly what you're doing in the writer: open and close the file each time in the read loop.
Be aware that there will be a moment when the file is empty; when you open the file for writing in the writer, it will be truncated, and if the reader happens to try to read at precisely this moment, it will find an empty file. (It's no big problem; just be aware of it, maybe skipping the sleep if you find an empty line.)
To add some detail to my answer to your previous question, here is how you could use Boost's interprocess communication to achieve this if you insist on using a file for ipc.
A writer may look like this:
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <fstream>
#include <iostream>
int main()
{
using namespace boost::interprocess;
std::string line, shared_filename = "shared";
{
std::ofstream create_shared_file(shared_filename.c_str());
}
for (;;)
{
std::cout << "Enter some text: ";
std::cin >> line;
try
{
file_lock lock(shared_filename.c_str());
scoped_lock<file_lock> lock_the_file(lock);
std::ofstream shared_file(shared_filename.c_str(), std::ofstream::trunc);
shared_file << line << std::endl;
shared_file.flush();
}
catch (interprocess_exception const& e)
{
std::cerr << e.what() << std::endl;
}
}
}
The corresponding reader:
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <fstream>
#include <iostream>
#include <unistd.h>
int main()
{
using namespace boost::interprocess;
std::string line, shared_filename = "shared";
for (;;)
{
try
{
file_lock lock(shared_filename.c_str());
std::cout << "Waiting for file lock..." << std::endl;
sharable_lock<file_lock> lock_the_file(lock);
std::cout << "Acquired file lock..." << std::endl;
std::ifstream shared_file(shared_filename.c_str());
shared_file >> line;
if (line.empty())
{
std::cout << "Empty file" << line << std::endl;
}
else
{
std::cout << "Read: " << line << std::endl;
}
}
catch (interprocess_exception const& e)
{
std::cerr << "Could not lock " << shared_filename << ": " << e.what() << std::endl;
}
std::cout << "Sleeping..." << std::endl;
sleep(2);
}
}