How to get program to read a line? C++ - c++

I have a data set with headers and data below those headers. How do I get c++ to read the first line of actual data (which starts on the 3rd row) and keep reading until the file ends?
I know you have to use a while loop and '++' on some declared variable, but I'm not sure how to.
Here is a screenshot of the data file: enter image description here

Just read the first line into a dummy variable first before your while loop
How to read line by line or a whole text file at once?
#include <fstream>
#include <string>
int main()
{
std::ifstream file("Read.txt");
std::string str;
std::getline(file, str); // read a line, as dummy read
while (std::getline(file, str)) // keep reading till end of file
{
// Process str
}
}

Related

Read multiline file and using rdbuf()

I've a multiline file, every line a string.
Example of code.txt:
AAAAA
BB33A
C544W
I have to put some code contained in another file before every string. I'm using this:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
//the file to include before every string
ifstream one("1.txt");
//final output file
ofstream final;
final.open ("final.txt", ofstream::app);
//string file
string line;
ifstream file("code.txt");
while (getline(file,line))
{
final<<one.rdbuf();
final<<line;
}
}
Now, this doesn't work, it works only for the first line of code.txt. What is wrong?
final<<one.rdbuf() works for only the first line because once you stream out the rdbuf the first time, its read pointer is sitting at the end of the 1.txt file data. There is no data left for it to read on subsequent streaming. You would have to reset the one stream back to the beginning of its data on each loop iteration, eg:
while (getline(file,line))
{
final<<one.rdbuf();
final<<line;
one.seekp(0); // <-- add this
}
Otherwise, do as #Check suggests. Read the content of the 1.txt file into memory one time, and then stream that out on each loop iteration, instead of re-reading the file on each iteration.
I would change your final<<one.rdbuf();.
You can use this:
//the file to include before every string
ifstream one("1.txt");
std::string first;
if (one.is_open())
{
// file length and reserve the memory.
one.seekg(0, std::ios::end);
first.reserve(static_cast<unsigned int>(one.tellg()));
one.seekg(0, std::ios::beg);
first.assign((std::istreambuf_iterator<char>(one)),
(std::istreambuf_iterator<char>()));
one.close();
}
//final output file
ofstream final;
final.open ("final.txt", ofstream::app);
//string file
string line;
ifstream file("code.txt");
while (getline(file,line))
{
final<<first;
final<<line;
}
Maybe you want to check this https://stackoverflow.com/a/8737787/3065110

Replace line in txt file c++

I just wondering cause i have a text file containing STATUS:USERID:PASSWORD in accounts.txt
example it would look like this:
OPEN:bob:askmehere:
OPEN:john:askmethere:
LOCK:rob:robmypurse:
i have a user input in my main as such user can login 3x else status will change from OPEN to LOCK
example after 3 tries of john
before:
OPEN:bob:askmehere:
OPEN:john:askmethere:
LOCK:rob:robmypurse:
after:
OPEN:bob:askmehere:
LOCK:john:askmethere:
LOCK:rob:robmypurse:
what i have done is:
void lockUser(Accounts& in){
// Accounts class consist 3 attributes (string userid, string pass, status)
ofstream oFile;
fstream iFile;
string openFile="accounts.txt";
string status, userid, garbage;
Accounts toupdate;
oFile.open(openFile);
iFile.open(openFile);
while(!iFile.eof()){
getline(iFile, status, ':');
getline(iFile, userid, ':');
getline(iFile, garbage, '\n');
if(userid == in.getUserId()){
toupdate.setUserId(in.getuserId());
toupdate.setPassword(in.getPassword());
toupdate.setStatus("LOCK");
break;
}
//here i should update the account.txt how do i do that?
ofile.open(openFile);
ofile<<toupdate.getStatus()<<":"<<toupdate.getUserId()":"<<toupdate.getPassword()<<":"<<endl;
}
There are two common ways to replace or otherwise modify a file. The first and the "classic" way is to read the file, line by line, check for the line(s) that needs to be modified, and write to a temporary file. When you reach the end of the input file you close it, and rename the temporary file as the input file.
The other common way is when the file is relatively small, or you have a lot of memory, is to read it all into memory, do the modification needed, and then write out the contents of the memory to the file. How to store it in memory can be different, like a vector containing lines from the file, or a vector (or other buffer) containing all characters from the file without separation.
Your implementation is flawed because you open the output file (which is the same as the input file) inside the loop. The first problem with this is that the operating system may not allow you to open a file for writing if you already have it open for reading, and as you don't check for failure from opening the files you will not know about this. Another problem is if the operating system allows it, then your call to open will truncate the existing file, causing you to loose all but the very first line.
Simple pseudo-ish code to explain
std::ifstream input_file("your_file");
std::vector<std::string> lines;
std::string input;
while (std::getline(input_file, input))
lines.push_back(input);
for (auto& line : lines)
{
if (line_needs_to_be_modified(line))
modify_line_as_needed(line);
}
input_file.close();
std::ofstream output_file("your_file");
for (auto const& line : lines)
output_file << line << '\n';
Use ReadLine and find the line you wanna replace, and use replace to replace the thing you wanna replace. For example write:
string Example = "Text to find";
openFile="C:\\accounts.txt"; // the path of the file
ReadFile(openFile, Example);
OR
#include <fstream>
#include <iostream>
#include <string>
int main() {
ifstream openFile;
string ExampleText = BOB;
openFile("accounts.txt");
openFile >> ExampleText;
openFile.replace(Example, "Hello");
}

#include <fstream> visual c++ 2010 not working properly

I know that the title is a little vague but i can't think of a better title right now.
The extract from my code looks like this:
#include<iostream>
#include<fstream>
int main(){
ifstream f("cuvinte.txt");
f.getline(cuvant);
return 0;
}
When i want to read the next word from "cuvinte.txt" i write f.getline(cuvant); but i get the following error
error C2661: 'std::basic_istream<_Elem,_Traits>::getline' : no overloaded function takes 1 arguments
I don't know what the issue is, and i stumbled upon this problem a while ago and still can't get past it.
I don't know what the issue is, and i stumbled upon this problem a
while ago and still can't get past it.
To the reference!
basic_istream& getline( char_type* s, std::streamsize count );
You need to provide the size, i.e. the amount of available space in cuvant.
f.getline(cuvant, size);
^^^^
EDIT
An alternative would be to use more modern instruments:
string cuvant;
getline(f, cuvant);
You seem a little shaky on your familiarity with the various forms of getline. Here are a few simple uses of it for your reference:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
int main()
{
string filepath = "test.txt"; // name of the text file
string buffer; // buffer to catch data in
string firstLine; // the first line of the file will be put here
ifstream fin;
fin.open(filepath); // Open the file
if(fin.is_open()) // If open succeeded
{
// Capture first line directly from file
getline(fin,firstLine,'\n'); // Capture first line from the file.
cout << firstLine << '\n'; // Prove we got it.
fin.seekg(0,ios_base::beg); // Move input pointer back to the beginning of the file.
// Load file into memory first for faster reads,
// then capture first line from a stringstream instead
getline(fin,buffer,'\x1A'); // Capture entire file into a string buffer
istringstream fullContents(buffer); // Put entire file into a stringstream.
getline(fullContents,firstLine,'\n'); // Capture first line from the stringstream instead of from the file.
cout << firstLine << '\n'; // Prove we got it.
fin.close(); // Close the file
}
return 0;
}
Using the following sample file:
This is the first line.
This is the second line.
This is the last line.
You will get the following output:
This is the first line.
This is the first line.
The prototypes for getline are:
istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );
so, as the error message clearly states, you can't call it with one argument...
Assuming cuvant is an std::string, the correct call is
std::getline(f, cuvant);

New to <dirent.h>, trying to access data in a directory

I've never used dirent.h before. I was using istringstream to read through text files (singular), but have needed to try to revise the program to read in multiple text files in a directory. This is where I tried implementing dirent, but it's not working.
Maybe I can't use it with the stringstream? Please advise.
I've taken out the fluffy stuff that I'm doing with the words for readability. This was working perfectly for one file, until I added the dirent.h stuff.
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // for istringstream
#include <fstream>
#include <stdio.h>
#include <dirent.h>
void main(){
string fileName;
istringstream strLine;
const string Punctuation = "-,.;:?\"'!##$%^&*[]{}|";
const char *commonWords[] = {"AND","IS","OR","ARE","THE","A","AN",""};
string line, word;
int currentLine = 0;
int hashValue = 0;
//// these variables were added to new code //////
struct dirent *pent = NULL;
DIR *pdir = NULL; // pointer to the directory
pdir = opendir("documents");
//////////////////////////////////////////////////
while(pent = readdir(pdir)){
// read in values line by line, then word by word
while(getline(cin,line)){
++currentLine;
strLine.clear();
strLine.str(line);
while(strLine >> word){
// insert the words into a table
}
} // end getline
//print the words in the table
closedir(pdir);
}
You should be using int main() and not void main().
You should be error checking the call to opendir().
You will need to open a file instead of using cin to read the contents of the file. And, of course, you will need to ensure that it is closed appropriately (which might be by doing nothing and letting a destructor do its stuff).
Note that the file name will be a combination of the directory name ("documents") and the file name returned by readdir().
Note too that you should probably check for directories (or, at least, for "." and "..", the current and parent directories).
The book "Ruminations on C++" by Andrew Koenig and Barbara Moo has a chapter that discusses how to wrap the opendir() family of functions in C++ to make them behave better for a C++ program.
Heather asks:
What do I put in getline() instead of cin?
The code at the moment reads from standard input, aka cin at the moment. That means that if you launch your program with ./a.out < program.cpp, it will read your program.cpp file, regardless of what it finds in the directory. So, you need to create a new input file stream based on the file you've found with readdir():
while (pent = readdir(pdir))
{
...create name from "documents" and pent->d_name
...check that name is not a directory
...open the file for reading (only) and check that it succeeded
...use a variable such as fin for the file stream
// read in values line by line, then word by word
while (getline(fin, line))
{
...processing of lines as before...
}
}
You probably can get away with just opening the directories since the first read operation (via getline()) will fail (but you should probably arrange to skip the . and .. directory entries based on their name). If fin is a local variable in the loop, then when the outer loop cycles around, fin will be destroyed, which should close the file.

C++ length of file and vectors

Hi I have a file with some text in it. Is there some easy way to get the number of lines in the file without traversing through the file?
I also need to put the lines of the file into a vector. I am new to C++ but I think vector is like ArrayList in java so I wanted to use a vector and insert things into it. So how would I do it?
Thanks.
There is no way of finding the number of lines in a file without reading it. To read all lines:
1) create a std::vector of std::string
3 ) open a file for input
3) read a line as a std::string using getline()
4) if the read failed, stop
5) push the line into the vector
6) goto 3
You would need to traverse the file to detect the number of lines (or at least call a library method that traverse the file).
Here is a sample code for parsing text file, assuming that you pass the file name as an argument, by using the getline method:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
int main(int argc, char* argv[])
{
std::vector<std::string> lines;
std::string line;
lines.clear();
// open the desired file for reading
std::ifstream infile (argv[1], std::ios_base::in);
// read each file individually (watch out for Windows new lines)
while (getline(infile, line, '\n'))
{
// add line to vector
lines.push_back (line);
}
// do anything you like with the vector. Output the size for example:
std::cout << "Read " << lines.size() << " lines.\n";
return 0;
}
Update: The code could fail for many reasons (e.g. file not found, concurrent modifications to file, permission issues, etc). I'm leaving that as an exercise to the user.
1) No way to find number of lines without reading the file.
2) Take a look at getline function from the C++ Standard Library. Something like:
string line;
fstream file;
vector <string> vec;
...
while (getline(file, line)) vec.push_back(line);
Traversing the file is fundamentally required to determine the number of lines, regardless of whether you do it or some library routine does it. New lines are just another character, and the file must be scanned one character at a time in its entirety to count them.
Since you have to read the lines into a vector anyways, you might as well combine the two steps:
// Read lines from input stream in into vector out
// Return the number of lines read
int getlines(std::vector<std::string>& out, std::istream& in == std::cin) {
out.clear(); // remove any data in vector
std::string buffer;
while (std::getline(in, buffer))
out.push_back(buffer);
// return number of lines read
return out.size();
}