What's new

I want to learn some programming

Poobah

New member
xneoangel said:
Hmm yes it kinda works but if i input 3 negative numbers i get 123 and if input 2 i get 12 is there a way to make it only display the last number? which is the number of negative digits, also if i input any positive number i get the You didn't input any negative number established but i thought it only display it if i didn't input any negative number but it appears if there is a positive number, how can i fix that?
Just remove "cout << num;", and insert "cout << num << endl;" after the while loop so that it only displays the count after you've finished. A positive number is a non-negative number, so, logically, the message will display. Are you concerned about it interpreting zero as being non-negative? Perhaps you could change the loop to be a 'do' loop, where it continues while ( a != 0 ).

EDIT: With the non-negatives thing, just make it display that message after the loop if the number of negatives is zero.
 
Last edited:
OP
xneoangel

xneoangel

Persona User
Hmm if i put the cout << num << endl; outside of the loop for some reason it doesnt display any number after inputting them.

Oh well i'm going to sleep i'll keep trying to fix it tomorrow.
 

Poobah

New member
That would be because the loop isn't ending. Just input something that cin doesn't read, such as the letter 'j', and it'll end because it will have read zero characters. Remember that your loop is depending on the number of characters read by cin, since you have used, "while (cin >> a)".
 

Doomulation

?????????????????????????
Poobah said:
What's a deadlock in terms of the Win32 API?
Deadlock means that your threads are waiting for something and therefore isn't responding. Indeed, deadlocks are very common and is a typical example what happens when one application freeze when ANOTHER application in the system has frozen.
 

Poobah

New member
Oh, I see. I don't think those are as much of a problem as Windows' idiotic HDD thrashing and new task manager.
 

Doomulation

?????????????????????????
I would say on the contrary. Windows API is flawed and a number of things can cause your application to freeze because of it. And when you ship your application, people will blame YOU when it freezes, not Windows.

Concerning your code, let me post a sample of what I would do:

Code:
#include <iostream>
using namespace std; // Specifies that every function in the namespace std can be refered without using std::

int main()
{
	int a, num = 0;
	char buf[1000]; // It never hurts to allocate too much. It is unlikely a user will enter 999 characters into the input stream, which eleminates the buffer overrun risk.
	cout << "Write a series of numbers separated by spaces: " << endl;
	while(cin >> buf)
	{
		a = atoi(buf);
		if (a == 0 && buf[0] != '0')
			cout << "\nInvalid number!\n";
		else if (a < 0)
			++num;
		else
			cout << "\nYou didn't input any negative number!\n";
	}
	cout << "You entered " << num << " negative numbers! Have a nice day.\n";
	system("PAUSE");
	return 0;
}
 
Last edited:
OP
xneoangel

xneoangel

Persona User
Could you explain to me what does this part of your code do?

a = atoi(buf);
if (a == 0 && buf[0] != '0')
 

Garstyciuks

New member
atoi function converts the inputed string into a number. And then if checks if a number was entered. If the converted number is 0 (that also may mean that the string had no number entered in it) and it also checks if the first character wasn't '0'. If it was, then the number entered is valid. Here's an example of invalid entered string:

//buf is "sasd124"
a = atoi(buf); //a is equal to zero 0
if (a==0 && buf[0] != '0') //buf[0] is not 0, it is 's', so that means that the string is not a valid number

other example, with valid string number:

//buf is "0"
a = atoi(buf); //a is equal to zero
if (a==0 && buf[0] != '0') //buf[0] is 0, so it is a valid number - 0

and third example:

//buf is "0123"
a = atoi(buf); //a is equal to 123
if (a==0 && buf[0] != '0') //a is not zero, so the if fails, a valid number was entered
 

Doomulation

?????????????????????????
To complicate things more, you can also write

Code:
if (a == 0 && *(char*)buf == '0') // Invalid number

:p
Assuming you know what that means. It's basic pointer manipulation. Don't know if you've schooled yourself with that.
 
OP
xneoangel

xneoangel

Persona User
Doomulation said:
I would say on the contrary. Windows API is flawed and a number of things can cause your application to freeze because of it. And when you ship your application, people will blame YOU when it freezes, not Windows.

Concerning your code, let me post a sample of what I would do:

Code:
#include <iostream>
using namespace std; // Specifies that every function in the namespace std can be refered without using std::

int main()
{
	int a, num = 0;
	char buf[1000]; // It never hurts to allocate too much. It is unlikely a user will enter 999 characters into the input stream, which eleminates the buffer overrun risk.
	cout << "Write a series of numbers separated by spaces: " << endl;
	while(cin >> buf)
	{
		a = atoi(buf);
		if (a == 0 && buf[0] != '0')
			cout << "\nInvalid number!\n";
		else if (a < 0)
			++num;
		else
			cout << "\nYou didn't input any negative number!\n";
	}
	cout << "You entered " << num << " negative numbers! Have a nice day.\n";
	system("PAUSE");
	return 0;
}

Hmm that code doesn't work for some reason i believe the problem resides in the while loop that has to be ended somehow or use another loop, oh well i'll leave it like that i'll come back to it when i have a bit more of experience.

No i don't know about pointers yes i'm still a newb.

Thanks.
 
Last edited:

Doomulation

?????????????????????????
I copied that from your original code. The question is: how do you want the program to end? Ask for 5 numbers? Ask until you enter a positive number? Or something? You never specified what you wanted it to do exactly.
 
OP
xneoangel

xneoangel

Persona User
Ok i want the program to ask the user to input a series of numbers separated by spaces, if user didn't input any negative number display a message that says you didn't input any negative number (ore something like it), and if you input negative numbers it should tell you how many negative numbers you inputted.

EDIT: i want it to end with
You inputted X negative numbers(if you actually input negative numbers)
or
You didn't input any negative number(if you don't input any negative number)

Then after either of those two messages display the
Press any key to continue...
and after pressing the key it should end.
 
Last edited:

Doomulation

?????????????????????????
Well, that's an entirely different approach. This requires some more advanced code. I propose something like this:

Code:
#include <iostream>
using namespace std;

int main()
{
	char buf[1000];
	int n;
	int num_negative = 0;
	char* p = buf;
	cout << "Enter some numbers: ";
	cin >> buf;
	if (atoi(buf) == 0 && *(char*)buf != '0')
	{
		cout << "\nInvalid value entered! Try again.\n";
		return 1;
	}
	for (; p < p + strlen(buf) + 1; )
	{
		n = atoi(p);
		if (n < 0) num_negative++;
		if (*p == '-') p++;
		while (*p >= '0' && *p++ <= '9');
		if (*p != ' ' && *p != 0)
		{
			cout << "\nEncountered junk in input. Enter your numbers properly!\n";
			return 1;
		}
	}
	cout << "You entered " << num_negative << " numbers!";
}
 
OP
xneoangel

xneoangel

Persona User
Doomulation said:
Well, that's an entirely different approach. This requires some more advanced code. I propose something like this:

Code:
#include <iostream>
using namespace std;

int main()
{
	char buf[1000];
	int n;
	int num_negative = 0;
	char* p = buf;
	cout << "Enter some numbers: ";
	cin >> buf;
	if (atoi(buf) == 0 && *(char*)buf != '0')
	{
		cout << "\nInvalid value entered! Try again.\n";
		return 1;
	}
	for (; p < p + strlen(buf) + 1; )
	{
		n = atoi(p);
		if (n < 0) num_negative++;
		if (*p == '-') p++;
		while (*p >= '0' && *p++ <= '9');
		if (*p != ' ' && *p != 0)
		{
			cout << "\nEncountered junk in input. Enter your numbers properly!\n";
			return 1;
		}
	}
	cout << "You entered " << num_negative << " numbers!";
}

Ok... now that confuses me, i'll save that code and try to understand it when i'm more advanced at programming.

Thanks for your help.
 

Doomulation

?????????????????????????
Updated code:

Code:
#include <iostream>
using namespace std;

int main()
{
	char buf[1000];
	int n;
	int num_negative = 0;
	char* p = buf;
	char* pEnd;

	cout << "Enter some numbers: ";
	cin.get(buf, 1000);

	if (atoi(buf) == 0 && *(char*)buf != '0')
	{
		cout << "Invalid value entered! Try again.\n";
		system("PAUSE");
		return 1;
	}

	for (pEnd = p + strlen(buf) + 1; p < pEnd; )
	{
		n = atoi(p);
		if (n < 0) num_negative++;
		if (*p == '-') p++;
		while (*p >= '0' && *p <= '9') p++;
		if (*p != ' ' && *p != 0)
		{
			cout << "Encountered junk in input. Enter your numbers properly!\n";
			system("PAUSE");
			return 1;
		}
		p++;
	}

	cout << "You entered " << num_negative << " negative number(s)!\n";
	system("PAUSE");
	return 0;
}

Tested and works.
I can, however, tell you what the code does. First, it asks for some numbers seperated by spaces. It then checks if it is a valid number entered by checking if atoi returns 0 (since it returns 0 on error) and also if the first character in the buffer is the number 0. If atoi returns 0 and the first number entered isn't 0, then an error occoured.
Then it uses pointers to access data. The variable p points to the current position in the buffer where it will read the next character. pEnd is used to point at the end of the buffer. That is the length of the string + 1 (since strings always have a 0 at the end of the string). It checks the current position against the end position and checks if it has passed the end of the used buffer. If it has, then terminate the loop.
Inside the loop, first aquire the number entered. Atoi will check the buffer (starting at the position pointed by p) until it reaches a non-number char and will then stop and returns the number prior to that char.
Then check if it is negative. If it is, the increase the num_negative variable by one.
The app will check if there is a minus sign in the buffer, which would indicate a negative number. If so, increase the read position by one.
Then it checks if the current character in the buffer at the read position is a number (its ASCII value is bigger or equal to 0 and is lower or equal to 9). If it is, then increase read position. If not, then terminate the loop.
Last it will make a sanity check to make sure the next character is a space. If it isn't, then you've entered some junk data.
Lastly, it increases the read position so that it won't read the space next time.

After the loop is done, it checks the number of negative numbers found and prints it to the user.
 
Last edited:
OP
xneoangel

xneoangel

Persona User
Wow. :drool:
Yes it works perfectly.
Now thanks man, i'll save that code and try to understand it later, right now it's way beyond me.
 
OP
xneoangel

xneoangel

Persona User
Way to much information for my head to proccess seriously i'll try to understand it when i get more knowledge on operators and pointers, because right now i only know some really basic stuff.

Thanks for the explanation i'll store it in a nice .txt with the code to came back to it later.
 

Poobah

New member
Updated code:
PHP:
#include <iostream>
using namespace std;

int main()
{
	char buf[1000];
	int num_negative = 0;
	char* p = buf;
	char* pEnd;

	cout << "Enter some numbers: ";
	cin.get(buf, 1000);

	for (p = buf, pEnd = buf + strlen( buf ); p < pEnd; )
	{
		while (*p == ' ' || *p == '\t' || *p == '\n')	p++; //Skip spaces, tabs and new lines

		if (atof(p) < 0) num_negative++;

		while (*p >= '0' && *p <= '9' || *p == '-' || *p == '.') p++; //Read through the number
		
		//If there isn't whitespace after the number then it must be junk!
		if (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0')
		{
			cout << "Encountered junk in input. Enter your numbers properly!" << endl;
			system("PAUSE");
			return 1;
		}
	}
	
	if (num_negative == 0)
		cout << "You didn't enter any negative numbers!" << endl;
	else
		cout << "You entered " << num_negative << " negative number" << ( num_negative == 1 ? "" : "s" ) << "!" << endl;

	system("PAUSE");
	return 0;
}
I fixed a few problems, and hopefully this one is easier to read. That last cout checks to see if the number is one or not to see if an 's' should be appended, for correct English. :)
 
Last edited:
OP
xneoangel

xneoangel

Persona User
Ok.
Thanks, yes it's easier on my eyes.
But i still need more experience to understand it, so i have to keep going.
 

Top