I am trying to read the number of newlines in a text file. However, my counter is not working. Is it because of the string comparison?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string line;
ifstream myFile;
int temp_height = 0;
myFile.open("Levels.txt");
while (!myFile.eof())
{
getline(myFile,line);
if (line == "\n")
temp_height++;
}
cout<<"\n Newlines: "<<temp_height;
myFile.close();
}
Change:
while (!myFile.eof())
{
getline(myFile,line);
to
while (getline(myFile, line))
{
This means you are actually reading before you check, and also that you check for other failures. You almost never want to actually check eof, it probably doesn't work quite how you expect.
Edit: Ok, you want blank lines. getline discards the '\n' character, so check for
if (line.empty())
for a final loop:
while (getline(myFile, line))
{
if (line.empty())
++temp_height;
}
You can find documentation for std::getline here.
Related
How do I remove/replace the last line of a file in C++? I looked at these questions:
Deleting specific line from file, Read and remove first (or last) line from txt file without copying
. I thought about iterating to the end of the file and then replacing the last line but I'm not sure how to do that.
Find the position of the last occurrence of '\n' in the file content. If the file ends with '\n', i.e there is no more data after the last '\n', then find the position of the previous occurrence of '\n'. Use resize_file to truncate files at the found position or just replace the content after the found position.
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream fin("input.txt");
ofstream fout("output.txt");
while (!fin.eof()) {
string buffer;
getline(fin, buffer);
if (fin.eof()) {
fout << "text to replace last line";
} else {
fout << buffer << '\n';
}
}
fin.close();
fout.close();
}
Also you can read and store all your input file, modify and then write it:
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main() {
// read
ifstream fin("input.txt");
vector<string> lines;
while (!fin.eof()) {
string buffer;
getline(fin, buffer);
lines.push_back(buffer + '\n');
}
fin.close();
// modify
lines[lines.size() - 1] = "text to replace last line";
// write
ofstream fout("output.txt");
for (string line: lines) { // c++11 syntax
fout << line;
}
fout.close();
}
I want to be able to a string that contains certain characters in a file that contains one string per line.
#include <iostream>
#include <fstream>
#include <string>
int main(){
string line;
ifstream infile;
infile.open("words.txt");
while(getline(infile, line,' ')){
if(line.find('z')){
cout << line;
}
}
}
That's my attempt at finding all the string that contains the character z.
The text file contains random strings such as
fhwaofhz
cbnooeht
rhowhrj
perwqreh
dsladsap
zpuaszu
so with my implementation, it should only print out the strings with the character z in it. However, it seems to be reprinting out all the contents from the text file again.
Problem:
In your file the strings aren't separated by a space (' ') which is the end delimiter, they are separated by a end of line ('\n'), that is a different character. As a consequence, in the first getline everything goes to line. line contains all the text in the file, including z's, so all the content is printed. Finally, the code exits the while block after running once because getline reaches the end of the file and fails.
If you run this code
#include <iostream>
#include <fstream>
#include <string>
int main(){
std::string line;
std::ifstream infile;
infile.open("words.txt");
while(getline(infile, line,' ')){
std::cout << "Hi";
if(line.find('z')){
std::cout << line;
}
}
}
"Hi" will be only printed once. That is because the while block is only executed once.
Additionaly, see that line.find('z') won't return 0 if not match is found, it will return npos. See it running this code (As it says here):
#include <iostream>
#include <fstream>
#include <string>
int main(){
std::string line;
std::ifstream infile;
infile.open("words.txt");
while(getline(infile,line)){
std::cout << line.find('z');
if(line.find('z')){
std::cout << line << "\n";
}
}
}
Solution:
Use getline(infile,line) that is more suitable for this case and replace if(line.find('z')) with if(line.find('z') != line.npos).
while(getline(infile,line)){
if(line.find('z') != line.npos){
std::cout << line << "\n";
}
}
If you need to put more than one string per line you can use the operator >> of ifstream.
Additional information:
Note that the code you posted won't compile because string, cout and ifstream are in the namespace std. Probably it was a part of a longer file where you were using using namespace std;. If that is the case, consider that it is a bad practice (More info here).
Full code:
#include <iostream>
#include <fstream>
#include <string>
int main(){
std::string line;
std::ifstream infile;
infile.open("words.txt");
while(getline(infile,line)){
if(line.find('z') != line.npos){
std::cout << line << "\n";
}
}
}
getline extracts characters from the source and stores them into the variable line until the delimitation character is found. Your delimiter character is a space (" "), which isn't present in the file, so line will contain the whole file.
Try getline(infile, line, '\n') or simply getline(infile, line) instead.
The method find returns the index of the found character, where 0 is a perfectly valid index. If the character is not found, it returns npos. This is a special value whcih indicates "not found", and it's nonzero to allow 0 to refer to a valid index. So the correct check is:
if (line.find('z') != string::npos)
{
// found
}
I'm trying to retrieve certain lines from a text file. I'm using:
#include <iostream>
#include <fstream>
using namespace std;
void parse_file()
{
std::ifstream file("VampireV5.txt");
string str= "Clan";
string file_contents;
while (std::getline(file, str))
{
file_contents += str;
file_contents.push_back('\n');
}
cout << file_contents;
file.close();
}
int main()
{
parse_file();
return 0;
}
I want to get that one and only line containing "Clan" until '\n'. I've tried to add an if inside the while loop but it is not returning anything.
Is there a way to make it get 1 line at once?
Your code is almost correct as in: It reads the file line by line and appends the contents to your string.
However since you only want that one line, you also need to check for what you are looking for.
This code snippet should give you only the line, which starts with the word 'Clan'.
If you want to check, whether the string is anywhere on the line, consider checking for != string::npos.
void parse_file()
{
std::ifstream file("VampireV5.txt");
string str;
string file_contents;
while (std::getline(file, str))
{
if (str.find("Clan") == 0)
{
file_contents += str;
file_contents.push_back('\n');
}
}
cout << file_contents;
file.close();
}
I have a large .txt file and I want to read all of the words inside it and print them on the screen. The first thing I did was to use std::getline() in this way:
std::vector<std::string> words;
std::string line;
while(std::getline(std::cin,line)){
words.push_back(line);
}
and then I printed out all the words present in the vector words. The .txt file is passed from command line as ./a.out < myTxt.txt.
The problem is that each component of the vector is a whole line, and so I am not reading each word.
The problem, I guess, is the spaces between words: how can I tell the code to ignore them? More specifically, is there any function that I can use in order to read each word from a .txt file?
UPDATE:
I'm trying to avoid all the commas ., but also ? ! (). I used find_first_of(), but my program doesn't work. Also, I don't know how to set what are the characters I don't want to be read, i.e. ., ?, !, and so on
std::vector<std::string> my_vec;
std::string line;
while(std::cin>>line){
std::size_t pos = line.find_first_of("!");
std::string line = line.substr(pos);
my_vec.push_back(line);
}
'>>' operator of type string exactly fills your requirements.
std::vector<std::string> words;
std::string line;
while (std::cin >> line) {
words.push_back(line);
}
If you need remove some noisy characters, e.g. ',','.', you can replace them with space character first.
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
int main() {
std::vector<std::string> words;
std::string line;
while (getline(std::cin, line)) {
std::transform(line.begin(), line.end(), line.begin(),
[](char c) { return std::isalnum(c) ? c : ' '; });
std::stringstream linestream(line);
std::string w;
while (linestream >> w) {
std::cout << w << "\n";
words.push_back(w);
}
}
}
cppreference
The getline function, as it sounds, only returns a whole line. You can split each line on spaces after reading it, or you can read word by word using operator>>:
string word;
while (cin >> word){
cout << word << "\n";
words.push_back(word);
}
Use operator>> instead of std::getline(). The operator will read individual whitespace-separated substrings for you.
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> my_vec;
std::string s;
while (std::cin >> s){
// use s as needed...
}
However, you may still end up receiving strings that have punctuation in them without any surrounding whitespace, ie hello,world, so you will have to manually split those strings as needed, eg:
#include <iostream>
#include <string>
#include <vector>
#include <cctype>
std::vector<std::string> my_vec;
std::string s;
while (std::cin >> s){
std::string::size_type start = 0, pos;
while ((pos = s.find_first_of(".,?!()", start)) != std::string::npos){
my_vec.push_back(s.substr(start, pos-start));
start = s.find_first_not_of(".,?!() \t\f\r\n\v", pos+1);
}
if (start == 0)
my_vec.push_back(s);
else if (start != std::string::npos)
my_vec.push_back(s.substr(start));
}
No matching function for call to 'getline' when using this code:
ifstream myfile;
string line;
string line2;
myfile.open("example.txt");
while (! myfile.eof() )
{
getline (myfile, line);
getline (line, line2, '|');
cout<<line2;
}
In the example.txt i have info like this:
1|Name1|21|170
2|Name2|34|168
etc...
I really want to get the line till the | char...
I try few explode functions but they are only in string type but i need:
1st to be int
2nd to be char
3rd and 4th to be float.
It's really complicated that i want to do, and i can't explain it well. I hope someone will understand me.
getline receives as first argument an instance of the template basic_istream. string doesn't meet that requirement.
You could use stringstream:
#include <sstream>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string line;
string line2;
ifstream myfile("test/test.txt");
while (getline(myfile, line))
{
stringstream sline(line);
while (getline(sline, line2, '|'))
cout << line2 << endl;
}
return 0;
}