Search code examples
c++compiler-errorsmingw-w64iomanip

no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::_Setfill<const char*>')


I just started learning cpp in my school. I was trying to do this thing:

Please follow the format of the output example to output the design and color of NxN twill floor tiles.

Note: The design and color of the twill floor tiles are like this. Firstly, each grid on the diagonal line from the upper left to the lower right is an '@' symbol, and the diagonal line is shifted to the left and right by three grids, that is, the interval is two The pattern on the line after the grid is also '@', and then continue to repeat on both sides until it exceeds the range of the floor tiles. Where there is no '@' pattern, it is represented by a '-' symbol.

EXAMPLE =
INPUT
10

OUTPUT
@--@--@--
-@--@--@-
--@--@--@
@--@--@--
-@--@--@-
--@--@--@
@--@--@--
-@--@--@-
--@--@--@

I tried to use setw and setfill, heres my code:

#include<iostream>
#include<iomanip>
#include<string>
using namespace std;

int main(){;
    int a,i,n;
    cin >> a;
    n=a;

    for(i=1;i<=a;i++){
        cout<<setw(a);
        if(n==1||(n-1)%3==0){
            cout<<setfill("@--")<<"@";
            cout<<endl;
        }
        if(n==2||(n-2)%3==0){
            cout<<setfill("-@-")<<"-";
            cout<<endl;
        }
        if(n==3||(n-3)%3==0){
            cout<<"--";
            cout<<setfill("--@")<<"--";
            cout<<endl;
        }
        n=n-1;
    }
return 0;
}

What i tried to do was trying to input from the back of the line, since from what i know, setw and setfill fill from the back of the input line.

There were 3 scenarios i set, starting with '@','-',or'--'. And after the scenario was met, i tried to fill the remaining input width with '@--','-@-',or'--@'.

But, when i tried to compile the file, the compiler says:

no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::_Setfill<const char*>')

and i have no idea what was the error and how to solve it.

What's the error I ecountered, and how to solve it? Also if possible, is there another optimal way to write the code?

Thank you so much.

Edit: i rewrote the code, this time using more arrays, if and for loops. It finally worked. Thank you for the insights!

here's the code:

#include<iostream>
using namespace std;

int main(){;
    int a;
    cin >> a;
    char one[a];
    char two[a];
    char three[a];

    int eFst,eScd,eTrd;
    //1,4,7... line elements
    for(eFst=0;eFst<a;eFst++){
        if((eFst-1)%3==0){
            one[eFst]='-';
            }
        if((eFst-2)%3==0){
            one[eFst]='-';
            }
        if((eFst-3)%3==0){
            one[eFst]='@';
            }
    }
    //2,5,8... line elements
    for(eScd=0;eScd<a;eScd++){
        if((eScd-1)%3==0){
            two[eScd]='@';
            }
        if((eScd-2)%3==0){
            two[eScd]='-';
            }
        if((eScd-3)%3==0){
            two[eScd]='-';
            }
    }
    //3,6,9... line elements
    for(eTrd=0;eTrd<a;eTrd++){
        if((eTrd-1)%3==0){
            three[eTrd]='-';
            }
        if((eTrd-2)%3==0){
            three[eTrd]='@';
            }
        if((eTrd-3)%3==0){
            three[eTrd]='-';
            }
    }
    
    int i,rFst,rScd,rTrd;       
//how many rows
    for(i=0;i<a;i++){
        //1,4,7 line and so on
        if((i-3)%3==0){
            for(rFst=0;rFst<a;rFst++){
                cout<<one[rFst];
            }
            cout<<endl;
        }
        //2,5,8 line and so on
        if((i-1)%3==0){
            for(rScd=0;rScd<a;rScd++){
                cout<<two[rScd];
            }
            cout<<endl;
        }
        //3,6,9 line and so on
        if((i-2)%3==0){
            for(rTrd=0;rTrd<a;rTrd++){
                cout<<three[rTrd];
            }
            cout<<endl;
        }
    }

return 0;
}

If there are ways to optimise my code, please kindly let me know, thanks!


Solution

  • Nobody knows all C++ by heart. You need to get accustomed to some reference where you can look stuff up. I recommend cppreference.com.

    std::setfill is

    template< class CharT >
    /*unspecified*/ setfill( CharT c );
    

    It is a function template with unspecified return type. This may sound a little odd, but most iomanipulators are functions. CharT denotes the character type. Strings and streams and most related stuff is parametrized on the character type. When you use std::cout of type std::ostream that is actually std::basic_ostream<char> (see here. Hence, here you want to use std::setfill<char>. The template parameter can be deduced so you only need to supply a parameter:

     std::cout << std::setfill('.'); 
    

    The error message is rather intersting...

    no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'std::_Setfill<const char*>')
    

    std::_Setfill<const char*> is the unspecified return type from above. In a different standard library implementation it could be a totally different type. Its just something that you can pipe to eg std::cout to get the desired effect. There is const char* because the character array "@--", a const char[4], has decayed to a pointer.

    TL;DR: std::setfill does not works with strings as argument.