Removing words between < and > signs in a string c++ - c++

I'm not sure where to go from here. I know something needs to go after ifstr.get(c). It copies the exact words that I have in my text file called project.txt but I just need to remove any words that have the chars < or >?
Any help would be great. Thanks:)
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string line;
char c;
ifstream ifstr("project.txt");
ofstream ofstr("past.txt");
if(ifstr.fail()){
cout<<"error!"<<endl;
} // if
ifstr.get(c);
while(!ifstr.eof()) {
cout<<c;
ifstr.get(c);
ofstr<<line<<endl;
} // while
cout<<endl<<"copy complete"<<endl;
ifstr.close();
ofstr.close();
system ("pause");
return 0;
} // main

Pseudo-code (iostream-esque conditions) for the question in title (also removes the angle brackets):
char c;
while (read_char_succeeded(&c))
if (c == '<')
while (read_char_succeeded(&c) && c != '>')
;
else
write_char(c);

Just another shot in the dark:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
ifstream ifstr("project.txt");
ofstream ofstr("past.txt");
if(ifstr.fail()){
cout << "error!" << endl;
} // if
bool skipOutput = false;
do
{
string word;
ifstr >> word;
if(!word.empty() && word[0] == '<')
{
skipOutput = true;
}
if(!skipOutput)
{
ofstr << word << " ";
// replicate the output to stdout
cout << word;
}
if(word[word.length()-1] != '>')
{
skipOutput = false;
}
} while(!ifstr.eof());
cout << endl << "copy complete" << endl;
ifstr.close();
ofstr.close();
//system ("pause"); Doesn't compile with my system
return 0;
} // main
If you're really just want to filter out words enclosed within '<' and '>' characters this should be sufficient. If you have more complex parsing rules for your <> tags you should elaborate your question.

I'm not sure, that this is what you wanted. Please take a look at the code!
//we create a boolean value, to know if we started skipping
bool skipStarted = false;
while(ifstr.get(c))
{
//if its a '<' and we havent started skipping jet,
//then we start skipping, and continue to the next char.
if(c=='<' && !skipStarted)
{
skipStarted = true;
continue;
}
//if its a '>' and we started skipping,
//then we finish skipping, and continue to the next char.
if(c=='>' && skipStarted)
{
skipStared = false;
ifstr.get(c);
if(c==' ')
continue;
}
//if we are skipping, then we go to the next char.
if(skipStarted)
continue;
//otherwise we simply output the character.
ofstr<<c;
}

Related

Ignoring certain lines in a txt file when parsing

I want to read files from a txt file and compare some lines with regex.
The first line of the txt file should start with the string #FIRST.
And if the string should start with a '#' the line should be ignored and it should continue. So counter should have the value 1 which it does and it should go to the second if statement if(counter==1). However it doesn't go to the second if statement.
txt file:
#FIRST
#
#haha
I expect the output to be good\ngood after the code is run once.
The output is:
good.
And it should be
good.
good.
.........
#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <fstream>
#include <sstream>
int main() {
std::ifstream input("test.txt");
std::regex e("#FIRST");
std::regex b("haha");
int counter;
for (counter = 0; !input.eof(); counter++) {
std::cout << counter << "\n";
std::string line;
if (counter == 0) {
getline(input, line);
if (std::regex_match(line, e)) {
std::cout << "good." << std::endl;
counter++;
} else
std::cout << "bad." << std::endl;
break;
}
getline(input, line);
if (line[0] == '#')
continue;
if (counter == 1) {
getline(input, line);
if (std::regex_match(line, b)) {
std::cout << "good." << std::endl;
} else
std::cout << "bad." << std::endl;
break;
}
}
return 0;
}
The issue is with the break statement in the first if clause. After getting the first line of the input the program encounters the break statement and breaks out of the loop immediately. No further statements are executed within the for loop which I believe is the behavior you are seeing. You will have to restructure the program to be something like:
for loop {
getline()
if (counter == <>) {
// no break
} else if (line[0] == '#') {
continue;
} else {
// whatever else you want to get done
}
}

C++ program need lines words and characters count

I have an assignment where i need to count lines, words and characters from a file. I'm having a problem counting the right amount of characters and words since if it gets doubled space it counts like a character and a word.
the output should be
Example
lines words characters filename
3 5 29 testfile
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;
int main(int argc, const char * argv[]) {
string lines, words, chars, file1, file2;
ifstream infile;
ofstream outfile;
char c;
int countLines = 0;
int countChars = 0;
int countWords = 0;
cout<< "Enter the file name" << endl;
cin >> file1;
infile.open(file1.c_str());
while(!infile.eof())
{
if(infile.peek() == 1)
break;
c = infile.get();
if(c != '\n')
countChars++;
else
countLines++;
if(c == ' '|| c =='\n')
countWords++;
}
// countChars = countChars - countWords;
cout << setw(12) << countLines << setw(12) << countWords << setw(12) << countChars << endl;
infile.close();
return 0;
}
Use getline for reading file line by line
while(getline(file,str))
{
countLines++;
countChars += str.length();
countWords += CountWords(str);
}
Which file is an iofstream object and str is a string. And for counting number of words(CountWords), you have several ways. One of them is:
#include <vector>
#include <string>
#include <boost/algorithm/string/split.hpp>
int countWords(std::string str) {
vector< std::string > result;
boost::algorithm::split_regex(result, str, regex( "\\s+" ));
return result.size();
}
I believe OP's purpose to ask this question is to find out why his/her code is not working, therefore I will answer in this perspective.
counting the right amount of words
C++ define EOF(end of file) as -1, so include a check for EOF too, or you will miss a word count.
if it gets doubled space it counts like a character and a word.
You can use a boolean test to solve this, if you encountered a space, turn on the boolean, and skip if next char is a space, too.
I suppose your character count doesn't count in punctuation? so check for c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'. If your assignment count punctuation as character count too, ignore this point.
Below is a correct version code that is modified based on your code.
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;
int main(int argc, const char * argv[]) {
string lines, words, chars, file1, file2;
ifstream infile;
ofstream outfile;
char c;
bool findNextString = false;
int countLines = 0;
int countChars = 0;
int countWords = 0;
cout << "Enter the file name" << endl;
cin >> file1;
infile.open(file1.c_str());
while (!infile.eof())
{
if (infile.peek() == 1)
break;
c = infile.get();
// use the boolean to find next valid string
if (findNextString && c == ' ')
continue;
else
findNextString = false;
// there is a structure issue with your code.
// you should think of the priority of checking
// do not check by rejection, because you will count in punctuation too.
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
{
countChars++;
}
else if (c == '\n')
{
countLines++;
countWords++; // <- add word too
}
else if (c == ' ' || c == EOF)
{
countWords++;
findNextString = true;
}
}
cout << setw(12) << countLines << setw(12) << countWords << setw(12) << countChars << endl;
infile.close();
return 0;
}

Odd Cout Behavior

I'm sorry for the initial post. This is tested and reproducible.
I'm trying to get cout to work within a fstream while loop while detecting each character its parsing, but it's exhibiting an odd behavior with the Text getting overrided by the first variable that I'm trying to put into cout.
main.cxx
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using std::string;
using std::fstream;
using std::noskipws;
using std::cout;
int main(int argc, const char *argv[]){
char pipe;
string word; // stores the word of characters it's working on at the moment
string filename = "Directory.dat";
int type = 0; // 2 types counter, starts at 0
int newindicator = 0; // for detecting a new * for the data set
fstream fin(filename.c_str(), fstream::in);
while(fin >> noskipws >> pipe){
if(pipe == '*'){ // if the character is an asterisk
type++;
newindicator = 0;
word.clear();
}else if (pipe == '\n'){ // if the character is next line
if(newindicator == 0){ // tells the reader to know that it just finished reading a *, so it doesn't print anything.
newindicator = 1;
}else {
if(type == 1){
cout << "new word as: ";
cout << word << "\n";
}else if (type == 2){
cout << "new word as: ";
cout << word << "\n";
}
word.clear(); // clears the word string as it's reading the next line.
}
}else{
word+=pipe;
}
}
return 0;
}
Directory.dat
*
Chan
Johnathan
Joespeh
*
Betty
Lady Gaga
Output
Chanword as:
new word as: Johnathan
new word as: Joespeh
Bettyord as:
new word as: Lady Gaga
Note that how "Chan" is overriding the characters "new " on the first line, but it's fine after that. This seems to happen on every new type I'm doing, and when its recalling a new set of type. Same with Betty on the next set, which overrides "new w" with "Betty" on that cout.
Any feedback would be much appreciated. Thank you!
I suspect your input file has Windows line endings. These contain the carriage return character that's handled differently on Unix.
https://superuser.com/questions/374028/how-are-n-and-r-handled-differently-on-linux-and-windows
Thank you all for the comments and feedback. Made the changes as suggested:
Corrected
#include <string.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
using std::string;
using std::fstream;
using std::noskipws;
using std::cout;
int main(int argc, const char *argv[]){
char pipe;
string word; // stores the word of characters it's working on at the moment
string filename = "Directory.dat";
int type = 0; // 2 types counter, starts at 0
int newindicator = 0; // for detecting a new * for the data set
fstream fin(filename.c_str(), fstream::in);
while(fin >> noskipws >> pipe){
if(pipe == '*'){ // if the character is an asterisk
type++;
newindicator = 0;
word.clear();
}else if (pipe == '\n'){ // if the character is next line
if(newindicator == 0){ // tells the reader to know that it just finished reading a *, so it doesn't print anything.
newindicator = 1;
}else {
if(type == 1){
cout << "new word as: ";
cout << word << "\n";
}else if (type == 2){
cout << "new word as: ";
cout << word << "\n";
}
word.clear(); // clears the word string as it's reading the next line.
}
}else{
if (pipe != '\r'){
word+=pipe;
}
}
}
return 0;
}
Output
new word as: Chan
new word as: Johnathan
new word as: Joespeh
new word as: Betty
new word as: Lady Gaga

Presentation Error:Word Reversal

I have problem with this question I don't know what is wrong with my code that I get Presentation Error every time I don't know what is the format of output can you help me to solve this question I am sorry that my code is a little confusing
here is the link of question http://sharecode.ir/section/problemset/problem/1208
#include <iostream>
#include <string>
#include <algorithm>
#include <cstdio>
using namespace std;
int main()
{
string temp=" ";
bool cheak3=false,cheak4=false;
int n,num;
cin>>n;
while(n != 0)
{
if(cheak4 == true)
cout<<endl;
cheak4=true;
cin>>num;
cheak3=false;
string cheak1,cheak;
while(1)
{
if(num ==-1)
break;
getline(cin,temp);
for(int i=0 ; i<temp.size() ; i++)
{
if(temp[i] != ' ')
cheak.push_back(temp[i]);
else
{
reverse(cheak.begin(),cheak.end());
cheak1+=cheak;
cheak.clear();
if(cheak3 == true)
cheak1.push_back(' ');
}
}
reverse(cheak.begin(),cheak.end());
cheak1+=cheak;
cheak.clear();
num--;
if(cheak3 == true)
{
cheak1.push_back(' ');
cout<<cheak1<<endl;
cheak1.clear();
}
cheak3=true;
}
n--;
}
}
I believe the tricky part is you should print a blank line between the output blocks.
Your code has too complicated logic! Here is my solution to this problem:
#include <iostream>
#include <string>
using namespace std;
int main() {
int N, lines;
string word;
cin>>N;
while (N--) {
cin>>lines;
while (lines--) {
char end;
do {
cin >> word;
end = cin.get();
for (int i=word.length()-1;i>=0;i--) cout<<word[i];
cout << end;
} while (end != '\n');
}
if (N) cout << endl;
}
return 0;
}
The line if (N) cout << endl; makes sure you print a newline character for every output block except the last one (when N equals to 0).
After reading each word in a line, you can use cin.get(); in order to determine the next character. If it is a space, then print it and read the next word. Else if it is a \n print it and go to next line! :)

How to read until ESC button is pressed from cin in C++

I'm coding a program that reads data directly from user input and was wondering how could I read all data until ESC button on keyboard is pressed. I found only something like this:
std::string line;
while (std::getline(std::cin, line))
{
std::cout << line << std::endl;
}
but need to add a portable way (Linux/Windows) to catch a ESC button pressed and then break a while loop. How to do this?
EDIT:
I wrote this, but still - works even if I press an ESC button on my keyboard:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int ESC=27;
std::string line;
bool moveOn = true;
while (std::getline(std::cin, line) && moveOn)
{
std::cout << line << "\n";
for(unsigned int i = 0; i < line.length(); i++)
{
if(line.at(i) == ESC)
{
moveOn = false;
break;
}
}
}
return 0;
}
EDIT2:
Guys, this soulution doesn't work too, it eats the first char from my line!
#include <iostream>
#include <string>
using namespace std;
int main()
{
const int ESC=27;
char c;
std::string line;
bool moveOn = true;
while (std::getline(std::cin, line) && moveOn)
{
std::cout << line << "\n";
c = cin.get();
if(c == ESC)
break;
}
return 0;
}
int main() {
string str = "";
char ch;
while ((ch = std::cin.get()) != 27) {
str += ch;
}
cout << str;
return 0;
}
this takes the input into your string till it encounters Escape character
After you read the line, go though all characters you just read and look for the escape ASCII value (decimal 27).
Here's what I mean:
while (std::getline(std::cin, line) && moveOn)
{
std::cout << line << "\n";
// Do whatever processing you need
// Check for ESC
bool got_esc = false;
for (const auto c : line)
{
if (c == 27)
{
got_esc = true;
break;
}
}
if (got_esc)
break;
}
I found that this works for getting input for the escape key, you can also define and list other values in the while function.
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#define ESCAPE 27
int main()
{
while (1)
{
int c = 0;
switch ((c = _getch()))
{
case ESCAPE:
//insert action you what
break;
}
}
return 0;
}
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
int number;
char ch;
bool loop=false;
while(loop==false)
{ cin>>number;
cout<<number;
cout<<"press enter to continue, escape to end"<<endl;
ch=getch();
if(ch==27)
loop=true;
}
cout<<"loop terminated"<<endl;
return 0;
}
I would suggest that for not just ESC character in C++, but for any other character of the keyboard in any language, read characters that you input into an integer variable and then print them as integer.
Either that or search online for a list of the ASCII characters.
This will give you ASCII value of the key, and then it's plain simple
if(foo==ASCIIval)
break;
For the ESC character, the ASCII value is 27.