Filter input received by getline [closed] - c++

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
#include <iostream>
#include <string>
#include <cstring>
#include <fstream>
using namespace std;
int main() {
string firstFile, secondFile, temp;
ifstream inFile;
ofstream outFile;
cout << "Enter the name of the input file" << endl;
cin >> firstFile;
cout << "Enter the name of the output file" << endl;
cin >> secondFile;
inFile.open(firstFile.c_str());
outFile.open(secondFile.c_str());
while(inFile.good()) {
getline(inFile, temp, ' ');
if ( temp.substr(0,4) != "-----"
&& temp.substr(0,5) != "HEADER"
&& temp.substr(0,5) != "SUBID#"
&& temp.substr(0,5) != "REPORT"
&& temp.substr(0,3) != "DATE"
&& temp != ""
&& temp != "")
{
outFile << temp;
}
}
inFile.close();
outFile.close();
return 0;
}
Hi All. I'm attempting to output all lines from a text file that do not meet the criteria in the control structure -- i.e. no blank lines, no symbols, etc. However, when I run this code it outputs everything, not taking into consideration my specifc requirements. If anyone could tell me what I'm doing wrong it would be greatly appreciated.

If you look at a reference such as this you will see that the second argument to substr is the number of character not the ending position.
This means that e.g. temp.substr(0,5) might return "HEADE" which is indeed not equal to "HEADER". This means that all non-empty string will be output.
Also note that right now, you don't actually read lines but words as you separate the input on space.

When you repeat the same action multiple times, that's a sign you need a function:
bool beginsWith( const std::string &test, const std::string &pattern )
{
if( test.length() < pattern.length() ) return false;
return test.substr( 0, pattern.length() ) == pattern;
}
First of all you can test it separately, then your condition will be much simplier and less error prone:
if ( !beginsWith( temp, "-----" )
&& !beginsWith( temp, "HEADER" )
&& !beginsWith( temp, "SUBID#" )
&& !beginsWith( temp, "REPORT" )
&& !beginsWith( temp, "DATE" )
&& temp != "" )

Short version (C++11):
const std::vector<std::string>> filter {
{"-----"}, {"HEADER"}, ... }; // all accepted line patterns here
while(getline(inFile, temp)) {
for(const auto& s: filter)
if (s.size() == temp.size() &&
std::equal(s.begin(), s.end(), temp.begin()))
outFile << temp;

Related

C++ code to find and modify/replace a string in .c file [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
My task is to search for a string in .c file and modify it using c++ code. Iam done till searching for the string but modifying it is giving an error. It gives the same error if i copy the contents of c file to a text file and try to modify it. So iam sure something is wrong with my code. Please help as iam a beginner. Thanks in advance.
My code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string s1, s2;
ifstream test("test.csv");
while (test.eof()==0) //test.eof() returns 0 if the file end is not reached
{
getline(test, s1, ','); //reads an entire line(row) till ',' to s1
getline(test, s2, '\n');
cout << s1 + "= " +s2 << endl;
fstream fileInput;
int offset;
string line;
string search=s1;
fileInput.open("IO_CAN_0_User.c");
if(fileInput.is_open()) {
while(!fileInput.eof()) {
getline(fileInput, line);
if ((offset = line.find(search, 0)) != string::npos) {
cout << "found: " << search << endl;
string str;
str=search;
str.replace(str.begin()+25,str.begin()+31,"=s2 //");
break;
}
}
//cout << "string not found" << endl;
fileInput.close();
}
else cout << "Unable to open file.";
if(test.eof()!=0)
cout<<"end of file reached"<<endl;
getchar();
return 0;
}
}
The error your are facing is not clear, but I can see one big issue, your running replace on an empty string.
Your code:
string str;
search=str;
str.replace(str.begin()+25,str.begin()+31,"=s2 //");
You create str (by default initialized as empty string), assign it to search (therefore this string gets empty) and then you call replace trying to change from char 25 to 31, which are not there since the str is empty.
Update
Probably you need to fix the replace, but then you cannot expect the file to change: the string you are modifying is in memory, not a piece of your file.
Therefore I would change the code (using yours as much as possible):
* Adding output file
* Fixing the replace
* Saving every line of the input file (replacing if need) on the output
fileInput.open("IO_CAN_0_User.c");
ofstream fileOutput;
fileOutput.open("output.c");
if(fileInput.is_open() && fileOutput.is_open() ) {
while(!fileInput.eof()) {
getline(fileInput, line);
if ((offset = line.find(search, 0)) != string::npos) {
cout << "found: " << search << endl;
line.replace( offset, offset+search.size(), s2 );
}
fileOutput << line << '\n';
}

Split string which components need to be written in a vector [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
My problem sounds like this: I have as a input a huge string with numbers separated by whitespaces. I need to split this string and put the components in a vector and then to use its components. (then to transform to integers bla bla...).
I searched here for this but I did not understand some things entirely, so please a bit of explanation.
Also another question: why the following return one more "Substring: " in the end?
int main()
{
string s("10 20 30 50 2000");
istringstream iss(s);
while (iss)
{
string sub;
iss >> sub;
cout << "Substring: " << sub << endl;
}
system("pause");
return 0;
}
why the following return one more "Substring: " in the end?
Because your loop is broken; you're checking the stream state before reading from it. It's the same problem as described under:
Why is iostream::eof inside a loop condition considered wrong?
First count the amount of whitespaces like this:
int i = counter;
for( size_t i = 0; i < s.size(); ++i )
{
if( ' ' == s[i] )
{
++counter;
}
}
After that you have to substring in another for loop the string s.
Try the following approach
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
int main()
{
std::string s( "10 20 30 50 2000" );
std::istringstream is( s );
std::vector<std::string> v( ( std::istream_iterator<std::string>( is ) ),
std::istream_iterator<std::string>() );
for ( const std::string &t : v ) std::cout << t << std::endl;
return 0;
}
The output is
10
20
30
50
2000
You could initially define the vector as having type std::vector<int> and in the vector initialization use iterator std::istream_iterator<int>.
As for your second question then before outputing a string you have to check whether it was read. So the correct loop will look like
string sub;
while ( iss >> sub )
{
cout << "Substring: " << sub << endl;
}

Why does unsigned variable contain wrong value [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am attempting to grab ID's from an text file with HTML in it. The ID's are being extracted from URL's in the HTML so I'm looping through the file to find the correct line and then using substrings obtain the correct information. There are two different types of ID so I have two different functions.
The second one (getYearId) works fine, but the first one causes the code to abort on the part that is currently commented out. As you can see, I've tried to output the value of first1 only to find that it's output is alue=", which is part of what I'd assume first was supposed to equal. What am I doing wrong?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
void getSyllabiId() {
string line;
ifstream myfile("syllabi.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
if (line.find("View Assignments") != string::npos) {
string startDel = "syllabusid";
string endDel = "View";
unsigned int first1 = line.find(startDel);
unsigned int last1 = line.find(endDel);
cout << first1 + "\n";
//string syllabusID = line.substr(first1, last1 - first1);
//syllabusID = syllabusID.substr(startDel.size());
// cout << syllabusID + "\n";
}
}
myfile.close();
}
else cout << "Unable to open file.";
}
void getYearId() {
string line;
ifstream myfile("syllabi.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
if (line.find("2014-2015</option>") != string::npos) {
string startDel = "value=\"";
string endDel = "\" selected";
unsigned int first = line.find(startDel);
unsigned int last = line.find(endDel);
string yearID = line.substr(first, last - first);
yearID = yearID.substr(startDel.size());
cout << yearID + "\n";
}
}
myfile.close();
}
else cout << "Unable to open file";
}
int main () {
getYearId();
getSyllabiId();
string x;
cin >> x;
return 0;
}
The problem was I never checked to see if first1 and last1 had values, so obviously in one (or several instances) one of them didn't causing the code to abort.

C++ multiple line input from keyboard

For an assignment of mine, we're suppose to take in several lines of input from the keyboard. For example:
Please enter your name: (this is static. Always 1 input)
Justin
Please enter the names: (this can be any number of inputs, smallest being 1)
Joe
Bob
John
Jackson
In the end, I want to compare the named entered at the beginning with all of the names entered in after. I tried using getline and cin, but that seems to only work if I know the exact number of names I expect to be entered. Can anyone guide me in the right direction please. Thank you
Try this
void read_lines( std::istream& in, std::list< std::string >& list ) {
while( true ) {
std::string line = "";
std::getline( in, line );
if( line != "" ) {
list.push_back( line );
} else {
break;
}
}
}
You should have added some rough code showing your efforts on doing the assignment.
However, I will provide you with some initial naive code (please read the comments inside!):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string name, temp;
vector<string> names; // this is just one of the possible container that you can use
bool result = false; // flag used to store the result of the matching operation (default: false)
// first we ask the user to enter his/her name
cout << "Please enter your name:" <<endl;
cin >> name;
// then we need something a little bit more complicated to look for variable number of names
cout << "Please enter the names:" <<endl;
while(cin)
{
cin >> temp;
names.push_back(temp);
}
// This for-loop is used to go through all the input names for good-match with the user name
for( int i = 0; i < names.size(); i++ )
{
temp = names.front();
if (name == temp) result = true; // change the flag variable only in case of match
}
cout << "Valid match: " << (result?"yes":"no"); // ternary operator
}
You did not provide in your question enough details.. so the above code may not fully fit your requirements!

Splitting a string using a single delimeter [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Splitting a string in C++
I'm trying to split a single string object with a delimeter into separate strings and then output individual strings.
e.g The input string is firstname,lastname-age-occupation-telephone
The '-' character is the delimeter and I need to output them separately using the string class functions only.
What would be the best way to do this? I'm having a hard time understanding .find . substr and similar functions.
Thanks!
I think string streams and getline make for easy-to-read code:
#include <string>
#include <sstream>
#include <iostream>
std::string s = "firstname,lastname-age-occupation-telephone";
std::istringstream iss(s);
for (std::string item; std::getline(iss, item, '-'); )
{
std::cout << "Found token: " << item << std::endl;
}
Here's using only string member functions:
for (std::string::size_type pos, cur = 0;
(pos = s.find('-', cur)) != s.npos || cur != s.npos; cur = pos)
{
std::cout << "Found token: " << s.substr(cur, pos - cur) << std::endl;
if (pos != s.npos) ++pos; // gobble up the delimiter
}
I'd do something like this
do
{
std::string::size_type posEnd = myString.find(delim);
//your first token is [0, posEnd). Do whatever you want with it.
//e.g. if you want to get it as a string, use
//myString.substr(0, posEnd - pos);
myString = substr(posEnd);
}while(posEnd != std::string::npos);