r3dux.org

A number-pimping side project from the valleys in *NEW* upside-down flavour.

  • Home
  • ABOUT
  • OLD SITE
  • SEARCH
  • FEEDBACK

How-to: Overload the C++ function operator()

r3dux | January 20, 2012

I’m working my way through the first few chapters of James Reinders’ Intel Threading Building Blocks book, and its a little bit hard going. As much as I’m enjoying the mental exercise of thinking in parallel, when it actually comes to the coding they use a lot of function operator (i.e. operator()) overloading, and I’m not so familiar with it. As much as I’ve overloaded operators before so you could, for example, add two Fruit objects together and get their weight, or multiply an Employee->monthlySalary by 12 to get their yearly wage, I’d never overloaded the function operator itself, so wasn’t sure what was really going on in the code.

To fix this, I’ve knocked together a super-simple example to show how it works:

#include <iostream>
using std::cout;
using std::endl;
 
class Foo
{
	public:
		// Property
		int number;
 
		// Constructor
		Foo() : number(0)
		{
			cout << "Constructing an object of type Foo..." << endl;
		}
 
		// First overloaded function operator, i.e. we're overloading the operator ()
		void operator()()
		{
			cout << "From our first overloaded () operator, I get the number: " << number << endl;
		}
 
		// Second overloaded function operator
		void operator()(Foo &first, Foo &second)
		{
			if (first.number > second.number)
			{
				cout << "The first number property is greater than the second number property." << endl;
			}
			else
			{
				cout << "The first number property is less than or equal to the second number property." << endl;
			}
		}
};
 
void doNothing(Foo tempFoo)
{
	cout << "I'm not using the overloaded () operator here." << endl;
}
 
int main()
{
	// Create our first test object
	Foo firstObject;
 
	// Make sure it's initialised with the default value specified in the constructor
	cout << "From main, number is: " << firstObject.number << endl;
 
	// Call the doNothing function on our Foo object - doesn't do a lot!
	doNothing(firstObject);
 
	// Anonymous object creation (i.e. invokes the constructor - but we don't keep a named object)
	Foo();
 
	// ***THIS*** is where the overloaded function operator comes in!
	firstObject();
 
	// Create a second test object and specify a value
	Foo secondObject;
	secondObject.number = 5;
 
	// Run our first overloaded function operator again on a different object
	secondObject();
 
	// Run our second overloaded function operator on the first object
	firstObject(firstObject, secondObject);
 
	// Run our second overloaded () operator (function operator) again, but on diff object
	// It doesn't matter which object we run it on - behviour is only dependant on the order
	// in which we supply the object parameters in this case!
	secondObject(firstObject, secondObject);
 
	// Finally, just to prove we can trigger the second path in the 2nd overloaded function operator...
	secondObject(secondObject, firstObject);
 
	return 0;
}

Which gives the output:

Constructing an object of type Foo...
From main, number is: 0
I'm not using the overloaded () operator here.
Constructing an object of type Foo...
From overloaded () operator, I got the number: 0
Constructing an object of type Foo...
From overloaded () operator, I got the number: 5
The first number property is less than or equal to the second number property.
The first number property is less than or equal to the second number property.
The first number property is greater than the second number property.

So, that’s how it works. Straight forward enough.

Another example, taken from the Function object wikipedia page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iterator>
#include <algorithm>
 
class countfrom {
	private:
		int &count;
	public:
	  countfrom(int &n) : count(n) {}
	  int operator()() { return count++; }
};
 
int main() {
	int state(10);
	std::generate_n(std::ostream_iterator<int>(std::cout, "\n"), 11, countfrom(state));
	return 0;
}

Counting from 10 to 20 has never been funner =D

Comments
No Comments »
Categories
Coding
Tags
C++, Coding, Function, Function Operator, Operator, Overloading
Comments rss Comments rss
Trackback Trackback

How to: Convert an OpenCV cv::Mat to an OpenGL texture

r3dux | January 14, 2012

I’m working on using OpenCV to get Kinect sensor data via OpenNI, and needed a way to get a matrix (cv::Mat) into an OpenGL texture – so I wrote a function to do just that – woo! Apologies in advance for the terrible juggling ;-)

YouTube Preview Image

The function used to perform the sensor data to texture conversion is:

// Function turn a cv::Mat into a texture, and return the texture ID as a GLuint for use
GLuint matToTexture(cv::Mat &mat, GLenum minFilter, GLenum magFilter, GLenum wrapFilter)
{
	// Generate a number for our textureID's unique handle
	GLuint textureID;
	glGenTextures(1, &textureID);
 
	// Bind to our texture handle
	glBindTexture(GL_TEXTURE_2D, textureID);
 
	// Catch silly-mistake texture interpolation method for magnification
	if (magFilter == GL_LINEAR_MIPMAP_LINEAR  ||
	    magFilter == GL_LINEAR_MIPMAP_NEAREST ||
	    magFilter == GL_NEAREST_MIPMAP_LINEAR ||
	    magFilter == GL_NEAREST_MIPMAP_NEAREST)
	{
		cout < < "You can't use MIPMAPs for magnification - setting filter to GL_LINEAR" << endl;
		magFilter = GL_LINEAR;
	}
 
	// Set texture interpolation methods for minification and magnification
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
 
	// Set texture clamping method
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapFilter);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapFilter);
 
	// Set incoming texture format to:
	// GL_BGR       for CV_CAP_OPENNI_BGR_IMAGE,
	// GL_LUMINANCE for CV_CAP_OPENNI_DISPARITY_MAP,
	// Work out other mappings as required ( there's a list in comments in main() )
	GLenum inputColourFormat = GL_BGR;
	if (mat.channels() == 1)
	{
		inputColourFormat = GL_LUMINANCE;
	}
 
	// Create the texture
	glTexImage2D(GL_TEXTURE_2D,     // Type of texture
	             0,                 // Pyramid level (for mip-mapping) - 0 is the top level
	             GL_RGB,            // Internal colour format to convert to
	             mat.cols,          // Image width  i.e. 640 for Kinect in standard mode
	             mat.rows,          // Image height i.e. 480 for Kinect in standard mode
	             0,                 // Border width in pixels (can either be 1 or 0)
	             inputColourFormat, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
	             GL_UNSIGNED_BYTE,  // Image data type
	             mat.ptr());        // The actual image data itself
 
	// If we're using mipmaps then generate them. Note: This requires OpenGL 3.0 or higher
	if (minFilter == GL_LINEAR_MIPMAP_LINEAR  ||
	    minFilter == GL_LINEAR_MIPMAP_NEAREST ||
	    minFilter == GL_NEAREST_MIPMAP_LINEAR ||
	    minFilter == GL_NEAREST_MIPMAP_NEAREST)
	{
		glGenerateMipmap(GL_TEXTURE_2D);
	}
 
	return textureID;
}

You can then use the above function like this:

// Create our capture object
cv::VideoCapture capture( CV_CAP_OPENNI );
 
// Check that we have actually opened a connection to the sensor
if( !capture.isOpened() )
{
	cout < < "Cannot open capture object." << endl;
	exit(-1);
}
 
// Create our cv::Mat object
cv::Mat camFrame;
 
	// *** loop ***
 
	// Grab the device
	capture.grab();
 
	// Retrieve desired sensor data (in this case the standard camera image)
	capture.retrieve(camFrame, CV_CAP_OPENNI_BGR_IMAGE);
 
	// Convert to texture
	GLuint tex = matToTexture(camFrame, GL_NEAREST, GL_NEAREST, GL_CLAMP);
 
	// Bind texture
	glBindTexture(GL_TEXTURE_2D, tex);
 
	// Do whatever you want with the texture here...
 
	// Free the texture memory
	glDeleteTextures(1, &tex);
 
	// *** End of loop ***
 
// Release the device
capture.release();

There's one very important issue to watch out for when using OpenCV and OpenNI together which I've commented in the code, but I'll place here as well as it can be a real deal breaker:

There appears to be a threading issue with the OpenCV grab() function where if you try to grab the device before it's ready to provide the next frame it takes up to 2 seconds to provide the frame, which it might do for a little while before crashing the XnSensorServer process & then you can't get any more frames without restarting the application. This results in horrible, stuttery framerates and garbled sensor data.

I've found that this can be worked around by playing an mp3 in the background. No, really. I'm guessing the threading of the mp3 player introduces some kind of latency which prevents the grab() function being called too soon. Try it if you don't believe me!

So just be aware that if you're using a Kinect you have to be careful with the grab() function... The source code used to create the above video is provided in full after the jump, if you're interested.

Cheers!

Read the rest of this entry »

Comments
No Comments »
Categories
Coding, Linux
Tags
Capture, Conversion, Convert, cv::Mat, Kinect, Linux, NITE, OpenCV, OpenGL, OpenNI, Texture
Comments rss Comments rss
Trackback Trackback

A simple C++/SDL_net chat server & client rewritten

r3dux | November 25, 2011

Back in January this year I was due to be teaching some diploma level programming (roughly equivalent to the UK A/S level for any Brits), and part of that had to deal with network programming with sockets and stuff, so I duly did my research and put together a simple chat server and client in SDL_net. And then my classes changed and I got moved on to teach other stuff. I wasn’t too upset though – I’d learnt a lot, and I’d put up the code to help people out who might be in a similar situation, so it was all good.

But now in November I’m back on programming duty, so I dug up my code, looked it over, and thought Naah – I can’t use that, it’s unweildy, and complex, and it would be a real pain to try to re-use the code. So I’ve gone back to the drawing board and refactored it all into something I hope is a lot more palletable and both easy to use and re-purpose. In effect, I’ve refactored it into two wrappers which now consist of a ServerSocket class and a ClientSocket class.

Check it out…

Cross Platform Socket Server and Clients

Cross platform socket connectivity? That'll be a yes, then...

Socket Server

The old chat server was 250 lines, it’s now down to 77:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Re-written simple SDL_net socket server example | Nov 2011 | r3dux
// Library dependencies: libSDL, libSDL_net
 
#include <iostream>
#include <string>
#include <SDL/SDL_net.h>
#include "ServerSocket.h"
 
int main(int argc, char *argv[])
{
	// Initialise SDL_net
	if (SDLNet_Init() == -1)
	{
		std::cerr << "Failed to intialise SDL_net: " << SDLNet_GetError() << std::endl;
		exit(-1);
	}
 
	// Create a pointer to a ServerSocket object
	ServerSocket *ss;
 
	try
	{
		// Try to instantiate the server socket
		// Parameters: port number, buffer size (i.e. max message size), max sockets
		ss = new ServerSocket(1234, 512, 3);
	}
	catch (SocketException e)
	{
		std::cerr << "Something went wrong creating a SocketServer object." << std::endl;
		std::cerr << "Error is: " << e.what()   << std::endl;
		std::cerr << "Terminating application." << std::endl;
		exit(-1);
	}
 
	try
	{
		// Specify which client is active, -1 means "no client is active"
		int activeClient = -1;
 
		// Main loop...
		do
		{
			// Check for any incoming connections to the server socket
			ss->checkForConnections();
 
			// At least once, but as many times as necessary to process all active clients...
			do
			{
				// ...get the client number of any clients with unprocessed activity (returns -1 if none)
				activeClient = ss->checkForActivity();
 
				// If there's a client with unprocessed activity...
				if (activeClient != -1)
				{
					// ...then process that client!
					ss->dealWithActivity(activeClient);
				}
 
			// When there are no more clients with activity to process, continue...
			} while (activeClient != -1);
 
		// ...until we've been asked to shut down.
		} while (ss->getShutdownStatus() == false);
 
	}
	catch (SocketException e)
	{
		cerr << "Caught an exception in the main loop..." << endl;
		cerr << e.what() << endl;
		cerr << "Terminating application." << endl;
	}
 
	// Shutdown SDLNet - our ServerSocket will clean up after itself on destruction
	SDLNet_Quit();
 
	return 0;
}

Socket Client

And the old chat client was 313 lines, which is now down to 83:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Re-written simple SDL_net socket client example | Nov 2011 | r3dux
// Library dependencies: libSDL, libSDL_net
 
#include <iostream>
#include <string>
#include <SDL/SDL_net.h>
 
#include "ClientSocket.h"
 
int main(int argc, char *argv[])
{
	// Initialise SDL_net (Note: We don't initialise or use normal SDL at all - only the SDL_net library!)
	if (SDLNet_Init() == -1)
	{
		std::cerr << "Failed to intialise SDL_net: " << SDLNet_GetError() << std::endl;
		exit(-1);
	}
 
	// Create a pointer to a ServerSocket object
	ClientSocket *cs;
 
	try
	{
		// Try to instantiate the client socket
		// Parameters: server address, port number, buffer size (i.e. max message size)
		// Note: You can provide the serverURL as a dot-quad ("1.2.3.4") or a hostname ("server.foo.com")
		cs = new ClientSocket("127.0.0.1", 1234, 512);
	}
	catch (SocketException e)
	{
		std::cerr << "Something went wrong creating a ClientSocket object." << std::endl;
		std::cerr << "Error is: " << e.what()   << std::endl;
		std::cerr << "Terminating application." << std::endl;
		exit(-1);
	}
 
	try
	{
		// Attempt to connect to the server at the provided address and port
		cs->connectToServer();
 
		string receivedMessage = "";
 
		cout << "Use /quit to disconnect or /shutdown to shutdown the server." << endl;
 
		// Display the initial prompt
		cs->displayPrompt();
 
		// Run the main loop...
		do
		{
			// Check if we've received a message
			receivedMessage = cs->checkForIncomingMessages();
 
			// If so then...
			if (receivedMessage != "")
			{
				// Display the message and then blank it...
				cs->displayMessage(receivedMessage);
 
				// ...and then re-display the prompt along with any typed-but-not-yet-sent input
				cs->displayPrompt();
			}
 
			// Get and deal with input from the user in a non-blocking manner
			cs->getUserInput();
 
		// ... until we decide to quit or the server is shut down
		} while ( (cs->getShutdownStatus() == false));
 
	}
	catch (SocketException e)
	{
		cerr << "Caught an exception in the main loop..." << endl;
		cerr << e.what() << endl;
		cerr << "Terminating application." << endl;
	}
 
	// Shutdown SDLNet - our ClientSocket will clean up after itself on destruction
	SDLNet_Quit();
 
	return 0;
}

On top of all this we have try/catch exception handling, a nice encapsulated & easy to work-with/modify/extend design and debug flags to control whether the client/server should be verbose or run silently. Obviously the chat client itself can’t run completely silently – you wouldn’t be able to read the messages being sent back and forth! – but when debug is off it only ever outputs anything when it receives a message or when the user enters messages to send, so it’s pretty darn quiet.

Oh, and it now comes in Linux and Windows flavours =D

Overall I’m really happy with it – it’s taken a few days to properly redesign and test (not to mention the issues involved with porting to Windows) – but I think the next time I need to do some socket stuff with C++ I’d be able to grab this code, make whatever modifications I need and get something up and running in no time.

Awthome! =P

Download links

  • Linux Client and Server Code (Code::Blocks projects, libs not included)
  • Windows Client and Server Code (Visual Studio 2008 projects, libs included)

Notes on Building for Windows

The windows client and server projects have some important tweaks made for them to compile, and it’s worth mentioning what they are:

  • The solution (which contains two projects) comes comes with a copy of the SDL and SDL_net libs and headers all merged together in the SDL folder (well, there are separate libs and include folders, but all the headers from both are in the include folder and all the libs from both are in the libs folder).
  • Each project has the following libraries linked in: SDL.lib, SDLmain.lib and SDL_net.lib, these libraries point to…
  • SDL.dll and SDL_net.dll which are in the solution’s Debug folder, so you can compile and build from Visual Studio, BUT you’lll need to copy these two dll files into the same folder as the SocketServer-Rewritten.exe or SocketClient-Rewritten.exe folders to run the executables “standalone” in other locations as opposed to build-and-run-from-visual-studio style!
  • The projects are defined as console applications, and because SDLmain.lib defines the main function as int main(int argc, char *argv[]) and not just int main() you MUST keep the definition of main in-line with the SDLmain.lib definition.
  • Finally, the projects will only build successfully in debug mode. Why? I’ve no idea. If you know how to fix it then go for it!

Comments
14 Comments »
Categories
Coding
Tags
C++, Client, networking, SDL_net, Server, Socket
Comments rss Comments rss
Trackback Trackback

How-To: Get valid integer input in C++ (a stupidly long solution to a stupidly simple problem)

r3dux | November 15, 2011

Update: See the comments for a far, far more elegent and robust solution courtesy of the mighty shetboy!


One of the assessments I’ve got my diploma class doing at the moment is to fix all the bugs in some deliberately shonky C++ code. The code just asks for a name (string) and an age in years (int), and it then multiplies the age in years by 365 to give a rough indication of how many days you’ve been alive. So for example if I enter Al and 34 it comes back with:

Hi, Al! You’ve been alive for roughly 12410 days!

The problems come thick and fast though if you want to verify that the age in years entered is really an integer value. You CAN do so like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;
 
int main()
{
    int yearsOld       = 0;
    bool gotValidInput = false;
 
    do
    {
        cout << "Please enter your age in years: ";
        cin >> yearsOld;
 
        if (cin.fail())
        {
            cin.clear();
            cin.ignore();
            cout << "Invalid entry! Whole numbers only, dawg!" << endl;
        }
        else
        {
            // We got some valid input! Set the flag so we can leave the loop!
            gotValidInput = true;
        }
 
    } while ( gotValidInput == false );
 
    cout << "Valid value is: " << yearsOld << endl;
 
    return 0;
}

But you then end up with output like this where each character fails individually:

Please enter your age in years: Mooo...
Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years: Invalid entry! Whole numbers only, dawg!
Please enter your age in years:

Obviously that’s no good, so I researched a bit and came up with a solution but –DAMN– it doesn’t feel like the right one… Check out all this clumsiness:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <sstream>
 
using namespace std;
 
int getValidInteger(string prompt)
{
    bool debug = true;                        // Toggle for verbosity
 
    bool   valid;                             // Our exit flag - we only get out of the do..while loop when this is true
    bool   mixedOperators;                    // Did the user enter a mixture of + and - operators (i.e. -5+3)
    bool   multipleOperators;                 // Did the user enter multiple + or - operators      (i.e. -5-3 or +5+3)
    int    userInt = 0;                       // Integer value we finally return after validation
    string userInput;                         // User input is taken as a string before being wrangled...
    int    foundInvalidInputLocation;         // Character location of any invalid input
 
    string validCharacters  = "+-0123456789"; // All the valid characters we're willing to accept as valid integer input
 
    do
    {
        // Set our initial flags
        valid                     = false;
        mixedOperators            = false;
        multipleOperators         = false;
        foundInvalidInputLocation = 0;
 
        // Display the prompt and get the user input as a string
        cout << endl << prompt << endl;
        getline(cin, userInput);
 
        // Convert the user input string into a input stringstream then...
        istringstream iss(userInput);
 
        // ...try to convert the istringstream into an integer.
        if (iss >> userInt)
        {
            if (debug)
            {
                cout << "This already is or can be made into a valid integer!" << endl;
            }
 
            // Now cast our input string-stream back to a string and...
            string test = iss.str();
 
            // ...test to see if we found any illegal characters (because "123Foo!" -WILL- convert to the int 123, but we want legit input!
            foundInvalidInputLocation = test.find_first_not_of(validCharacters);
 
            if (debug)
            {
                cout << "Value of foundInvalidInputLocation is: " << foundInvalidInputLocation << endl;
            }
 
            // Check whether we found an character which cannot be part of a valid int (-1 indicates no invalid character found)
            if (foundInvalidInputLocation != -1)
            {
                if (debug)
                {
                    cout << "Although we can cast the provided input to an int..." << endl;
                    cout << "...the original input contained at least one invalid character at location: " << foundInvalidInputLocation << endl;
                }
            }
            else // No non-digit characters found? Then we were likely given a legitimate int - but we still need to do more testing to be sure!
            {
                // Find the locations of the first and last plus and minus operators in our converted-from-iss string
                int firstMinusOperatorLoc = test.find_first_of("-");
                int lastMinusOperatorLoc  = test.find_last_of("-");
                int firstPlusOperatorLoc  = test.find_first_of("+");
                int lastPlusOperatorLoc   = test.find_last_of("+");
 
                if (debug)
                {
                    // Wax lyrical about multiple negative operators if detected...
                    cout << "First and last minus signs are at: " << firstMinusOperatorLoc << " and " << lastMinusOperatorLoc << " Match?: ";
                    firstMinusOperatorLoc == lastMinusOperatorLoc? cout << "Yes! This is good!" << endl : cout << "No! Multiple minus operators detected!" << endl;
 
                    // Wax lyrical about multiple positive operators if detected...
                    cout << "First and last plus signs are at: " << firstPlusOperatorLoc << " and " << lastPlusOperatorLoc << " Match?: ";
                    firstPlusOperatorLoc == lastPlusOperatorLoc? cout << "Yes! This is good!" << endl : cout << "No! Multiple plus operators detected!" << endl;
                }
 
                // Got a mixture of both positive and negative operators in the input? Then it's not a valid int!
                if ( (firstMinusOperatorLoc != -1) && (firstPlusOperatorLoc != -1) )
                {
                    if (debug)
                    {
                        cout << "Mixed + and - operators detected, so flagging this as invalid input!" << endl;
                    }
 
                    mixedOperators = true;
                }
                else // No mixed operators? Then we can continue to check for multiple operators...
                {
                    if (debug)
                    {
                        cout << "No mixed operators - continuing... " << endl;
                    }
 
                    // Got multiple negative or positive operators in the input? Then it's not a valid int!
                    if ( (firstMinusOperatorLoc != lastMinusOperatorLoc) || (firstPlusOperatorLoc != lastPlusOperatorLoc) )
                    {
                        if (debug)
                        {
                            cout << "Multiple + or - operators detected, so flagging this as invalid input!" << endl;
                        }
 
                        multipleOperators = true;
                    }
                    else
                    {
                        if (debug)
                        {
                            cout << "No multiple operators - continuing... " << endl;
                        }
                    }
 
                } // End of if mixed operator check else-block
 
                // If we've finally got here and we don't have mixed or multiple operators - then FINALLY we know we have a valid int...
                if ( (mixedOperators == false) && (multipleOperators == false) )
                {
                    if (debug) { cout << "Got a truly valid int! Hurrah!" << endl; }
 
                    // ...so set our exit flag to get out of the do..while loop
                    valid = true;
                }
 
            } // End of if (foundInvalidInputLocation != -1) else section
 
        } // End of if (iss >> userInt) section
        else
        {
            cout << "That's not a valid integer value!" << endl;
        }
 
    } while (valid == false);
 
    // Because we got out of the loop, we must have a valid integer, which we can now return!
    return userInt;
}
 
 
int main()
{
    int x = getValidInteger("Please enter a valid integer: ");
 
    cout << endl << "The value of our valid integer is: " << x << endl;
 
    //system("pause");
    return 0;
}

That works perfectly well as far as I’m concerned (remember – I’m not trying to validate the int to be within a given range or anything – I just want a valid int!) but something is surely wrong here… this should be a one-liner, or maybe three or four lines at the absolute most, not 140 lines or so…

Anyone got any suggestions on how to do this the right way? (In C++ not C, so no atoi or C-strings, and no boost library please! Just “standard” C++!).

Comments
7 Comments »
Categories
Coding
Tags
C++, Input, int, string, stringstream, stupid, user, valid, validate
Comments rss Comments rss
Trackback Trackback

How-To: Fix LMDE Repo Hell

r3dux | November 12, 2011

LMDE is a great distro, but the repo situation is a bit of a mess, what with all the update packs and tracking testing or sid or romeo or wheezy or… yeah, it gets confusing. As I wanted to build openFrameworks the other day and it was moaning about libavcodec and libavcodec-dev mismatches I did a bit of searching around and found this thread over on the mint forums, and making the following changes fixed up the repo issues in no time:

Change your main repos (in /etc/apt/sources.list) to:

deb http://packages.linuxmint.com/ debian main upstream import
deb-src http://packages.linuxmint.com/ debian main upstream import
# deb http://debian.linuxmint.com/incoming testing main contrib non-free
# deb http://debian.linuxmint.com/incoming/security testing/updates main contrib non-free
# deb http://debian.linuxmint.com/incoming/multimedia testing main non-free
 
## DEBIAN
deb http://ftp.us.debian.org/debian/ testing main contrib non-free
deb-src http://ftp.us.debian.org/debian/ testing main contrib non-free
deb http://security.debian.org/ testing/updates main contrib non-free
deb-src http://security.debian.org/ testing/updates main contrib non-free
deb http://www.debian-multimedia.org testing main non-free
deb-src http://www.debian-multimedia.org testing main non-free

Update: Added the deb-src repos to the above list because without them you can’t see package change-logs without ‘em.

And then to ensure the mint repos take precedence over the debian ones, make sure the following is in /etc/apt/preferences:

Package: *
Pin: release o=linuxmint
Pin-Priority: 700
 
Package: *
Pin: origin packages.linuxmint.com
Pin-Priority: 700
 
Package: *
Pin: release o=Debian
Pin-Priority: 500

If you then do and update and upgrade via apt-get or the update manager, all package mismatches should be fixed and you can actually build stuff! Woo! =D

Update May 2012: Getting a large number of packages to be removed when you contemplate updating/upgrading? Pin all repos to 500 (i.e. level the playing field) to fix! Source: http://forum.linuxmint.com/viewtopic.php?f=198&t=67502&p=578038. Thanks, ZeroZero!

Comments
No Comments »
Categories
Coding, How-To, Linux
Tags
Apt, Debian, LMDE, Repo Hell, Repositories, Synaptic, Tracking
Comments rss Comments rss
Trackback Trackback

« Previous Entries Next Entries »

Translate

Categories

Archives

Tags

3D ActionScript ActionScript 3.0 Adobe AI Ballarat Bash C++ Class Convert CS4 Effect Error Film Flash GLSL Gnome Hack How-To install Jaunty Java Kinect Linkage Linux Mash-Up Microsoft Motion OpenGL Particle Problem PS3 Remix Retro script Slides Sound Systems Texture Ubuntu Video VirtualBox Wii Windows XBox

Gamercard

OpenR3dux

Misc.

Flattr this

RSS Feed

r3dux twitter feed



“I have a simple philosophy. Fill what's empty. Empty what's full. Scratch where it itches.”

 - Alice Longworth Roosevelt

rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox