ArkM 1,090 Postaholic

Of course, you can't access protected method in main! Only member functions of derived classes can access protected members.
Re-read your C++ textbook...

ArkM 1,090 Postaholic

>I am talking about the programming interface ArkM, it is drag and drop just like VB
>I'm out of this thread, tired of being treated like a dumbass.
I hope now you will have a time to read Qt documentation: Qt Creator (probably it's that damned drag and drop interface) is an optional tool in Qt SDK. You (and me) can create Qt GUI applications without any visual add-ons...

killdude69 commented: Thank you ArkM, for not doing like Siddhant and slandering my oppinion just because you didn't like it. Although your comment may have been passive aggressive, you did it in a way that wasn't too disrespectful. For that, I give you respect. +1
ArkM 1,090 Postaholic

>I have tried QT, it is like visual basic, you wouldn't tell a C++ programmer to go back down to VB programming would you?
Are you sure that it looks like VB?

MainWindow::MainWindow()
{
  spreadsheet = new Spreadsheet;
  setCentralWidget(spreadsheet);
  createActions();
  createMenus();
  createContextMenu();
  createToolBars();
  createStatusBar();
  readSettings();
  findDialog = 0;
  setWindowIcon(QIcon(":/images/icon.png"));
  setCurrentFile("");
}
...
bool MainWindow::okToContinue()
{
  if (isWindowModified()) {
    int r = QMessageBox::warning(this, tr("Spreadsheet"),
                 tr("The document has been modified.\n"
                 "Do you want to save your changes?"),
                 QMessageBox::Yes | QMessageBox::Default,
                 QMessageBox::No,
                 QMessageBox::Cancel | QMessageBox::Escape);
    if (r == QMessageBox::Yes) {
        return save();
    } else if (r == QMessageBox::Cancel) {
        return false;
    }
  }
  return true;
}
...
void MainWindow::updateRecentFileActions()
{
  QMutableStringListIterator i(recentFiles);
  while (i.hasNext()) {
    if (!QFile::exists(i.next()))
    i.remove();
  }
  for (int j = 0; j < MaxRecentFiles; ++j) {
    if (j < recentFiles.count()) {
      QString text = tr("&%1 %2")
                     .arg(j + 1)
                     .arg(strippedName(recentFiles[j]));
      recentFileActions[j]->setText(text);
      recentFileActions[j]->setData(recentFiles[j]);
      recentFileActions[j]->setVisible(true);
    } else {
      recentFileActions[j]->setVisible(false);
    }
  }
  separatorAction->setVisible(!recentFiles.isEmpty());
}
ArkM 1,090 Postaholic

May be it helps (see modf function: split integer and fractional parts):

/**
 *  2008-10-01 Beta version. No warranties...
 *  Rounding functions freeware mini-package.
 *  About rounding forms and MS rounding stuff
 *  see http://support.microsoft.com/kb/196652
 *  Dependencies: <math.h> <float.h>
 *  Languages: standard C and C++
 *  Not optimized!..
 */
/** Not-optimized 10 power n (n > 0) */
static double tenpow(int n) {
    double y = 10.0;
    while (--n > 0)
        y *= 10.0;
    return y;
}
/** 64-bit double precision ~ 15 digits. */
static int nMax = DBL_DIG; /* from float.h */

/** Round off with Banker's method, n in -15..15 */
double Round(double x, int n) {
    bool neg = (x < 0.0);
    double ipart, fpart;
    double y, p;
    int id;
    if (neg)
        x = -x;
    if (n > 0) {
        double yy;
        fpart = modf(x,&ipart);
        if (n > nMax)
            n = nMax;
        p = tenpow(n);
        y = fpart * p;
        fpart = modf(y,&yy);
        if (fpart < 0.5)
            fpart = 0.0;
        else if (fpart > 0.5)
            fpart = 1.0;
        else { /* Banker's Method */
            id = (int)fmod(yy,10.0);
            fpart = (id&1)? 1.0: 0.0;
        }
        yy += fpart;
        y = ipart + yy / p;
    }
    else if (n < 0) {
        if (n < nMax)
            n = -nMax;
        p = tenpow(-n);
        y = x / p;
        y = Round(y,0) * p;
    }
    else { /* n == 0 */
        fpart = modf(x,&ipart);
        if (fpart > 0.5)
            ipart += 1.0;
        else if (fpart < 0.5) …
ArkM 1,090 Postaholic

There is freeware Qt for Windows now (from April 2009). There are some other freeware GUI libs for Windows - as usually, they are portable too.

ArkM 1,090 Postaholic

How would I test if it IS empty.
Because I am currently using: if (fileName == "")

And I am using this for over 6 if statments.

Didn't you familiar with logical not operator?

if (!*fileName)
// or
if (fileName[0] == '\0')
// or
if (strlen(fileName) == 0)

By the way, fileName == "" is equal to false in all cases. Why? Think about pointers comparison ;)

ArkM 1,090 Postaholic

Keep it simple:

fileName[0] = '\0';
// or even
*fileName = 0;
// to test:
if (*fileName) { // non-empty

;)

ArkM 1,090 Postaholic

You can deallocate dynamically allocated memory here, there and everywhere:

int main()
{
  al = new Vertex*[numLocations];
  ...
  delete [] al; // al is visible
  ...
  // or
  f(al); // al as argument
  ...
}
...
void f(Vertex* p)
{
  delete [] p; // array of Vertex is deallocated
  ...
}

Name scope (name visibility) and storage duration (span of life) are different notions. In actual fact to deallocate memory obtained from operator new you need not al variable per se but the pointer value which refers to the memory chunk.

Daria Shmaria commented: helpful, clear, concise +1
ArkM 1,090 Postaholic

You didn't include <string> header in main.cpp (for std::getline declaration). Change "iostream" and "fstream" to <iostream> and <fstream> (standard headers).

You declare al variable in the if alternative block. Of course, this local variable is out of scope outside this block. Declare al at the main function body level - that's all.

Now you have:

if (numLocations == 0)
  { // it's a new scope
    Vertex ** al; // al is local in if alternative
    al = new Vertex * [numLocations]; // to breath al's last
  } // al is out of scope and is discarded.
  // and you have memory leak because can't free this memory
ArkM 1,090 Postaholic

tux4life, don't torment the unhappy C++ programmer, tell him/her about while(f>>i) construct ;)

tux4life commented: Srry, forgot to tell it :D +7
ArkM 1,090 Postaholic

Oh my God! Read your previous thread carefully:
http://www.daniweb.com/forums/thread194034.html

ArkM 1,090 Postaholic

1. here's this forum announcement: http://www.daniweb.com/forums/announcement8-3.html
[code=cplusplus] source

[/code]
2. See an example of these cmds parsing:

// don't forget to include <sstream>
typedef istringstream::pos_type Pos;
// cmd arg parsing sample only:
void cmdGet()
{
    string line, cmd, arg;
    bool intarg = false;
    int  iarg;
    cout << "Type instruction: "; // no need in flush
    if (getline(cin,line)) {
        istringstream is(line); // parse line
        if (is >> cmd) {    // get 1st token
            Pos pos = is.tellg();//save position
            if (is >> arg) {    // has arg
                is.seekg(pos);  // read again
                if (is >> iarg) // try to get int
                    intarg = true;
                else
                    intarg = false; // not-a-number
            } else { // no arg
                arg.clear(); // arg.empty() == true
            }
            // Process cmd & arg, for example:
            cout << cmd;
            if (!arg.empty()) { // has arg
                cout << ' ' << arg;
                if (intarg)
                    cout << " (integer)";
            }
            cout << endl;
        } else { // no cmd at all
            cout << "Try again...\n";
        }
    } else { // cin closed
        return; // ctrl-z on Windows, for example
    }
}

Try this. Adopt it (it's freeware in the public domain ;)...

ArkM 1,090 Postaholic

Of course, you have linker error because nobody (except you) knows such library function as concat (probably you want strcat).

The second attempt failed because fgets function puts the last '\n' character in the buffer (read library function specifications more carefully):

Input buffer after successful fgets:
<line contents><'\n'><'\0'>

So you must overwrite (or erase) this newline character when concatenate two lines to form output line.
Probably you want separate two output line parts with blank character. So replace the 1st line trailing newline with blank, for example:

int csz = strlen(c) - 1;
if (csz >= 0 && c[csz] == '\n')
    c[csz] = ' ';
/* or c[csz] = '\0'; to erase it at all */

Now use fprintf with double %s %s specifiers (see commented line in your snippet)...

Apropos, declare longer input buffers for file lines (at least 256, for example). Always test open result: if (file == NULL) { ERROR! } ...

ArkM 1,090 Postaholic

cout << r[0] << r[1] or cout << r.substr(0,2) ;)

siddhant3s commented: The first one was funny. +7
ArkM 1,090 Postaholic

Line by line, word by word:

void WordByWord(const char* filename)
{
    if (!filename)
        return;
    ifstream file(filename);
    string line, word;
    for (int lineno = 1; getline(file,line); lineno++) {
        cout << "Line #" << lineno << ":\n";
        istringstream words(line);
        while (words >> word)
            cout << word << '\n';
    }
}

Think ;)...

ArkM 1,090 Postaholic

It works:

template <typename T>
class Sample {
private:
	typedef std::vector<T> vectorType;
	vectorType vector;

public:
	typedef typename vectorType::iterator vectorIterator;
	vectorIterator begin();
};

template <typename T>
typename Sample<T>::vectorIterator Sample<T>::begin() {
	return vector.begin();
}

An example from the C++ standard:

template<class T> struct A {
  typedef int B;
  A::B b; // ill-formed: typename required before A::B
  void f(A<T>::B); // ill-formed: typename required before A<T>::B
  typename A::B g(); // OK
};

The keyword typename is required whether the qualified name is A or A<T> because A or A<T> are synonyms
within a class template with the parameter list <T>.

ArkM 1,090 Postaholic
ArkM 1,090 Postaholic

Declare class table member functions with const parameters:

bool insert(const TKT& inskey, const TDT& insdata);
...

Consider anytable.insert(6,"john") . It's impossible to bind non-const std::string reference to char array "john". However it's possible to bind const std::string reference to temporary std::string object produced by "john" => std::string("john") conversion.

Yet another remark: type aliases TKT and TDT do not clarify your code (quite the contrary)...

ArkM 1,090 Postaholic

>i've been reading a lot of tutorials but none of them have been helpful for my scenario.
Without any doubt you didn't understand those tutorials. You have a classic linked list building scenario.

>...they all deal with int data and my data is of char type dynamically allocated and read in from a file.
It does not matter where is your data source. A list does not know any files. It is of no importance what's the node data type. A list node essence is the link to the next node - that's all.

To add a new node:

allocate a new node, fill its data fields, set next member to NULL.
if a list is empty (head == NULL)
   set head to the new node; all done
else 
   find a pointer to the last list node *)
   set this node.next to the new node
endif

*) That's why a good list implementation maintains not only head but also tail pointer! Otherwise you must traverse a list from the head upto the last node on every add node operation.

It seems you don't understand a pointer concept. Look at your code (lines 25-29):

expense::expense()
{
  head = NULL;
  head->cost = 0.0;
}

That's terribly badly!
The 1st statement says: head is a null pointer, it points to nowhere.
The 2nd statement: OK, let this nowhere gets zero to its cost member!
Better start from the beginning, re-read a wonderful tutorial …

ArkM 1,090 Postaholic

>i already did.
Where? If the 1st choice is 6, head == NULL after constructor.

ArkM 1,090 Postaholic

Of course, you got memory access exception: initial head == 0 but you are trying to assign new node pointer via this null pointer:

head->name = new char ...

Regrettably you did not set the language specifier into the code tag so no line numbers in your snippet. Next time use code tag properly:
[code=cpluplus] source

[/code]

You must set the 1st node pointer into the head member (you have an empty list at this moment).
Add the code yourself then come back (there are lots of other defects in the code ;)).

ArkM 1,090 Postaholic

Place this function into the separate .cpp file:

void ShowText(const char* filename)
{
    ::ShellExecuteA(::GetDesktopWindow(),
        "open",
        "notepad.exe",
        filename,
        0,
        SW_SHOWNORMAL);
}

Include <windows.h> dependency into this file only.
This function works in console applications too.

tux4life commented: Good job! +5
ArkM 1,090 Postaholic
class Stack // Capitalize the name, there is class stack in STL
{
  ...
  bool empty() const { return Top < 0; }
  ...
};

It's C++, not Pascal ;)

ArkM 1,090 Postaholic

how do i create a set method to get the fstream input file.

in need to be able to define the file location in the main method.

class a
{
private:
	ifstream fileOne;
	ofstream report1;
	
	
public:
	void setinput(std::ifstream& in);
	void setoutput(std::ofstream& out);
	
};

how can i code these set methods.

Use pointers:

class A // Better use capitalized names for your classes
{
public: // Better place public interface first
  A():inFile(0),report(0) {}
  void setinput(std::ifstream& in) { inFile = &in; }
  void setoutput(std::ofstream& out)
  {
    outFile = &out;
  }
  void report();
  ...
private: // it's not so interesting for the class user
  ifstream*  inFile;
  ofstream* outFile;
};
void A::report()
{
  if (outFile) {
    ofstream& f = *outFile;
    f << ...;
    ...
  } // else no output file settings...
}

Be careful: you must provide these fstream existence while A::report is working. So it's not a very robust architecture (no matter with or w/o pointers).

newcook88 commented: THank you for the Help:) +1
ArkM 1,090 Postaholic

Hi
I want to have a n*n matrix
is there sombody to help me??
how i can write it??

Start from this forum announcement: http://www.daniweb.com/forums/thread78060.html
(especially Describe your problem clearly and fully! paragraph).

ArkM 1,090 Postaholic

>i hope i did tag right on code posted.
Alas, correct tags are:
[code=cplusplus] source

[/code]

ArkM 1,090 Postaholic

1. string is not defined as a variable in C++. Use char* or char[50] instead.
2. str="ABCDEFGHIJK"; is erroneous. Use strcpy() or the like instead.

Thanks...

??? What's a nonsense?

ArkM 1,090 Postaholic

1. Next time use code tag with the language specifier:
[code=cplusplus] source

[/code]
2. Double apostrophes (empty character constant) is not a valid construct in C++ (have you ever seen the compiler diagnostic messages? ):

cout<<str2+''+str3+''+str1<<endl;

Use ' ' for the space character.

ArkM 1,090 Postaholic

Better YOU take a paper and a pencil and try to push 2 elements in the stack with DEFAULT_SIZE == 1. Do it step by step and see that you DON'T RESIZE a stack when the 2nd element is added.

ArkM 1,090 Postaholic

That's it:

if ( top_ == size )
    resize();

See what happens:
0. empty stack of size 1 (for simplicity); top_ = -1
1. push; top_ != size, OK, top_ = 0 now, stack full!
2. push again: WARNING: top_ != size, NO resize!!! ...
... and you overwrite allocated memory ...

I think it's so easy to correct the code.
Do it yourself ;)

ArkM 1,090 Postaholic

1. Would that also work for a "float2String" function?
2. ... But I'd be happy to change it if you just give me a suggestion...

1. Yes, it works for short, long, float & double...
2. Variant(s):

/// w/o test s.size() >= sizeof(dWord)
dWord string2int(const std::string& s)
{
    dWord dw;
    ::memcpy(&dw,s.data(),sizeof dw);
    return dw;
}
// or for any non-class type
template<typename POD>
bool string2pod(const std::string& s, POD& pod)
{
    if (s.size() >= sizeof pod) {
        ::memcpy(&pod,s.data(),sizeof pod);
        return true;
    }
    return false;
}
ArkM 1,090 Postaholic

Sorry, I don't understand:
>why when i do buff[i]=0; ...
No such assignment in the squeeze function!
WHY and WHERE you do buff[i]=0 ?!

ArkM 1,090 Postaholic

If the program runs on a little-endian computer:

inline
std::string int2String(dWord n) // unsafe programming
{
    char* p = reinterpret_cast<char*>(&n);
    return std::string(p,sizeof n);
}

Platform-independent (more precisely, LSB/MSB-independent) code is a few cumbersome...

Apropos, your *reinterpret_cast<dWord*>(...) expression is not portable at all: how about proper (for dWord* pointer) alignment of str.data() pointer?..

ArkM 1,090 Postaholic

I want to make an input stream parser capable of handling input in any of the following forms:

x y z
x,y,z
x, y, z
(x,y,z)
(x, y, z)

Is there a clever way to do this? Or do I have to check the first character, if it is '(' then do one thing, if it is not then read a double, then check if the next character is a ',', etc etc.

Is there a robust way to handle these types of inputs?

Of course, there is a robust way...
That's it:

I have to check the first character, if it is '(' then do one thing, if it is not then read a double, then check if the next character is a ',', etc etc.

ArkM 1,090 Postaholic

>i began reading K&R ...
Well, let's read the next sentence after squeeze function definition:

Each time a non-c occurs, it is copied into the current j position, and only then is j incremented to be ready for the next character. This is exactly equivalent to

if (s[i] != c) {
       s[j] = s[i];
       j++;
   }

What else?
Better turn off your computer, take a sheet of paper and a pencil then try to squeeze a simple string (do it step by step)...

ArkM 1,090 Postaholic

how can i convert a hex value of a byte (unsigned char) to a short value?

unsigned char hexByte = 0x02;
short value= ???

thank you for your help!

As usually:

short value = hexByte;

What's a problem?

ArkM 1,090 Postaholic
if (x - y + abs(x-y)) { /* x > y */

;)

ArkM 1,090 Postaholic

See also ToLowerInvariant() function:
http://msdn.microsoft.com/en-us/library/system.string.tolowerinvariant.aspx.
MS recommends ToLowerInvariant for OS identifiers (file names, registry keys etc)...

ArkM 1,090 Postaholic

The answer: use anonymous namespace...

using std::cout;

class A // External linkage name
{
public:
    void f() { cout << "::A:f()\n"; }
};
namespace { // Internal linkage area:
    class A // Internal linkage name
    {
    public:
        void f() { cout << "LocalA::f()\n"; }
    };
    typedef A LocalA; // for local references
    void F() 
    {
        cout << "F()...\n"; 
        A a; a.f(); ::A aa; aa.f(); 
    }
}
// need type alias if ::A is visible here.
void FF() { cout << "FF()...\n"; LocalA a; a.f(); }

int main()
{
    F();
    FF();
	return 0;
}

Try this method for separate modules.
Moreover: anonymous namespace is a preferred way to force internal linkage in C++ (instead of C-style static keyword).

tux4life commented: Finally someone which just answers his question :) +4
ArkM 1,090 Postaholic

More precisely: v1 and v2 are initialized if both are well constructed empty vectors. The class vector default constructor (constructor without parameters) constructs an empty vector.
The C++ Standard:

A constructor is used to initialize objects of its class type.

Yet another example:

void Grid::Grid(const vector<int>& vi): v2(vi) {}

There is so called ctor-initializer list in this Grid constructor: v2 member now is directly-initialized by the value of this constructor parameter. It's a preferred form of a member initialization if there is a proper non-default constructor of this member class.

ArkM 1,090 Postaholic

And what for friend arith operators?

fraction operator+(const fraction& f) const;
...
ArkM 1,090 Postaholic

No problems with v1 and v2: these members constructors create empty vectors. You can initialize them in Grid constructor(s) or later in the special member function (let it's named as init or what else), for example:

explicit Grid::Grid(size_t n): v2(n), v3(n) {}
// or
void Grid::initv2(const std::vector<int>& v) { v2 = v; }
void Grid::initv2(const int* a, size_t n)
{
    v2.clear();
    if (n > 0) {
        v2.resize(n);
        for (size_t i = 0; i < n; i++)
            v2[i] = a[i];
}

However you can't declare std::vector<Obj> v1 from incomplete Obj declaration class Obj; : template std::vector wants complete element type definition.

ArkM 1,090 Postaholic

1. Use code tag with the language specifier:
[code=cpluplus] source

[/code]
2. We can't help you (mor precisely, we can't verify your solution) without class Stack definition. However I see that your Copy member signature is wrong. You never modify passed by value parameter. If you want to copy from *this to otherStack, use a reference to otherStack:

void Stack::Copy(Stack& otherStack);

3. Better try to overload Stack::operator=() and define copy constructor for this class. Essentially it's the same code as for Copy member.

ArkM 1,090 Postaholic
ArkM 1,090 Postaholic

Well, start from this forum announcement: http://www.daniweb.com/forums/announcement8-2.html

ArkM 1,090 Postaholic

Are you stupid or not - judge for yourself. I see at least two senseless fragments in your code:

total += pi1/pow(10.0,digits);

and

if (pi1 == total)

I can't understand the goal of the 1st one, and I see that you don't know a simplest thing: double numbers are approximations of real numbers so you have no chance to get exact equation in the 2nd one...
Moreover, OP title is incorrect. Probably you want to test (informally) if (abs(pi-sum_of_series) < 10^-n) . It does not bear a relation to rounding at all.

ArkM 1,090 Postaholic

1. It looks like a black cat in the dark room (from the user interface point of view). What's series #1, #2 etc?
2. You NEVER get pi1==counter : you forgot that doubles are real number approximations.

ArkM 1,090 Postaholic
double x=7839,total=0;
total=x/pow(10.0, 3);

Thank you, I have never seen so strange code as it ;)
have you ever seen 1000.0 constant?
What for total=0 initialization?
I see you don't understand my code at all.

total = round(x,3);
ArkM 1,090 Postaholic

Sorry, I don't understand: do you want to round zero to zero with 2 decimal positions precision? ;)
About rounding of 3.91: re-read my post again.
Try this code:

#include <cmath>

double round(double x, int n = 0)
{
    bool neg = (x < 0.0);
    double ipart, fpart, pow10 = 1.0;
    if (neg)
        x = -x;
    fpart = modf(x,&ipart);
    for (int i = 0; i < n; i++)
        pow10 *= 10.0; // faster than pow(10,n)
    fpart = floor(fpart*pow10+0.5)/pow10;
    x = ipart + fpart;
    return neg? -x: x;
}

const double pi = 3.14159265358;

int main()

{
    printf("%.15f\n",pi); // (I hate setprecision() ;)
    for (int i = 0; i < 12; ++i)
        printf("%.15f\n",round(pi,i));
    return 0;
}
/* Output:
3.141592653580000
3.000000000000000
3.100000000000000
3.140000000000000
3.142000000000000
3.141600000000000
3.141590000000000
3.141593000000000
3.141592700000000
3.141592650000000
3.141592654000000
3.141592653600000
3.141592653580000
*/

Remember: these numbers are not exact values!

ArkM 1,090 Postaholic

As usually (on this forum ;)), you OP don't understand floating-point type data semantics.

Floating-point numbers are approximations of real numbers. For example, double(3.14) is NOT equal (exactly) to 3.14, double(0.1) is NOT equal to 1/10. Try this and see what happens:

double d = 0.0;
for (int i = 0; i < 10; i++)
    d += 0.1;
if (d == 1.0)
    cout << "OK, 10*0.1 == 1\n";
else
    cout << "Oops, 10*0.1 != 1\n"; // This case!!!

Therefore it's IMPOSSIBLE to round double values to n DECIMAL digits exactly. Think about your specifications and desired effects...