#include <iostream>
using namespace std;
int main()
{
bool result;
char text[1000];
cin>>text;
int len=sizeof(text);
for(int i = 0 ;i<len; ++i)
{
if(text[i]=='t' && text[i+1]=='r' && text[i+2]=='u' && text[i+3]=='e')
result = true;
else if(text[i]=='f' && text[i+1]=='a' && text[i+2]=='l' && text[i+3]=='s' && text[i+4]=='e')
result = false;
}
for(int i = 0 ;i<len; ++i)
{
if(text[i]=='n' && text[i+1]=='o' && text[i+2]=='t')
result = !result;// i think here is the problem
}
if(result == true)
cout<<"true"<<endl;
else if(result == false)
cout<<"false"<<endl;
return 0;
the exercise:
A boolean value can be either True or False. Given a string with less than 1000 characters with a number of space-separated not directives terminated by a True or False value, evaluate the boolean expression.
but when i run the program the result is always true.
please can you tell me where is the problem
Why don't you just use what is already there?
#include <iostream>
#include <iterator>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>
int main()
{
bool result;
// Read the line
std::string line;
std::getline(std::cin, line);
// Split the line at spaces (https://stackoverflow.com/a/237280/1944004)
std::istringstream iss(line);
std::vector<std::string> tokens{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};
// Convert last element to bool
if (tokens.back() == "true") result = true;
else if (tokens.back() == "false") result = false;
else throw std::invalid_argument("The last argument is not a boolean!");
// Remove the last element
tokens.pop_back();
// Loop over the nots
for (auto const& t : tokens)
{
if (t == "not") result = !result;
else throw std::invalid_argument("Negation has to be indicated by 'not'!");
}
// Output the result
std::cout << std::boolalpha << result << '\n';
}
Live example
Related
Is there an elegant way in C++ 11 to get the item from a std::vector of doubles which is closest to a certain value?
Code:
#include <iostream>
#include <vector>
double GetClosest(const std::vector<double>& vec, double value) {
// How to get the item closest to "value" from the items in vec. Vec is assumed to be sorted.
}
int main() {
std::vector<double> my_doubles_vec;
my_doubles_vec.push_back(101480.76915103197);
my_doubles_vec.push_back(101480.85708367825);
my_doubles_vec.push_back(101480.93293087184);
my_doubles_vec.push_back(101481.0027936101);
my_doubles_vec.push_back(101481.5625);
my_doubles_vec.push_back(101481.5626);
std::cout.precision(17);
std::cout << GetClosest(my_doubles_vec, 101480.76915103201) << std::endl; // Should output "101480.76915103197"
std::cout << GetClosest(my_doubles_vec, 101480.93293086279) << std::endl; // Should output "101480.93293087184"
std::cout << GetClosest(my_doubles_vec, 101481.5625) << std::endl; // Should output "101481.5625"
return 0;
}
Since its a std::vector of doubles, I think precision comes into play? Or can the logic be made in such a way that one doesn't need to bother about precision?
You could use std::partition_point, std::lower_bound or std::upper_bound on the sorted range.
Example:
#include <algorithm>
#include <cmath>
#include <stdexcept>
double GetClosest(const std::vector<double>& vec, double value) {
if(vec.empty()) throw std::runtime_error("no elements");
// partition_point is the most generic of the three:
auto it = std::partition_point(vec.begin(), vec.end(), [value](double v) {
return v < value;
});
// or auto it = std::lower_bound(vec.begin(), vec.end(), value);
// or auto it = std::upper_bound(vec.begin(), vec.end(), value);
if(it == vec.end()) --it; // value larger than the largest in the vector
else if( it != vec.begin()) { // value not less than first
// check which one of the two around the partition point that is closest
if(std::abs(*std::prev(it) - value) < std::abs(*it - value)) --it;
}
return *it;
}
Since the vector is sorted, you could try something like this:
#include <algorithm>
#include <cmath>
#include <stdexcept>
double GetClosest(const std::vector<double>& vec, double value) {
if (vec.empty()) throw std::invalid_argument("vector cant be empty");
if (vec.size() == 1) return vec[0];
auto iter = std::find_if(vec.begin(), vec.end(),
[=](double d){ return d >= value; }
);
if (iter == vec.begin()) return vec.front();
if (iter == vec.end()) return vec.back();
if (std::abs(value - *(iter-1)) < std::abs(value - *iter)) --iter;
return *iter;
}
I am reading text from a text file and need to know the number of characters in the file in total. I thought this should work but it always seems to be overcounting. For example I typed this into my text file:
thisisatestthisisa
thisisa
And the program returned a total of 32.
#include <iostream>
#include <fstream>
#include <string>
#include <ostream>
using namespace std;
int main() {
fstream inFile;
string inputString;
inFile.open("text.txt", ios::in);
unsigned int total = 0;
if (inFile) {
while (inFile)
{
getline(inFile, inputString);
unsigned int tempStringLength = inputString.length();
total += tempStringLength;
}
cout << "total is: " << total << endl;
}
else {
cerr << "Unable to open file text.txt";
exit(1);
}
return 0;
}
You are double-counting the last line in the file.
Because you are using while(inFile) instead of while(getline(inFile, inputString)) the stream's state is not invalidated until the call to getline(...):
Walking through the loop will make this obvious:
Iteration 1:
unsigned int total = 0;
//...
while (inFile) //True
{
getline(inFile, inputString); //inFile: True, inputString: thisisatestthisisa
unsigned int tempStringLength = inputString.length(); //18
total += tempStringLength; //18
}
//...
Iteration 2:
//...
while (inFile) //True
{
getline(inFile, inputString); //inFile: True, inputString: thisisa
unsigned int tempStringLength = inputString.length(); //7
total += tempStringLength; //25
}
//...
Iteration 3:
//...
while (inFile) //True
{
getline(inFile, inputString); //inFile: EOF, inputString: thisisa (not modified)
unsigned int tempStringLength = inputString.length(); //7
total += tempStringLength; //32
}
//...
inFile now returns false because the EOF was reached and your loop terminates. Printing 32 as the length.
Long story short: Don't use the file state as a loop terminator. Use the actual read, either getline or operator>> depending on the situation.
The program is supposed to receive a string, that can have blank lines, blank spaces, and break lines. So the problem is i can't use get line, because i don't know how many break lines the user will use.
I tried making a do while but it didn't work, the program stops working.
It was a do while, that would receive an char and using pushback insert in the string while the char was different to EOF. I don't know how else to do it, or why this do while doesn't work.
This code is using get line witch doesn't accept a break line.
'''''
#ifndef INDICE_H
#define INDICE_H
#include <cstddef>
struct Indice{
std::size_t f;
double p;
};
#endif
#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>
#include <map>
#include "Indice.hpp"
int main()
{
std::string str;
std::getline(std::cin, str);
// Count the number of occurrences for each word
std::string word;
std::istringstream iss(str);
std::map<std::string,Indice> occurrences;
while (iss >> word) ++occurrences[word].f;
//Calculate the percentual each word
int total = 0.0;
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
total += it->second.f;
}
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
it->second.p = (static_cast<double>(it->second.f))/total;
}
// Print the results
for (std::map<std::string,Indice>::iterator it = occurrences.begin();
it != occurrences.end(); ++it)
{
if(it->first.size()>2)
std::cout << it->first << " " << it->second.f << " "<< std::fixed << std::setprecision(2) << it->second.p << std::endl;
}
return 0;
}
''''
Two possible solutions:
#include <iostream>
#include <string>
int main(){
std::string line;
while(std::cin >> line){
//Variable line contains your input.
}
//Rest of your code
return 0;
}
Or:
#include <iostream>
#include <string>
int main(){
std::string line;
while(std::getline(std::cin, line)){
if (line.empty()){
break;
}
//Variable line contains your input.
}
//Rest of your code
return 0;
}
I have made a function for my program that reads from a text file, adds content to a vector and then search in that vector. The Problem is that even if the file is empty it shows that it found something, on the other side if i change return value to 0 it does not give results at all!
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
vector<string> contacts;
//This function returns at what index the name is found
int searchContact(string contactToSearch)
{
string entry;
ifstream input;
input.open("contacts.txt");
while (input.good())
{
while (getline(input, entry))
{
contacts.push_back(entry);
}
input.close();
}
for(int i = 0; i < contacts.size(); i++)
{
if(contactToSearch == contacts[i])
{
//Found => Returning index rest of program can see index
return i;
}
}
return 1;
}
I have just refactored your code a little. Further improvements are possible, but to begin with
1) You dont need a while for input.good()
2) You were trying to return 0 and 1 which are indeed valid positions where the string could have been present in the vector
All these aside, I still think your code might not properly populated the array The reasons for this maybe :- case sensitive comparison, reading incorrect file, binary file.. etc..
Here is a refactored code that you could use
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
void readContacts(const string &fileName inputFileName, vector<string> &contacts){
string entry;
ifstream input;
input.open(inputFileName);
if (input.good())
{
while (getline(input, entry))
contacts.push_back(entry);
input.close();
}
}
int searchContact(const string &contactToSearch, vector<string> &contacts)
{
for (int i = 0; i < contacts.size(); i++)
{
if (contactToSearch == contacts[i])
return i;
}
return -1;
}
int main(){
vector<string> contacts;
// This needs to be filled in with the contact name u want to search
string contactToSearch;
readContacts("contacts.txt", contacts);
int index = searchContact(contactToSearch, contacts)
if (index != -1)
cout << "Found Contact " << contactToSearch" at location " << index << endl;
else
cout << "Could Not find contact " << contactToSearch << endl;
}
I'm splitting a document by a string delimiter in C++.
This is a minimal Python code to demonstrate the problem. la is splitted by 'x' to get (a,b,b) and (c,d) (only the element between x, or between x and end of file is recorded)
la = ['a','x','a','b','b','x','c','d']
out = []
tmp = []
inside = False
for a in la:
if a == "x":
if inside:
out.append(tmp)
tmp = []
inside = True
continue
if inside:
tmp.append(a)
out.append(tmp)
for a in out:
print a
There is code duplication here for the last element out.append(tmp). How do I move it inside the loop?
(out.append(tmp) is actually some large code and it's prone to error to write in different places).
P/S: Since the actual code is in C++, no special function from python is allowed to call in solving the problem
A minimal C++ code, I'm reading from a stringstream:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main() {
// your code goes here
stringstream instream("a x b c d x c d");
vector<string> result;
string word, content;
while(getline(instream, word, ' ')) {
if (word == "x") {
result.push_back(content);
content = "";
continue;
}
content += word;
}
return 0;
}
Not sure why you would not just append outside the loop but you can check the length in the loop to catch the end elements:
out = []
tmp = []
for ind, ele in enumerate(la):
if ele == "x":
if tmp:
out.append(tmp)
tmp = []
elif ind == len(la) - 1:
tmp.append(ele)
out.append(tmp)
else:
tmp.append(ele)
You can use range in place of enumerate.
If you want to use continue you can remove the else:
for ind, ele in enumerate(la):
if ele == "x":
if tmp:
out.append(tmp)
tmp = []
continue
elif ind == len(la) - 1:
out.append(tmp)
tmp.append(ele)
I have zero experience with c++ but using stringstream.eof to catch the end of file might to do what you want:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
int main() {
// your code goes here
stringstream instream("x a x b c d x c d x");
vector<string> result;
string word, content;
while(true) {
getline(instream, word, ' ');
if (instream.eof()){
if (word != "x"){
content += word;
}
cout << content << "\n";
break;
}
if (word == "x") {
result.push_back(content);
cout << content << "\n";
content = "";
continue;
}
content += word;
}
return 0;
}
Output:
a
bcd
cd
You also need to handle the case where he first character is x where you would output an empty string