William Hemsworth 1,339 Posting Virtuoso

That is what im after :) thanks, didn't know that was possible.

William Hemsworth 1,339 Posting Virtuoso

Hi

I have a small question, probably quite obvious but I cant seem to figure it out.
When using the ifstream or any other stream you can tell if it was sucessfull in its last event. For example:

#include<fstream>
int main() {
	ifstream in("test.txt", ios::in);
	if (in) {
	} // Load successful
	else {
	} // Load fail
	return 0;
}

I understand why this works as if it doesn't load successfully, the variable in will be pointed to NULL. But when trying to copy this example I coulden't figure out how to do this. For example:

#include<iostream>
#include<fstream>
using namespace std;

class Example {
private:
public:
	Example() {
	};
	void Change() {
		// this = ((void*)0); // doesnt work
	}
};


int main() {
	Example example;

	if (example) cout << "Worked\n";
	} else       cout << "Didnt work\n";

	example.Change();

	if (example) cout << "Worked\n";
	} else       cout << "Didnt work\n";

	cin.ignore();
	return 0;
}

Does anybody else know how?

William Hemsworth 1,339 Posting Virtuoso

The forums don't update in realtime like the Subscription Spy. It would be great if it did :)

scru commented: they don't? +3
William Hemsworth 1,339 Posting Virtuoso

Edward made a good point there, if you try

cout << CountDidget(INT_MAX) << '\n';

Im just gona have to keep changing ;)

template<typename type>
int CountDidgets(type val, bool signInc = 0) {
	int d = 1; long long c;
	if (val >= 0) for (c = 10; c <= val; c *= 10) d++;
	else for (c= -10 ; c >= val; c *= 10) d++;
	return (signInc && c < 0) ? ++d : d;
}

Now try this:

cout << CountDidgets<unsigned int>(INT_MAX) << '\n';

Should work now :icon_wink:

William Hemsworth 1,339 Posting Virtuoso

You could also change the function very easily so you have a choise:

int CountDidgets(int val, bool signInc = 0) {
	int d = 1, c;
	if (val >= 0) for (c = 10; c <= val; c *= 10) d++;
	else for (c= -10 ; c >= val; c *= 10) d++;
	return (signInc && c < 0) ? ++d : d;
}

Now were both happy :)

William Hemsworth 1,339 Posting Virtuoso

Ive had that function for a year or two now, never failed on me o.0

Ed would also argue that any sane programmer will use a slow and correct function rather than a fast and broken function.

I agree there, although I would rather have both.
But I dont see how its broken.. :icon_confused:

William Hemsworth 1,339 Posting Virtuoso

The results are identical

Not exactly, the function I made is Much more efficient and doesnt make any calls to any other functions. And I think the minus sign should count as a didget as if you are don't, trying to assign it to a char buffer and it wont have enough space if it's a negative number.

William Hemsworth 1,339 Posting Virtuoso

int getNumDecimalDigits(int value)
{
char myString[16];
sprintf(myString,"%d",value);
return strlen(myString);
}

That is not the best way to do it, heres a better way:

// Will work with negative numbers
int CountDidgets(int val) {
	int d = 1, c;
	if (val >= 0) for (c = 10; c <= val; c *= 10) d++;
	else for (c = -10 ; c >= val; c *= 10) d++;
	return (c < 0) ? ++d : d;
}
jephthah commented: this is not a pissing contest. if it were, i would point out that your function is no better, no more efficient, and -- in fact -- more convoluted. +0
William Hemsworth 1,339 Posting Virtuoso

I learned how to do Win32 programming quite well in under a week off this tutorial, it might be what your looking for. You should also do this tutorial before moving on to MFC, it will help.
http://www.winprog.org/tutorial/start.html

William Hemsworth 1,339 Posting Virtuoso

I don't see a main () function or a WinMain () function.

That may be why he is getting this error :D

William Hemsworth 1,339 Posting Virtuoso

Thanks for the reply mitrmkar,
I took a look at the link and that answers my second question. :)
Do you have any idea on how std::string / std::vector manages to allocate memory so quickly, if so, would it be possible to use the same technique here?

William Hemsworth 1,339 Posting Virtuoso

And one more question, when I run this example on Debug, I got the following output:

SubStr:            4073 CPU Cycles
string::substr:    689  CPU Cycles

However, if I run it on Release, I get this output:

SubStr:            3436  CPU Cycles
string::substr:    67    CPU Cycles

What is causing this difference in speed? :icon_rolleyes:

William Hemsworth 1,339 Posting Virtuoso

Hi

I am trying to make function which returns a substring as a char* , but string::substr returns a const char* . So I have managed to make a function that will return a substring as char* , except when I was comparing the speed of the two, I found that string::substr was much faster than the one I made. But its not actually to do with the technique I used to retrieve a substring, I found that just allocating the memory takes about twice as long than string::substr to manage everything.

Here is the code that compares the two functions:

#include<iostream>

unsigned __int64 start;
unsigned __int64 end;

inline __declspec(naked) unsigned __int64 GetCycleCount() {
    _asm rdtsc;
    _asm ret;
}
inline void StartMeasure() {
	start = GetCycleCount();
}
inline void EndMeasure() {
	end = GetCycleCount();
}
inline unsigned __int64 GetMeasure() {
	return (end - start);
}

#define SpeedTest(event, loops)\
	StartMeasure();\
	for(unsigned __int64 _i = 0; _i < loops; _i++) {\
		event;\
	}\
	EndMeasure();\
	start /= loops, end /= loops;\
	std::cout << GetMeasure();


char *SubStr(char *text, unsigned int beg, unsigned int fin) {
	unsigned int len = fin - beg;
	char *sub = new char[len];
	memcpy(sub, &text[beg], len);
	sub[len] = '\0';
	return sub;
}

int main() {

	char text[] = "0123456789";
	std::string text_s = text;

	/*  SubStr  */
	std::cout << "\n SubStr:\t   ";
	SpeedTest(
		SubStr(text, 0, 5),
	1000000);
	std::cout << "\tCPU Cycles";


	/*  string::substr  */
	std::cout << "\n\n string::substr:   ";
	SpeedTest(
		text_s.substr(0, 5),
	1000000);
	std::cout << "\tCPU Cycles";


	std::cin.ignore(); …
William Hemsworth 1,339 Posting Virtuoso

You havent explained your problem. I can see a few errors just by looking at it.

  • BaseArea (i,x,y,z); i hasnt been assigned a value yet
  • Change <iostream.h> to <iostream>
  • Your using std events but you fergot to add using namespace std; at the beginning of the code

<iostream.h> was declared deprecated

William Hemsworth 1,339 Posting Virtuoso

I have formatted the code for you and fixed it to the way it should have been done. :icon_neutral:

#include <iostream>
#include <vector>

using namespace std;

class Pair {
private:
	int x;
	int y;
public:
	Pair(int a, int b) {
		x = a;
		y = b;
	};
	int get_x() {
		return x;
	};
	int get_y() {
		return y;
	};
};

int main()
{
	vector<Pair> set;

	Pair a1(70, 64);
	set.push_back(a1);

	cin.ignore();
	return 0;
}

Hope it helps.

William Hemsworth 1,339 Posting Virtuoso

Many problems in the code.. but this will remove the error:

#include <iostream>
#include <vector>

using namespace std;

class Pair {
public:
Pair(int a, int b)
{x=a; y=b;};
int get_x()
{return x;};
int get_y()
{return y;};
private:
int x;
int y;};

int main()
{vector<Pair> set;
Pair* a1 = new Pair(70, 64);

set.push_back(*a1);


system("PAUSE");
return 0;
}

- Dont use system("pause")
- Format your code better
- Use code tags

William Hemsworth 1,339 Posting Virtuoso

Yes, what Ancient Dragon sead will work fine, to save some time you could define it as a macro.

#include<iostream>

#define rand_f(n)   (((rand()%10000)/10000.0f)*n)

int main() {
	for (int i = 0; i < 100; i++) {
		std::cout << rand_f(1) << '\n';
	}
	std::cin.ignore();
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

No way.., the moniter doesn't communicate with the PC in any way, except by recieving information for it to display.

William Hemsworth 1,339 Posting Virtuoso

I dont often use goto, but it has been usefull in some cases for me too.
There might be better ways to do this but this seems like the easiest method to me:

// Breaking out of nested loops
for (int i = 0; i < 100; i++) {
   for (int j = 0; j < 100; j++) {
      for (int k = 0; k < 100; k++) {
         if (....) goto out;
      }
   }
   out:
}
William Hemsworth 1,339 Posting Virtuoso

Use code tags and format your code, then I will help.

William Hemsworth 1,339 Posting Virtuoso

Using std::string does not require a Null Terminator because it keeps track of the length as you add characters into the vector, but when you call std::string::c_str(), it will return the characters in the string along with a '\0' at the end.

William Hemsworth 1,339 Posting Virtuoso

To make rand() generate a random number inbetween a certain value you need to do something like this:

int var = rand() % 100; // Generates a random number between 0 and 100

But every time you load the program up you should first call srand(time(NULL));

William Hemsworth 1,339 Posting Virtuoso

is it good to end up string with '\0' or it should be '\n'???

All strings should finish with a '\0', known as a NULL Terminator. Without it, Problems may appear, for example:

char str[] = {'a','b','c','d'}; // has no NULL Terminator
cout << str; // Will print "abcd" but may also print a load of random characters after it.

char str[] = {'a','b','c','d','\0'}; // Contains a NULL Terminator and therefore will stop printing characters when it reaches '\0'.
cout << str;

Also it is used in many standard C++ functions like strlen.

You could rewrite the strlen function like this:

size_t strlen(const char *str) {
	size_t len = 0;
	while (*str++) len++;
	// Terminates when the NULL character is reached
	/*
	Same as:
	 while (*str++ != 0) len++;
	*/
	return len;
}

When you assign a string like this:

char str[] = "Hello";

The NULL Terminator is automaticly placed at the end.

William Hemsworth 1,339 Posting Virtuoso

For the last code I gave you, you should imagine it like this:

index	fibonacci value
0:	0
1:	1
2:	1
3:	2
4:	3
5:	5

So if you enter the index 3, the output will be 2.

William Hemsworth 1,339 Posting Virtuoso

If you just want to get the fibonacci depending on the index, you dont need to store all the values inbetween, so something like this will do:

#include<iostream>
using namespace std;

int main() {
	//
	cout << "Enter index: ";
	unsigned int index;
	cin >> index;
	//
	unsigned int sum = 0;
	unsigned int old1 = 0;
	unsigned int old2 = 1;
	//
	for (unsigned int i = 0; i < index; i++) {
		sum = old1 + old2;
		old2 = old1;
		old1 = sum;
	}
	//
	cout << "\nResult: " << sum;
	//
	cin.ignore();
	cin.ignore();
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

Just add the values to a vector instead of displaying them.

#include<iostream>
#include<vector>
using namespace std;

int main() {
	cout << "Enter maximum value: ";
	int max;
	cin >> max;
	//
	int sum = 0;  // old1 + old2
	int old1 = 0; // old
	int old2 = 1; // oldest
	//
	vector<int> values;
	//
	while (sum <= max) {
		values.push_back(sum);
		sum = old1 + old2;
		old2 = old1;
		old1 = sum;
	}
	//
	cout << "Enter index: ";
	int index;
	cin >> index;
	cout << "\nResult: " << values[index];
	//
	cin.ignore();
	cin.ignore();
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

Very easy to do, heres an example:

#include<iostream>
using namespace std;

int main() {
	cout << "Enter maximum value: ";
	int max;
	cin >> max;
	//
	int sum = 0;  // old1 + old2
	int old1 = 0; // old
	int old2 = 1; // oldest
	//
	while (sum <= max) {
		cout << sum << '\n';
		sum = old1 + old2;
		old2 = old1;
		old1 = sum;
	}
	//
	cin.ignore();
	cin.ignore();
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

I think you need to disable unicode to remove those errors.
Try adding:

#undef UNICODE

at the very beginning of your source code.

William Hemsworth 1,339 Posting Virtuoso

I think you need to learn how to use pointers. Heres a tutorial:
You probably only need to look at the Pointer initialization section.
http://www.cplusplus.com/doc/tutorial/pointers.html

William Hemsworth 1,339 Posting Virtuoso

This will return true if the characters are equal up to the minimum length of the two strings. And it does not use the == operator.

bool Compare(char *str1, char *str2) {
	if (!(*str1 || *str2)) return true; // End of string
	bool match = (*str1 >= *str2) && (*str1++ <= *str2++); // Check char
	if (match) return Compare(str1, str2);
	return false;
}
William Hemsworth 1,339 Posting Virtuoso

Can you post the code that is giving this error ?

William Hemsworth 1,339 Posting Virtuoso

you cant have a single array of floats "mixed with" ints

You can have an array with different data types, you just need to point to them using void*

example:

void *array[] = {(int*)123, (char*)"Hello"};
cout << (int)array[0]; // prints 123
cout << (char*)array[1]; // prints "Hello"
jephthah commented: good call +3
William Hemsworth 1,339 Posting Virtuoso

Opps, I just realized I posted this in the C forum ;) I thought I was in C++.

William Hemsworth 1,339 Posting Virtuoso

I just happened to have posted in a thread very similar to this.
http://www.daniweb.com/forums/thread107523.html

Heres a few functions that may help.

#include<iostream>
using namespace std;

inline char *SubStr(char *text, int beg, int end) {
	register unsigned len = end - beg;
	register char *cut = new char[len];
	memcpy_s(cut,(rsize_t)len,&text[beg],(size_t)len);
	cut[len] = '\0';
	return cut;
}

inline bool TextContains(char *txt, char ch) {
	while (*txt) if (*txt++ == ch) return 1;
	return 0;
}

int CountWords(char *text, char *gaps) {
	bool t = 0, ot = 0;
	int wc = 0;
	while (TextContains(gaps, *text++));
	while (*text) {
		t = TextContains(gaps, *text++);
		if (t != ot) wc++;
		ot = t;
	}
	return (wc/2)+1;
}

char *GetWord(char *text, char *gaps, int bzIndex) {
	register unsigned int i = 0, sc = 0, ec = 0, g = 0;
	for (;text[i] && TextContains(gaps, text[i]);) i++;
	for (sc = i; text[i]; i++) {
		if (TextContains(gaps, text[i])) {
			while (text[i] && TextContains(gaps, text[i+1])) i++;
			if (++g == bzIndex) sc = i + 1;
		} else if (g == bzIndex) {
			while (text[i] && !TextContains(gaps, text[i])) i++;
			ec = i;
			break;
		}
	}
	return SubStr(text, sc, ec);
}

char **GetAllWords(char *text, char *gaps) {
	unsigned int NumWords = CountWords(text, gaps);
	char **words = new char*[NumWords];
	register unsigned int sc = 0, ec = 0, g = 0;
	for (unsigned int i = 0; g < NumWords; i++) {
		while (text[i] && TextContains(gaps, text[i])) i++;
		sc = i;
		while (text[i] && !TextContains(gaps, text[i])) i++;
		ec …
William Hemsworth 1,339 Posting Virtuoso

This may not be the best way to seperate each word, but heres how I managed it.
You could read all the text out of the file first and then manually retrieve each word.

#include<iostream>
using namespace std;

#pragma warning(disable : 4018)

char *SubStr(char *text, int beg, int end) {
	register int len = end - beg;
	register char *cut = new char[len];
	memcpy_s(cut, (rsize_t)len, &text[beg], (size_t)len);
	cut[len] = '\0';
	return cut;
}

inline bool TextContains(char *txt, char ch) {
	while (*txt) if (*txt++ == ch) return 1;
	return 0;
}

unsigned int WordCount(char *text, char *gaps) {
	register bool t = 0, ot = 0;
	register int wc = 0;
	while (TextContains(gaps, *text++));
	while (*text) {
		t = TextContains(gaps, *text++);
		if (t != ot) wc++;
		ot = t;
	}
	return (wc/2)+1;
}

string *GetAllWords(char *text, char *gaps) {
	int NumWords = WordCount(text, gaps);
	string *words = new string[NumWords];
	register unsigned int sc = 0, ec = 0, g = 0;
	for (unsigned int i = 0; g < NumWords; i++) {
		while (text[i] && TextContains(gaps, text[i])) i++;
		sc = i;
		while (text[i] && !TextContains(gaps, text[i])) i++;
		ec = i;
		words[g++] = SubStr(text, sc, ec);
	}
	return words;
}

int main() {
	char str[] = "zero:;one#@two([three ==four";
	char gaps[] = " :;#@([=";
	string *words = GetAllWords(str, gaps);
	for (int i = 0; i < WordCount(str, gaps); i++) {
		cout << words[i].c_str() << '\n';
	}
	cin.ignore();
	return 0;
}
Ancient Dragon commented: good work :) +29
William Hemsworth 1,339 Posting Virtuoso
Salem commented: Good answer, which should have been found by STW to begin with. +17
William Hemsworth 1,339 Posting Virtuoso

At the end of the code, try adding

cin.ignore()
William Hemsworth 1,339 Posting Virtuoso

Try this:

#include <iostream>

using namespace std;

int main()
{
	unsigned int digit1;
	unsigned int digit2;

	for( digit1 = 0; digit1 < 10; digit1++ ) {
		for( digit2 = 0; digit2 < digit1 + 1; digit2++ ) {
			cout << '*';
		}
		cout << '\n';
	}

	cin.get();

	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

Two year old thread..

William Hemsworth 1,339 Posting Virtuoso

The exact same would be:

if (tos==0) {		// tos==0?
	return 1;	// 1
} else {		// :
	return 0;	// 0
}

But as you can see

return (tos==0?1:0)

is much easier to write.

William Hemsworth 1,339 Posting Virtuoso

Hello

I have a friend who has a problem with his PC, as soon as he turns his computer on it will get stuck at the loading screen. The last line is displays is:

Press F1 for setup...

He has the same problem before but it would continue normally after about 20-30 minutes and there would be no problems until he next tried to turn it on. I managed to fix that problem by resetting the BIOS by opening up the PC and removing the lithium battery but I tried it again with the current problem and it didn't work.

Does anyone have any suggestions on how to fix this?
Pressing F1 does nothing :icon_sad:

(Im not sure if this is the right place to post but he does use Windows Vista)

William Hemsworth 1,339 Posting Virtuoso

If it says 'Release' just to the right of the run (Start Debugging) icon then when you run or compile the project it will have compiled as release, but the reason I think you get the error message (Which I always used to get) is because the computer without MSVC doesn't have the correct netframe, thats the reason I started plain Win32 / MFC because .NET projects arent very portable.
Downloading http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en
should fix the problem on the other computer.

William Hemsworth 1,339 Posting Virtuoso

To Build the project in release, click on the drop down menu by the run icon and set it to 'Release' then compile it. The program should be under the directory 'Visual Studio 2008\Projects\PROJECTNAME\Release\PROJECTNAME.exe'

William Hemsworth 1,339 Posting Virtuoso

The other computer you are testing it on probably does have the required .NET framework to execute the program.

William Hemsworth 1,339 Posting Virtuoso

I made a game in Win32 but it was quite difficult. It is called the 'SameGame' or commonly known as bubblebreaker mainly for phones, It might just give you an idea of how difficult it is to make these kind of games using Win32.

William Hemsworth 1,339 Posting Virtuoso

For C you can use these functions:

#include<iostream>
using namespace std;

typedef unsigned char UCHAR;

template<class t> inline
char *toBase(t val, char base, char *values) {
	register char d = 1; t c;
	register bool _signed = val < 0;

	if (val >= 0) for (c = base; c <= val; c *= base, d++);
	else for (c= -base; c >= val; c *= base, d++);

	register char i = d + _signed;

	char *bin = new char[i + 1];
	if (_signed) bin[0] = '-';

	for (val *= base; i - (_signed); i--)
		bin[i - 1] = values[(val /= base, (
		(val % base) < 0 ? -(val % base) : (val % base)))];

	bin[d + _signed]='\0';
	return bin;
}

inline char GetIndex(char *str, char c) {
	for(UCHAR i = 0;; *str, i++)
		if(*str++ == c) return i;
	return 0;
}

template<class t> inline
t fromBase(char *val, char base, char *values) {
	t v = 0;
	for (char i=val[0]=='-';val[i];i++) {
		v*=base;
		v+=GetIndex(values, val[i]);
	}
	return val[0]=='-'?-v:v;
}

int main() {

	// 0100101111111 in hex
	int decimal = fromBase<int>("0100101111111", 2, "01");
	char *hex = toBase(decimal, 16, "0123456789ABCDEF");
	cout << hex << '\n';

	// 3F16 in binary
	decimal = fromBase<int>("3F16", 16, "0123456789ABCDEF");
	char *bin = toBase(decimal, 2, "01");
	cout << bin << '\n';

	cin.ignore();
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

Can you post your code?

William Hemsworth 1,339 Posting Virtuoso

Or without any logical operators:

int min3(int a, int b, int c) {
	for (int i = 0;; i++) {
		if (!(a - i)) return a;
		if (!(b - i)) return b;
		if (!(c - i)) return c;
	}
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

Heres a way of doing it without < > <= >=

#include<iostream>
using namespace std;

int min3(int a, int b, int c) {
	for (int i = 0;; i++) {
		if (i == a) return a;
		if (i == b) return b;
		if (i == c) return c;
	}
	return 0;
}

int main() {
	cout << min3(77,24,879);  // output 24
	cin.ignore();
	return 0;
}
William Hemsworth 1,339 Posting Virtuoso

Here is a way to do it, I made a function GetWord which will return a word depending on the index and the gaps you give it. It will loop through all the words and count number of words that match. Hope it helps.

#include<iostream>
using namespace std;

inline bool TextContains(char *txt, char ch) {
	while (*txt) if (*txt++ == ch)
		return 1;
	return 0;
}
inline char *SubStr(char *text, int beg, int end) {
	register int len = end - beg;
	char *cut = new char[len];
	memcpy_s(cut,(rsize_t)len, &text[beg], (size_t)len);
	cut[len] = '\0';
	return cut;
}
int CountWords(char *text, char *gaps) {
	register bool t = 0, ot = 0;
	register int wc = 0, i = 0;
	while (TextContains(gaps, text[i])) i++;
	for (;text[i];i++) {
		t = TextContains(gaps, text[i]);
		if (t != ot) wc++;
		ot = t;
	}
	return (wc/2)+1;
}
char *GetWord(char *text, char *gaps, int bzIndex) {
	int i=0, sc=0, ec=0, g=0;
	for (;text[i] && TextContains(gaps,text[i]);) i++;
	for (sc = i; text[i]; i++) {
		if (TextContains(gaps, text[i])) {
			while (text[i] && TextContains(gaps, text[i+1])) i++;
			if (++g == bzIndex) sc = i + 1;
		} else if (g == bzIndex) {
			while (text[i] && !TextContains(gaps, text[i])) i++;
			ec = i;
			break;
		}
	}
	return SubStr(text, sc, ec);
}

int main() {
	char text[] = "Hello World! Hello World! Hello World!";
	char word[] = "Hello";
	int count = 0;

	for (int i = 0; i < CountWords(text, " !"); i++) {
		if (strcmp(GetWord(text, " !", i), word)==0)
			count++;
	} …