I'm trying to under the parse function for creating a formatter for a custom type in fmt. In their documentation (https://fmt.dev/dev/api.html) there is this line that has some sort of loop construct I haven't seen before:
auto it = ctx.begin(), end = ctx.end();
if (it != end && (*it == 'f' || *it == 'e')) presentation = *it++;
It's obviously a loop using iterators, presumably something new in C++17. What is it? Full example here: https://godbolt.org/z/fEGvaj
The formatter::parse function takes a parse context ctx and checks if the range [ctx.begin(), ctx.end()) contains format specifiers f or e in this example.
if (it != end && (*it == 'f' || *it == 'e')) presentation = *it++;
^ ^ ^
check if the check if the first
range is empty character is 'f' or 'e'
There is nothing particularly novel here, this code is compatible with C++98.
Related
Trying to test if input is "TF" or "MC". The while condition keeps coming out as true even though argument is written: line != "TF" || line != "MC"
Not understanding how the loop keeps repeating even though I input TF or MC. I have also verified that the tranform method is making the string capital.
do {
cout << "\nEnter the Question type (TF) for True/False or (MC) for Multiple Choice:\n";
getline(cin, line);
transform(line.begin(), line.end(), line.begin(), ::toupper);
} while (line != "TF" || line != "MC");
I expected the loop to only initiate once and exit.
If the person types "MC", the expression
line != "TF"
will be set to true, which will make the OR statement true.
(And thus repeating the while even though the person typed a valid answer)
What you are looking for is to check if the answer is neither one of the options, which can be checked as follows:
(line != "TF" && line != "MC")
The opposite would be reasonable too. That is, to check if the person typed a valid answer, and keep repeating it while it is not the case:
while(!(line == "TF" || line == "MC"))
Both statements are equivalent, as stated in the comments, by the De Morgan's Laws.
This might be overkill, but it does explain the relationships between the OR, AND, and NOT operators: https://en.wikipedia.org/wiki/Boolean_algebra
I'm trying to recreate a program in my textbook, with the syntax shown below. However when I add in the line for detecting tabs [if ((c=' ' || c='\t'] (and the inverted version above , and printing only one tab at once, it shifts the entire text a few more'tabs' to the left. If I delete mentions of tabs, it works perfectly with blanks. Hope this helps.
I tried to do this question before from my book, but ended up focusing on answers from this site (https://clc-wiki.net/wiki/K%26R2_solutions:Chapter_1:Exercise_9) For being concise, I won't post the code that worked best, but it's the one at the very bottom of the page if you want to consult it. Afterwards I changed my sight towards a code (a part of it is listed below), which let be able to answer the Q with tabs also which which wasn't originally in the Q.
int main(void)
{
int c, p;
p = 0;
while ((c = getchar()) != EOF)
{
if (c != ' ' || c!= '\t')
{
putchar(c);
p= 0;
}
if ((c == ' ' || c== '\t') && p<1)
{
putchar(c);
p++;
}
} if (c == '\n')
p = 0;
}
______________________________________________________________________________Another example from the site I listed, which I thought syntax was concise and interesting.
while ((c = getchar()) != EOF)
{ if (c == ' ' || c == '\t')
{ while ((c = getchar()) == ' ' || c == '\t')
No error messages come up, but in an instance like ' [tab][tab]hello world
, I expect' [tab]hello world'. But somehow I get '[tab][tab][tab][tab]hello world. It seems to increase the output by 2x including both tabs and blanks.
The problem is on this line here:
if (c != ' ' || c!= '\t')
Let's look at three cases:
c == ' ' is true. This means that c != '\t' is also true, so the if statement executes.
c == '\t' is true. This means that c != ' ' is also true, so the if statement executes.
c is neither of those. This means that c != ' ' is true, so the if statement executes.
In every possible case, the if statement executes.
Proposed solution: Re-write it as
if (c != ' ' && c != '\t')
using '&&' instead of '||'.
Since your first if statement will always evaluate to true putchar will be called the first time and p will be set to 0. Since p is 0 the 2nd if statement will always be true. This will call putchar a 2nd time. You may want to use isspace(). It will check for white-space characters.
I am now trying to explore pascal. And I ran into some compiler errors. I wrote a if else if statement like this:
if ((input = 'y') or (input = 'Y')) then
begin
writeln ('blah blah');
end;
else if ((input = 'n') or (input = 'N')) then
begin
writeln ('blah');
end;
else
begin
writeln ('Input invalid!');
end;
And it gives me an error at the first else:
";" expected but "ELSE" found
I looked for a lot of tutorials about if statements and they just do it like me:
if(boolean_expression 1)then
S1 (* Executes when the boolean expression 1 is true *)
else if( boolean_expression 2) then
S2 (* Executes when the boolean expression 2 is true *)
else if( boolean_expression 3) then
S3 (* Executes when the boolean expression 3 is true *)
else
S4; ( * executes when the none of the above condition is true *)
I tried to delete the begin and end but the same error occured. Is this a compiler bug?
P.S. I am doing this in a case statement. But I don't think it matters.
; is not allowed before else in the majority of cases.
if ((input = 'y') or (input = 'Y')) then
begin
writeln ('blah blah');
end
else if ((input = 'n') or (input = 'N')) then
begin
writeln ('blah');
end
else
begin
writeln ('Input invalid!');
end;
will compile.
But... Prefer using begin ... end brackets to avoid misunderstanding of code in complicated if then else statements.
something like this will be better:
if ((input = 'y') or (input = 'Y')) then
begin
writeln('blah blah');
end
else
begin
if ((input = 'n') or (input = 'N')) then
begin
writeln('blah');
end
else
begin
writeln('Input invalid!');
end;
end;
The second sample is much easier to read and understand, isn't it?
The code does not work when you remove begin and end because there is a semicolon before else. This will compile without errors:
if ((input = 'y') or (input = 'Y')) then
writeln('blah blah')
else
begin
end;
Appended on comment of #lurker
Please, see the following example without begin ... end brackets.
if expr1 then
DoSmth1
else if expr2 then
if expr3 then
DoSmth2
else
DoSmth3;//Under what conditions is it called?
It is not clearly seen here, if DoSmth3 is called on not (expr2) or (expr2) and (not (expr3)). Though we can predict the compiler behaviour in this sample, the more complicated code without begin ... end becomes subect to mistakes and is difficult to read. See the following code:
//behaviour 1
if expr1 then
DoSmth
else if expr2 then
begin
if expr3 then
DoSmth
end
else
DoSmth;
//behaviour 2
if expr1 then
DoSmth
else if expr2 then
begin
if expr3 then
DoSmth
else
DoSmth;
end;
Now the code behavior is obvious.
I have a string vector of user-input data containing strings. Now I need to make sure program won't execute if strings are different than specified few. Vector contains 4 fields and every has different condition:
vector[0] can only be "1" or "0"
vector[1] can only be "red" or "green
vector[2] can only be "1", "2" or "3"
vector[3] can only be "1" or "0"
I tried writing if for every condition:
if(tokens[0]!="1" || tokens[0]!="0"){
decy = "error";
}
else if(tokens[1]!="red" || tokens[1]!="green"){
decy = "error";
}
else if(tokens[2]!="1" || tokens[2]!="2" || tokens[2]!="3"){
decy = "error";
}
else if(tokens[3]!="1" || tokens[3]!="0"){
decy = "error";
}
else{
switch(){} //working code
}
return decy;
It always enters first if and returns error. I tried with if instead of else if but it doesn't work either. I checked vector[i] contents and it returns correct strings. No " " at the end of it etc. Removing else and releasing switch just makes program check first condition and ignore rest of it.
I'm probably doing something terribly wrong, but I can't find an answer on internet so I decided to ask here.
This line:
if(tokens[0]!="1" || tokens[0]!="0")
should be:
if(tokens[0]!="1" && tokens[0]!="0")
^^
The same goes for the rest of the if statements as well.
The conditions are invalid.
Any distinct value can satisfy your conditions.
You should use && instead of ||.
For example:
if (tokens[0] != "1" || tokens[0] != "0") {
Consider this line. If tokens[0] is "1", which is valid input, it will not satisfy the first condition, but it will satisfy the second. You only want to throw an error when the value is neither of the valid possible inputs.
This means that your condition should be:
if (tokens[0] != "1" && tokens[0] != "0") {
Same goes for all the others.
You should turn those || into &&. If the input can only be X or Y, this means that it is illegal when it is not X and not Y:
if (tokens[0] != "1" && tokens [0] !="0")
// ^^
The first if:
if(tokens[0]!="1" || tokens[0]!="0")
ALWAYS evaluates to true.
How would I look through a string for a word rather then each character in that word. I have my code here and it always seems to find everything that is .obj even if its o or b or j or "." I checked the docuementation here but was unable to find an answer. Here is my code:
string &str = *it;
if(it->find(".obj"))
{
cout << "Found .Obj" << endl;
}
I also tried to use string::compare but that failed.
find does search for the full text string that you pass as the function argument. What you're misunderstanding is the return value; find doesn't return true or false for whether or not it found the string you requested; it returns the index in the string where it found your requested substring, or std::string::npos if no match was found.
So for example:
std::string a = "foobar.obj";
std::string b = "baz.obj";
std::string c = "qux";
std::string d = ".obj";
a.find(".obj") == 6
b.find(".obj") == 3
c.find(".obj") == std::string::npos // not found
d.find(".obj") == 0
When interpreted as a boolean value, any integer other than 0 is treated as "true" -- even the "not found" std::string::npos value. Which is, I think, what has you confused.
So in your "if" statement, then, instead of:
if (it->find(".obj"))
You want to be testing:
if (it->find(".obj") != std::string::npos)