Tom Gunn 1,164 Practically a Master Poster

Thus a void pointer seemed to be the most powerful way.

Void pointers are powerful, but you lose any kind of type checking when you use them. That is the trade off. This message system has the same problem that printf() does, and which the iostream library overcomes. There is no way to check that the argument types match the format string.

The only thing I can think of without overhauling the entire system to be type safe is a master template:

template <class T1, class T2, class T3, 
          class T4, class T5, class T6>
void gFont::AddTest (int passedPosition, 
                     std::string passedString, 
                     T1 &var1=T1(), T2 &var2=T2(), T3 &var3=T3(),
                     T4 &var4=T4(), T5 &var5=T5(), T6 &var6=T6())

With the default values you can pass fewer than the maximum and just ignore the ones that are not in the format string. As long as the master template supports as many parameters as you pass, it will work.

Tom Gunn 1,164 Practically a Master Poster

is there a way to change a member void pointer to an int pointer?

The member is a void pointer, that will not change unless you change the type in your class definition. The only way to turn the void pointer into an int pointer is to cast it when you need an int pointer, as in my example.

Also, is there a way to know the type of passed pointer? Let's say I pass an int* to Do(void* p). How can I figure out that int* was passed?

You can do it, but not with void pointers unless you want to write a smart pointer class that knows the type. Using templates and RTTI will give you enough information to figure out what type of pointer was passed:

#include <iostream>
#include <typeinfo>
#include <string>

template <typename T>
void function(T* p)
{
    if (typeid(T) != typeid(int))
    {
        std::string actualType = typeid(T).name();
        throw std::invalid_argument(actualType + "* does not match int*");
    }

    std::cout << *(int*)p << '\n';
}

int main() try
{
    int ivalue = 123;
    double dvalue = 123;
    int *pi = &ivalue;
    double *pd = &dvalue;

    function(pi);
    function(pd);
}
catch (std::exception const& e)
{
    std::cerr << e.what() << '\n';
}

But I think you are probably doing something unnecessary. The actual type of a void pointer should be well known or not needed. If you need it, your design needs work. So what are you writing that needs this kind of type check?

Tom Gunn 1,164 Practically a Master Poster

Cast the void pointer when you want to use it as an int pointer, not when you want to store it as a void pointer:

#include <iostream>

class A;
class B;

class A
    {
    public:
        A():      pVar(0){};
        
        void*     pVar;
    };

class B
    {
    public:
        B(){};
        void      Do(void *passedVar);
    };

void B::Do(void *passedVar)
    {
    A* a = new A;
    a->pVar = passedVar;

    std::cout << *static_cast<int*>(a->pVar) << '\n'; 
    }

int main()
    {
    B* b = new B;
    int value = 123;
    int*cVar=&value;

    b->Do(cVar);
    }
Tom Gunn 1,164 Practically a Master Poster

Try this:

IDirectSound8* pDS8 = NULL;

HRESULT hr = DirectSoundCreate8(NULL, &pDS8, NULL);

And are you linking with the direct sound lib?

Tom Gunn 1,164 Practically a Master Poster

cannot convert parameter 2 from 'LPDIRECTSOUND8' to 'LPDIRECTSOUND8 *'

This probably means that parameter 2 is an output parameter and needs to be a pointer:

HRESULT hr = DirectSoundCreate8(NULL,  &ppDS8, NULL);

I do not know much about the DirectSound API, so that is the best I can help without pretending I know by reading MSDN. ;)

Tom Gunn 1,164 Practically a Master Poster

The order of cin.clear() and cin.ignore() is backward. cin.ignore() is just as much a read as cin.get() , so if the stream is in an error state, nothing will be read. The code needs to clear first, then ignore:

if (!cin)
{
    name.clear();
    cin.clear();
    cin.ignore(256, '\n');
}

I also added '\n' to the call because the delimiter defaults to EOF. That turns cin.ignore() into a blocking read because it waits for up to 256 characters or EOF.

tux4life commented: Perfect! +19
Tom Gunn 1,164 Practically a Master Poster

Your inner loop does not account for the name being accepted and there is no way to break out of it without somehow signaling a character that has a value of 0. This will work better:

while (!name_accepted && cin.get(ch))

Otherwise the code works fine.

Tom Gunn 1,164 Practically a Master Poster

Could I suppose this is the rules of c++?

Yes. The methods of a class can see everything in the class regardless of the access level. That is because a class can always see its own privatemost stuff. This is all at the class level, not the object level. When classes are instantiated into objects, the objects follow the rules of the class.

It is the same way with friends. When you declare a friend class or function, that class or function can see everything regardless of which object you give it.

Tom Gunn 1,164 Practically a Master Poster

If you are trying to initialize the array inside a class definition, that will not work. To initialize like that the array needs to be global, local to a namespace, or local to a function.

Tom Gunn 1,164 Practically a Master Poster

Correctly in that you get two true results? Do you get the same result if you print everything just before the if statement?

Tom Gunn 1,164 Practically a Master Poster

File:f:\dd\vctools\crt_bld\self_x86\crt\src\fgetc.c
Expression: (stream !=NULL)

This is an easy one. The stream you passed to fgetc is NULL. It means fopen returned NULL because the file could not be opened for some reason. Check the result before using it:

FILE* fp = fopen(file, mode);

if (!fp)
{
    perror("fopen");
    exit(EXIT_FAILURE);
}

Replace exit() with whatever recovery method you want. :)

Tom Gunn 1,164 Practically a Master Poster

Did you print the result of the expression to see what happens? :)

cout << hex << header[0] << '\t' 
     << boolalpha << (header[0] == 0xFF) << '\n';
cout << hex << header[1] << '\t'
     << hex << (header[1] & 0xE0) << '\t'
     << boolalpha << ((header[1] & 0xE0) == 0xE0) << '\n';
Tom Gunn 1,164 Practically a Master Poster

Add a cout statement to print the bytes right after reading them. Debuggers sometimes lie, and it could be telling you they are 0x00 when they really are not.

Tom Gunn 1,164 Practically a Master Poster

Old C meaning the latest standard will not allow it. If you compile as C89, the implicit int works, but if you compile as C99, it will throw an error. gcc supports both standards, so it depends on your compiler settings.

tux4life commented: Clean, sweet, and solid! +18
Tom Gunn 1,164 Practically a Master Poster

Check the header variable between the file.get() and f.setHeader(). Are the bytes the right value and in the right order? Then check it again after f.setHeader() is called and make sure that the bytes have not changed.

Tom Gunn 1,164 Practically a Master Poster

Can you give an example of a sequence of bytes that should pass the test but does not?

Tom Gunn 1,164 Practically a Master Poster

You do not need to pair isupper and tolower. If the character passed to tolower does not have a lower case equivalent then the same character will be returned:

#include <iostream>
#include <string>
#include <cctype>

int main()
{
    using namespace std;

    string input;

    cout << "Enter a word: ";
    cin >> input;

    for (int i = 0; i < input.size(); i++)
    {
        input[i] = tolower(input[i]);
    }

    cout << input << '\n';
}

Why does the word need to be added to an array? Can it not be changed in place like my example? If not, a string would be much better than an array because with an array you have to figure out the size and do other stuff that is not necessary in C++.

Tom Gunn 1,164 Practically a Master Poster

The fstream class is declared in the <fstream> header, not <iostream> or <stdio.h>. And a function needs to be declared before it can be used. You can declare it by moving the definition before main like my last example, or by adding a prototype before main and leaving the definition in the same place as your code:

#include <iostream>
#include <fstream>

using namespace std;

void GetNext(fstream& is);

int main()
{
    fstream file("test.txt", ios::in | ios::out | ios::binary);

    GetNext(file);
    GetNext(file);
    GetNext(file);
}

void GetNext(fstream& is)
{
    cout << (char)is.get() << '\n';
}
Tom Gunn 1,164 Practically a Master Poster

Try it and see. Like I mentioned already, testing this stuff is easy easy. :)

Tom Gunn 1,164 Practically a Master Poster

Not without doing some kind of explicit mapping:

#include <iostream>
#include <string>

enum Color {Red, Blue, Green};

static std::string ToString(Color color)
{
    switch (color)
    {
        case Red:   return "Red";
        case Blue:  return "Blue";
        case Green: return "Green";
        default: return "";
    }
}

int main()
{
    Color color = Red;

    std::cout << ToString(color) << '\n';
}
Tom Gunn 1,164 Practically a Master Poster

Plus,

Doing

file.get(header,4);
file.seekg(-4,ios::cur);

gets the get pointer back in its original point? I'm kinda confused with this :S

Stand up and take 4 steps forward, then take 4 steps back. Now you are right where you started. This is the same principle expressed as C++ code. :)

Tom Gunn 1,164 Practically a Master Poster

The get and set pointers will not revert to their value before the function was called when the function returns because the stream object needs to be passed as a reference. Try passing by value and you will get an error. ;)

The behavior is easy to test:

#include <iostream>

void GetNext(std::istream& is)
{
    std::cout << (char)is.get() << '\n';
}

int main()
{
    GetNext(std::cin);
    GetNext(std::cin);
    GetNext(std::cin);
}
Tom Gunn 1,164 Practically a Master Poster

Two instances of undefined behavior, three if your compiler does not support void main.

  1. The i variable is uninitialized. Anything could be in that memory space, and you are not allowed even to read it.
  2. A sequence point is only guaranteed after all of the function arguments are evaluated. Modifying a variable more than once between sequence points is undefined.

In other words, anything could happen and there is no way to explain your output that is consistent.

Tom Gunn 1,164 Practically a Master Poster

Can you explain your design? A Frame is an Mp3, but an Mp3 has a list of Frames, so an Mp3 has a list of Mp3s? Why does Frame need to inherit from Mp3? That does not make sense to me, but I admit that I only know enough about Mp3s to play them. ;)

The error you are getting means that Frame is not defined when Mp3 is defined, but Mp3 uses Frame in the class definition. Problems like that can usually be solved by forward declaring the class being used:

class Frame;

class Mp3 {
	list<Frame> frames;
	fstream myfile;
	unsigned long length;
public:
	char * name;

	Mp3(){}
	Mp3(const char * n);
	const char * Getname();
	unsigned long getLen(const char * path);
	bool isOk();
	bool getFirstFrame(Frame& f);
	list<Frame> getFrames(const char * path);
	int visitFrames(FrameVistior fv);
	void WriteFrame(Frame fr, FILE * dst);
};

But I am not sure that fixing the actual error makes as much sense as solving what might be a design problem.

Tom Gunn 1,164 Practically a Master Poster

since generating 1 from (float)rand()/RAND_MAX has low odds

I am not good at taking people's word. ;) Why does (float)rand()/RAND_MAX have low odds of generating 1 and how does it justify adding .1 in all cases?

Tom Gunn 1,164 Practically a Master Poster

Did not know you could override properties!(This is true is it?)

It is true. Properties can also be part of an interface.

Tom Gunn 1,164 Practically a Master Poster

I think a property is better because the method has extra syntax that is not needed. But they both do the same thing and are close enough that you should pick the one you like better.

Suppose I want to derive from a Square class, call it a SuperSquare class, what is the best option?

Properties can be virtual. Adding inheritance and polymorphism to the question does not change the answer. :)

Tom Gunn 1,164 Practically a Master Poster

Your function generates a random number in the range of [0..RAND_MAX), not in the range of [1..5). The easiest trick for fixing the range is the remainder operator:

i = rand() % 4 + 1;

The remainder of division from RAND_MAX by 4 will always result in a value in the range of [0..4), or 0, 1, 2, and 3. Adding 1 to that shifts the range to [1..5). The easiest trick might not be the best trick if rand() does not have good randomization of low order bits.

The random() function should probably do something like this, with whatever random trick you want:

int random(int lb, int ub)
{
    return std::rand() % (ub - lb) + lb;
}

Then in the calling function, call random() in a loop 8 times:

for (int x = 0; x < 8; ++x) cout << random(1, 5) << '\n';
Tom Gunn 1,164 Practically a Master Poster

Plenty of questions, plenty of weak programmers, or both ?

Yes. :D

Tom Gunn 1,164 Practically a Master Poster

It's not because you quickly want to test out some code that you may use bad coding styles.
Bad coding styles are considered: bad, so you don't have to use them, under any circumstances.

That rationalization might work when you preach to the choir, but everyone else needs a better reason. :) The better reason is that you are not just a tutor but a role model too. If you use bad coding practices then those practices will be emulated. If you use good coding practices then *those* practices will be emulated. Set a good example because you do not need to create more questions by training weak programmers. There are already plenty. ;)

tux4life commented: The better example is in place here :) +18
Tom Gunn 1,164 Practically a Master Poster

You have textBox1 and textBox2. From the names I guess you dragged and dropped using the visual designer. What that does is generate a partial class for you with all of the dirty work of creating and placing controls. You can look at that code by finding the <filename>.Designer.cs file in your project that corresponds to the <filename>.cs file.

All of that extra fluff takes space and adds complexity, so I did it manually by creating controls and putting them directly into the form class without using a partial class. My _sentence and _vowelCount are the same as your textBox1 and textBox2.

Tom Gunn 1,164 Practically a Master Poster

Have you tried opening with FILE_APPEND_DATA instead of GENERIC_WRITE?

Tom Gunn 1,164 Practically a Master Poster

infile is local to the if statement and the file gets closed when the if statement ends. Inside the loop, the file is closed, the object pointed to by the pointer is gone and you are not allowed to dereference the pointer anymore. Even if you have a pointer to an object, you need to make sure that the object still exists as long as the pointer is being used:

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

int main(int argc, char *argv[]) {
    istream *fin = &cin;
    ifstream infile;

    if(argc > 1) 
    {
        infile.open(argv[1], ios::in);
        if (!infile) return 1;
        fin = &infile;
    }

    while (1)
    {
        char c;
        fin->get(c);

        if (! *fin) break;
        cout.put(c);
    }
    return 0;
}
Tom Gunn 1,164 Practically a Master Poster

Static members of a class still need to be defined outside of the class, and in a file that will not be included multiple times like a header:

// globals.h
#include <string>

struct car
{
	std::string type;
	std::string brand;
	std::string manufacturer;
	std::string engine;
	int cylinders;
	std::string tyres;
};

public class globals
{
public: 
	static car test[100];
};
// globals.cpp
#include "globals.h"

car globals::test[100];
Tom Gunn 1,164 Practically a Master Poster

For a good block cipher the responsible thing to do is change the constraint to expect cipher text length instead of plain text length or change the limit of the plain text to be short enough to meet the current database constraint. If you use a block cipher it is easy to figure out the size of the cipher text because it will be a multiple of the block size for the algorithm.

For example, if you want to use Blowfish and the plain text limit is 15 characters, that is 30 bytes for C#'s char type and the next block multiple is 32 bytes because Blowfish uses a block size of 8 bytes. Then you need to add the overhead of a text representation like base 64. Base 64 adds 4 characters to the string for every 3 bytes and does some padding for lengths not divisible by 3. To hold the base 64 cipher text of 15 two byte characters the database constraint should grow from 15 characters to 44 characters.

Growing the database constraint is better than shrinking the application constraint because if you do the math, the plain text length would have to be very small for 15 base 64 characters.

If you really want the cipher text to have the same length as the plain text, look into stream cipher algorithms. AES can be run in a mode called CFB that turns it into a stream cipher. Or you can use any …

Tom Gunn 1,164 Practically a Master Poster

You can do it, but I think a better way is to have a Clone() method in the Animal class that the child classes override. Then all you need to do is this:

foreach (Animal d in AnimalBufferList)
{
    Add(d.Clone());
}
sknake commented: Thats what I would do +6
Tom Gunn 1,164 Practically a Master Poster

You are kind of missing the point of the KeyDown event. It gets fired when a new character is added to the text box, and only that new character needs to be checked for a vowel. With a label holding the running total and being updated each time the event is fired, there is no need for a button. Here is a simple form that shows what I mean:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Daniweb
{
	class MainForm: Form
	{
		#region Form Controls
		private TextBox _sentence;
		private Label _vowelCount;
		#endregion

		private int _vowels = 0;

		public MainForm()
		{
			SuspendLayout();

			_vowelCount = new Label();
			_vowelCount.Dock = DockStyle.Top;
			UpdateCount();
			Controls.Add(_vowelCount);

			_sentence = new TextBox();
			_sentence.Dock = DockStyle.Top;
			_sentence.KeyDown += _sentence_KeyDown;
			Controls.Add(_sentence);

			ResumeLayout();
		}

		void _sentence_KeyDown(object sender, KeyEventArgs e)
		{
			if (IsVowel(e.KeyData)) ++_vowels;
			else
			{
				// handle backspacing and deleting if you want
			}

			UpdateCount();
		}

		private bool IsVowel(Keys key)
		{
			return key == Keys.A ||
			       key == Keys.E ||
			       key == Keys.I ||
			       key == Keys.O ||
			       key == Keys.U;
		}

		private void UpdateCount()
		{
			_vowelCount.Text = "There are " + _vowels + " vowels.";
		}
	}
}
Tom Gunn 1,164 Practically a Master Poster

But that means I still have to retain my original code where I have it under:
private void btnCount_Click(object sender, EventArgs e)
is that right?

If you still want to have the same behavior on a button click that you do now, yes. But keeping a running count means you do not need to have a separate button that counts all vowels from scratch.

Btw, if I write the private int _vowels = 0; I got an error saying that expected token. What does it mean?

You may be adding it to the wrong place. _vowels is a field for your form class, not a local variable. The code I gave has it in the right place. Make sure that you do the same thing and it should work.

Tom Gunn 1,164 Practically a Master Poster

The event is fired for each character. You do not need to loop over everything that has already been tested in the text box. Test just that one character and add to a count field:

public class Form1
{
    private int _vowels = 0;

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        // you write IsVowel()
        if (IsVowel(e.KeyData)) ++_vowels;
        else
        {
            // handle backspacing and deleting if you want
        }

        labelCount.Text = _vowels.ToString();
    }
}
Tom Gunn 1,164 Practically a Master Poster

You can do it with the KeyPress or KeyDown event for the text box. Both of those have event args that tell you what key was pressed.

Tom Gunn 1,164 Practically a Master Poster

Good OO design is like good code. You know it when you see it, but it is not something that can be taught. There are guidelines to get started, but the real teacher is experience with what works and what does not.

Tom Gunn 1,164 Practically a Master Poster

I still need to figure out if there are other options.

There are other options, but not for two unsorted strings. Most intersection algorithms assume that both sets are sorted and use an algorithm that is both fast and uses little or no extra memory.

Tom Gunn 1,164 Practically a Master Poster

If the two strings are not sorted, the 'best' way depends on what trade off you want to make. If you want to have a small memory footprint but slower algorithm your way is fine. If you want to have a faster algorithm at the cost of more memory, two histogram tables is a good way:

define sa as array[0..CHAR_MAX] = {0}
define sb as array[0..CHAR_MAX] = {0}

// build the histograms
for x = 0 to a.length
    ++sa[a[x]]
loop

for x = 0 to b.length
    ++sb[b[x]]
loop

// print the unique intersection
for x = 0 to CHAR_MAX
    if sa[x] <> 0 and sb[x] <> 0 then
        print x as char
    end if
loop

In C that comes out to about a 10 line function and it has O(n) time complexity.

Tom Gunn 1,164 Practically a Master Poster

There is not a portable way to set a window title. The best you can do is have something like a appsys.h header with all of the non portable stuff:

#ifndef APPSYS_H
#define APPSYS_H

bool ChangeConsoleTitle(const char *title);

#endif
#include <windows.h>
#include "appsys.h"

bool ChangeConsoleTitle(const char *title)
{
    // windows API
    return SetConsoleTitle(title);
}

This separates the non portable code from the portable code. In the portable code, call ChangeConsoleTitle and when porting to a new system, just change the definition of ChangeConsoleTitle.

Tom Gunn 1,164 Practically a Master Poster

Is this array initialization static or dynamic?

C++ does not allow an array with a size that is not constant. If your compiler compiles that declaration and it runs, then the documentation will tell you how it works. I assume it has the same behavior as an array created with alloca(). alloca() is not a standard C++ function, by the way. ;)

Tom Gunn 1,164 Practically a Master Poster

Is there ANY standards compliant way to get unbuffered input from the console without the characters being automatically displayed?

Short answer, no. The console does its own buffering, and then C++ does another level of buffering for performance. You can change C++'s buffering, but that only affects performance. By the time your program gets the characters, they have already been displayed on the console.

The only way to change the console's buffering is with a system level API, and that is not portable. That is what getch() does, but the standard does not define a function with getch()'s behavior.

Tom Gunn 1,164 Practically a Master Poster

3) wrong, you only create a pointer of type char, this can't hold a string.

The next line assigns the pointer to a string constant:

char *abc;
abc="xyz";

There is no problem here, and the string is read only. It is the same to initializing directly:

char *abc = "xyz";

In fact, the compiler will probably reduce both ways to the same machine code.

tux4life commented: Thanks for the correction :) +16
Tom Gunn 1,164 Practically a Master Poster

What is problem with memory occurs here?because the code will run fine>

It is called a memory or resource leak. The memory you allocated from the first call to malloc is never freed, and for the rest of the program it will stay allocated and cannot be used anymore because you do not have a pointer to it.

The problem is that memory is finite, and fast memory is even more finite. The more you leak memory, the more often your program will dip into virtual memory pages. This slows the program down and if too much memory is leaked, can crash or freeze the whole machine.

a=(char*)malloc(100); /is ir required coz it refreshes in the next line
a=strste(b,"name");
//if memory allocated in this case so how to free it??
/* memory is allocated and the address is stored in a */
a=(char*)malloc(100);

/* memory leak. a now points somewhere inside b 
and the address returned by malloc is forgotten */
a=strste(b,"name");

//if memory allocated in this case so how to free it??

If you do not have at least one pointer to the address returned by malloc, freeing the memory is impossible. You need to wait until the program ends and the OS reclaims memory for the process. Or if the OS does not reclaim memory for processes, you need to wait until a reboot.

Tom Gunn 1,164 Practically a Master Poster

Isn't the memory released automatically when the program ends?

Yes and no. It depends on how your OS handles processes, but unless you work with some obscure or legacy systems, it is pretty safe to assume that when the program ends, all heap memory allocated to the process is freed by the OS.

The real danger of not freeing your own memory is if your code is reused in something longer lived. I've seen a lot of one off programs get hoisted into a library, and if those programs did not free their memory, they could have killed the hosting program by leaking away memory until a crash or freeze.

Tom Gunn 1,164 Practically a Master Poster

Code guards will work everywhere, but #pragma once will only work if the compiler supports it. What's worse, one compiler might define #pragma once to do the same thing as code guards and another compiler might define it to do something completely different. Your code would break on the second compiler.

If you have the option of choosing between two constructs with the same behavior, choose the one that is more portable.