1

relatively new to C++ and I'm having issues getting my code going. When I compile and run the program the terminal window is just black, but I noticed 3 warnings I have might be causing this issue, however I'm not sure how to clear them up.

The errors are the following, all stated to be in the .cc file:


    Line 31 Warning C4018    '<': signed/unsigned mismatch  
    Line 60 Warning C4018    '<': signed/unsigned mismatch  
    Line 57 Warning C4018    '>=': signed/unsigned mismatch

Here is the header file to my program:


    #ifndef H_JOSEPHUS
    #define H_JOSEPHUS
    
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <list>
    #include <algorithm>
    
    using namespace std;
    
    #define NO_LETS  26    // no of letters in English alphabet
    #define NO_ITEMS 12    // no of items printed on single line
    
    // struct for input arguments
    
    struct args {
        unsigned N,       // no of initial people   
                 M,       // count to eliminate person
                 K;       // frequency of printouts
    };
    
    // class to generate name tags for people
    
    class SEQ {
    private:
        string id;         // name tag for person
        unsigned size, nd; // no of people, no of digits in name tags
    
        // returns no of digits in name tags
        unsigned find_nd ( const double& sz ) {
            if ( ( sz / NO_LETS ) <= 1 ) return 2;
            else return ( find_nd ( sz / NO_LETS ) + 1 );
        }
    
    public:
        // constructor for name-tag generator
        SEQ ( const unsigned& s = 1 ) : size ( s ) {
            double sz = ( double ) size / 9; nd = find_nd ( sz );
            id = string ( nd, 'A' ); id [ nd - 1 ] = '1'; 
        }
    
        // returns next name tag in sequence
        string operator ( ) ( ) {
            string tmp = id; int i = nd - 1;
            if ( id [ i ] < '9' ) id [ i ]++;
            else {
                id [ i ] = '1'; bool flag = true;
                for ( i--; i >= 0 && flag; i-- )
                    if ( id [ i ] < 'Z' ) { id [ i ]++; flag = false; }
                    else id [ i ] = 'A';
            } 
            return tmp;
        }
    };
    
    // reads and initializes all input arguments
    void init_vals(list<string>& L, args& in);
    
    // prints all name tags for remaining people after elimination
    void print_list ( const list < string >&, const unsigned& );
    
    #endif

Here is my .cc file:


    #include "josephus.h"
    #include <iostream>
    using namespace std;
    
    int M;
    int K;
    void prnt(list < string >& L)
    {
        int c = 1;
        int i = 0;
        for (list<string>::iterator it = L.begin(); it != L.end(); it++)
        {
    
            cout << *it << " ";
            if (c == 12)
            {
                c = 1; cout << "\n";
            }
            c++;
    
    
        }
        cout << "\n";
    }
    
    void init_vals(list<string>& L, args& in)
    {
        cin >> in.N >> in.M >> in.K;
        cout << "\nThe values of n m k are: " << in.N << " " << in.M << " " << in.K;
        list<string>::iterator it;
        for (int i = 0; i < in.N; i++) // line 31
        {
            string s;
            stringstream ss;
            ss << char('A' + i / 9);
            ss >> s;
            s += char(((i + 1) % 9) + '0');
            L.push_back(s);
            //cout<<L[i]<<" ";
        }
    }
    
    void print_list(const list<string>&L, const unsigned&cnt)
    {
        cout << "\nAt begining of the joseph problem\n";
        //bool arr[L.size()]={true};
        list < string > l = L;
        prnt(l);
        int counter = 0;
        int sz = L.size() - 1;
        int c = cnt;
        while (c < sz)
        {
    
    
            counter += M - 1;
            if (counter >= l.size()) counter %= l.size(); // line 57
            list<string>::iterator it = l.begin();
            //it = it
            for (int i = 0; i < static_cast<unsigned int>(counter); i++) // line 60
                it++;
            l.erase(it);
            c++;
            if ((c) % K == 0)
            {
                cout << "\n After deleting K name\n";
                prnt(l);
            }
        }
        cout << "\nLast remaining person: " << *(l.begin());
    }
    
    int main()
    {
        list<string> L;
        struct args in;
        init_vals(L, in);
        M = in.M;
        K = in.K;
        print_list(L, 0);
    
    }

Any guidance is greatly appreciated!

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    There are no line numbers, can you annotate the lines that are getting the errors? – Barmar Feb 26 '21 at 21:28
  • Declare `counter` as `unsigned int` instead of `int`. – Barmar Feb 26 '21 at 21:29
  • 1
    Those warnings should not cause any problems in the code. – Barmar Feb 26 '21 at 21:31
  • Agreed, if the code doesn't work the real problem is somewhere else. Fire up your debugger, start adding print statements at strategic points, et cetera. – Nate Eldredge Feb 26 '21 at 21:32
  • Don't elide the errors/warning messages - you have not stated which of the two files each warning appears in. – Clifford Feb 26 '21 at 21:33
  • @Clifford He said they're in the `.cc` file. – Barmar Feb 26 '21 at 21:33
  • While there are some occasions when these signed/unsigned comparisons can cause issues, your code won't have those problems. – Barmar Feb 26 '21 at 21:37
  • @Barmar There must be something I have to dig deeper into then. When I compile and run this code the terminal opens and nothing gets printed. – Dreamvillain Feb 26 '21 at 21:50
  • It's waiting for you to type the values of N, M, and K. – Barmar Feb 26 '21 at 21:56
  • In such cases, it's often a good idea to throw an extra `std::cout << "Program start!\n";` at the top of `main()`. Once you see that and prove that your program actually is running, time to learn to use a debugger. – Ben Voigt Feb 26 '21 at 21:59
  • @Barmar fair enough, but if he posted the full error message he need have said nothing more. Easier to copy and paste verbatim and avoids loosing useful diagnostic information. But point taken, I did moss that. – Clifford Feb 26 '21 at 22:15
  • Indeed, notice my first comment asking him to show where the errors actually occurred. I eventually added comments to mark them. – Barmar Feb 26 '21 at 22:17

2 Answers2

1

in::N is declared as unsigned here:

struct args {
        unsigned N,       // no of initial people   
                 M,       // count to eliminate person
                 K;       // frequency of printouts
    };

You declare your loop variable as a plain (i.e. signed) int in

for (int i = 0; i < in.N; i++)

And std::list::size is unsigned yet you compare it with the signed int counter here:

if (counter >= l.size()) counter %= l.size();
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
0

All the warnings are trivial type mismatches and the cause of your program failing to output.

  • At for (int i = 0; i < in.N; i++) args::N is unsigned while i is int.
  • At if (counter >= l.size()) counter %= l.size(); counter is int while std::list::size()returns an unsigned type.
  • At for (int i = 0; i < static_cast<unsigned int>(counter); i++) i is int and you have bizarrely force a type disagreement by casting counter.

Fixing the warnings is a simple matter of not comparing signed to unsigned types. I get an additional warning - the variable i in prnt() is unused.

Running the code, it waits for input at:

    cin >> in.N >> in.M >> in.K;

I entered 1 2 3, and it output:

The values of n m k are: 1 2 3                                                                                             
At begining of the joseph problem                                                                                          
A1

Perhaps the only problem is it is waiting for input that you are not providing - a user prompt might be in order.

You might also use a debugger - when your code stalls like this you can interrupt its execution and see where it is in the code.

Clifford
  • 88,407
  • 13
  • 85
  • 165