gcc and clang both cannot compile a loop program - c++

I've been unable to get gcc and clang to compile this simple program I've written for an exercise in a textbook. The objective of this program is to accept 2 simple integer values from standard input, and then print out the 2 values to standard output. The program I have written is as follows:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
inline void keep_window_open() {char ch; cin>>ch;}
int main()
{
vector<int> vect;
int number;
int i = 0 ;
while (cin >> number && vect.size() < 3)
{
vect.push_back(number);
}
cout << vect << '\n';
}
When I compile the program with gcc, I get the following error:
Kohs-MacBook-Pro:Learning_C++ Kohaugustine$ gcc drill_chapter_4_v2.cpp -o drill_chapter_4_v2 -stdlib=libstdc++ -lstdc++
drill_chapter_4_v2.cpp:21:8: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'vector<int>')
cout << vect << '\n';
~~~~ ^ ~~~~
The same error "invalid operands to binary expression" also happens when I try using clang.
Does anyone know what exactly is the problem here?
I'm really new to C++ and although I previously had experience with Python, moving to C++ is so different, and I've yet to take any formal introductory courses in programming, so please bear with me if this is a very simple problem. I would greatly appreciate any help to move forward!
Thank you!

You can't print an entire vector like that. Use a loop:
for (auto value : vect)
std::cout << value << ' ';

There is no operator<<(std::ostream, std::vector<int>) in the C++ standard library.
One could write one, such as this:
std::ostream& operator<<(std::ostream& os, std::vector<int> v)
{
for(auto i : v)
{
os << i << ' ';
}
return os;
}
I should point out that iterating over the vector in situ is the typical solution, so:
for(auto i : vect)
{
std::cout << i << ' ';
}
would be what I expect to see in the code.

Change this part of the code
while (cin >> number && vect.size() < 3)
{
vect.push_back(number);
}
cout << vect << '\n';
the following way
while ( vect.size() < 3 && cin >> number )
{
vect.push_back( number );
}
for ( int x : vect ) cout << x << '\n';
As for the error then there is no operator << for vectors. Either you should define it yourself or print out each element of a vector yourself using as shown above for example the range based for loop.

Related

C++ program behaviour differs when compiled with Cygwin and MinGW

I am fairly new to C++ and have been tinkering with some simple programs to teach myself the basics. I remember a little while ago installing MinGW on my desktop (I think for the C compiler). I decided to go for Cygwin for C++ and it seems to have been working a treat, up until I noticed that it seems to behave differently from the MinGW compiler for this program. I'm probably breaking some coding golden rule, but the reason for this is that Windows CMD uses the MinGW compiler, or I can open the Cygwin shell and use that instead. Variety!
For the program below, I am making notes on the ternary operator and switch statement. I initialize 'a' and 'b', ask for user input, and then use a function to check which is larger.
I then ask for user input again, to over-write the values in 'a' and 'b' to something else. When compiling from Windows CMD, this works fine and I can overwrite with new input, and the #define MAXIMUM and MINIMUM functions work fine on the new values. When I compile on Cygwin, however, after the first 'pause', the program launches past the two std::cin's and just runs MAXIMUM and MINIMUM on the old values of 'a' and 'b'.
Obviously I have tried just creating two new int variables, 'c' and 'd', and then there is no issue. The values are not immutable in any sense that I am aware of (although I don't know much, so I could be wrong).
I wasn't sure if this was something to do with the auto keyword, so I specified the type as int manually.
I also checked the version of both compilers with 'g++ -v' in Cygwin and at the CMD.
#include <iostream>
#include <cstdlib>
#define MAXIMUM(a,b) ((a > b) ? a : b)
#define MINIMUM(a,b) ((a < b) ? a : b)
int ternary_op(int a, int b)
{
char x = 'a';
char y = 'b';
auto result_var = 0;
result_var = a > b ? x : y; //Shorthand if statement with syntax (test_condition) ? (if_true) : (if_false)
return result_var;
}
int main()
{
auto a = 0;
auto b = 0;
auto larger = 0;
auto smaller = 0;
std::cout << "Enter an integer: " << "\n";
std::cin >> a;
std::cout << "Enter another integer: " << "\n";
std::cin >> b;
char greater_var = ternary_op(a,b); //Therefore if condition a > b is satisfied, greater_var is assigned x ('a')
std::cout << greater_var << std::endl;
switch(greater_var){
case 'a':
std::cout << "First integer " << a << " is larger than second, " << b << std::endl;
break;
case 'b':
std::cout << "Second integer " << b << " is larger than first integer, " << a << std::endl;
break;
}
std::cout << system("cmd /c pause") << std::endl;
std::cout << "We can also use defined functions to check equivalency and assign variables based upon the result." << "\n";
std::cout << "Enter an integer: " << std::endl;
std::cin >> a;
std::cout << "Enter another integer: " << std::endl;
std::cin >> b;
larger = MAXIMUM(a,b);
smaller = MINIMUM(a,b);
std::cout << "Larger and smaller numbers determined by defined function: " << larger << ", " << smaller << std::endl;
std::cout << system("cmd /c pause") << std::endl;
return 0;
}
Obviously if I make two new variables, 'c' and 'd', there is no issue. Changing the type to int myself did not change the way the program behaved using Cygwin. Unusually the MinGW version was 8.1.0, while Cygwin was 7.4.0. I'm not sure if this means that it is simply an older version of the same compiler.
Again, I'm very new to this so I'm just quite confused as to why they would behave so differently. I was also under the impression that different compilers were completely different beasts that simply read from the same standard hymn sheet, so to speak.
Just curious as to what is going on here!
Cheers!

Using a variable in a for loop, causing segfault [duplicate]

This question already has an answer here:
Why does this simple C++ code segfault? [closed]
(1 answer)
Closed 3 years ago.
I'm practicing operator overloading, and my goal is to enumerate all the values of a vector class I have written myself.
In doing this I came across a segfault (no biggie) and started to pare back my code to find where it originated. After some difficulty, I've come to a point where I don't understand what's going wrong.
While trying to run a for loop to iterate over the data in a vector object, I found that I get a segfault if I use a variable s which is set to 10. If I use the integer literal 10, it works.
This makes very little sense to me, but then again I'm working with unfamiliar concepts. Any help is appreciated!
Here's an MCVE:
Compile using g++ Q1.cpp vector.h -o Q1
Demo class (Q1.cpp):
#include <iostream>
#include "vector.h"
#define INFO(x) std::cout << "[INFO]: " << x << std::endl;
int main(void) {
// 1- Test the default constructor
INFO(" ---------- Vector 1 ----------");
vector v1;
INFO(v1);
return 0;
}
Vector class (vector.h):
#include <iostream>
#include <string>
class vector {
public:
float size;
float* data;
vector() : vector(0) {}
vector(int s){
size = s;
data = new float[size]();
}
};
std::ostream& operator<<(std::ostream& stream, const vector& obj){
stream << "vector: size(" << obj.size << ")" << "\n";
int s = 10;
for(int i = 0; i < s; ++i){ // problem occurs here, replace s with '10' and it works.
stream << i;
//stream << "data[" << i << "] = " << obj.data[i];
}
}
Your overloaded function needs to return stream.
Also, don't use size_t as a class member name. It's utterly confusing.
You should also delete the data array when the vector is deleted. It now leaks.

parse issue:Expected unqualified-id and semantic issue:C++ requires a type specifier for all declarations

It's quite funny that it keeps f'ing me while I've put everything right.!
It keeps giving me same issues all the time and I can't figure out what's going on anymore. I'm like so done, I've rewritten everything and still all kinds of errors keep popping up. I know that this is part of the programming that you can't just succeed all at once, you always have at some point struggle for hours with random kinds of errors. I was wishing I could get response from someone who've seen this before, as I'm quite inpatient person, I get fed-up quite easily by stuff like this, especially when I'm starting up at something like this.
// This program demonstrates the xor() function.
#include <iostream>
using namespace std;
bool xor(bool a, bool b);
int main()
{
bool p, q;
cout << "Enter P (0 or 1): ";
cin >> p;
cout << "Enter Q (0 or 1): ";
cin >> q;
cout << "P AND Q: " << (p && q) << '\n';
cout << "P OR Q; " << (p || q) << '\n';
cout << "P XOR Q: " << xor(p, q) << '\n';
return 0;
}
bool xor (bool a = bool b)
{
return (a || b) && !(a && b);
}
Screenshot
xor is not allowed as an identifier, it is an alternative token for ^.

Calling function in C++

I'm trying to call a function with no return type but it doesn't seem to be getting called.
The code looks something like this(summarized):
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int ItemsInQuestion[4];
void GetQuestions(int NumQuests);
int main()
{
int NumberOfQuestions = 0;
srand((unsigned)time(NULL));
cout << "How many questions would you like?" << endl;
cin >> NumberOfQuestions;
cout << NumberOfQuestions << " questions will be asked.";
GetQuestions(NumberOfQuestions);
system ("PAUSE");
return 0;
}
void GetQuestions(int NumQuests)
{
for(int Questions=NumQuests; Questions>NumQuests; Questions++)
{
ItemsInQuestion[0]=(rand()%(263))+1;
ItemsInQuestion[1]=(rand()%(263))+1;
ItemsInQuestion[2]=(rand()%(263))+1;
ItemsInQuestion[3]=(rand()%(263))+1;
cout << ItemsInQuestion[0] << ' ' << ItemsInQuestion[1] << ' ' <<ItemsInQuestion[2] << ' ' << ItemsInQuestion[3];
}
}
The line that outputs the values in the array never comes up. What is causing this?
Because
int Questions=NumQuests;
and
Questions>NumQuests;
don't like each other.
You set Questions to NumQuests and then tell the loop to keep going as long as Questions is strictly greater than NumQuests, which it isn't to start off with.
Even if it was, you'd soon run into an overflow and undefined behavior.
This is not the way of using for-loops :
for ( __Initialization, __Condition, __Increment)
As Grigore pointed out in his answer, your initialization is wrong. As Questions=NumQuest, the statement Questions>NumQuests is false from the beginning, and your code is equivalent to
for ( ; 1<1 ; ) // I'm a lazy loop, I'm ugly and useless
There is an infinite number of way to do what you want :
// Direct : 0, 1, 2, .. NumQuest-1.
for (int Questions=0 ; Questions < NumQuests ; Questions++)
{ ... }
// Reverse : NumQuest, ..., 2, 1.
for (int Questions=NumQuests ; Questions > 0 ; Questions--)
{ ... }

Formatting C++ output problem

Let me examplify my problem , I've a function like:
void printer(int width, int hight){
for(int i=0;i<width;++i) std::cout<<" & ";
for(int i=0;i<hight;++i) std::cout<<" ^ ";
std::cout<<std::endl;
}
my problem is function printer should always output of both for loop in same width
e.g:
output could look (width 5):
&^
&&&^
or there is anyway that i print any of (from above code) for loop's output in constant width independent of no of times for loop executes
Question is unclear. Are you looking for something like the following ?
void printer(int amps, int carets, int overallWidth){
for (int i = amps + carets; i < overallWidth; i++) std::cout<<" "; // leading padding
for (int i=0;i<amps;++i) std::cout<<"&";
for (int i=0;i<carets;++i) std::cout<<"^";
std::cout<<std::endl;
}
The change was just to add a loop for outputting the padding. (also changed the parameters name for clarity)
printer(1,1,5);
printer(3,1,5);
would then produce the output shown in example
&^
&&&^
and of course, rather than being passed as a parameter, the overallWidth variable could be hardcoded; an implicit constant of the printer() function.
Edit:
The snippet above stayed very close to that of the question. There are however more idiomatic approaches, for example the following "one liner", which uses one of the string constructor overloads to produce the strings of repeated characters, and iomanip's setw() to produce the padding.
void printer(int amps, int carets, int overallWidth){
std::cout << setiosflags(ios::right) << setw(overalWidth)
<< string(amps, '&') + string (carets, '^')
<< std::endl;
}
Look into <iomanip>. Using cout you can specify a width.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << setiosflags(ios::left) << setw(10) << "Hello"
<< setiosflags(ios::right) << setw(20) << "World!";
return 0;
}