Narue 5,707 Bad Cop Team Colleague

>T() does not produce a "null" value, right?
It produces a default constructed object for the type. In the case of std::string, it's an empty string.

>I wanted to assign a "null" value to the array element
Assigning "null" doesn't do anything meaningful in this case. What are you trying to accomplish?

>is there an equivalent in C++?
It depends on what you want to do. If you're worried about any of the cases where setting to "null" is useful, you've got fundamental design issues to iron out first. Personally, I don't see why it can't be as simple as this for your class:

#include <iostream>
#include <exception>
#include <stdexcept>
#include <string>

using namespace std;

template <class T, int size>
class Stack {
  T arr[size];
  int top;
public:
  Stack(): top(0) {}
  void push ( T obj );
  T pop();
};

template <class T, int size>
void Stack<T,size>::push ( T obj )
{
  if ( top >= size )
    throw runtime_error ( "Stack is full" );

  arr[top++] = obj;
}

template <class T, int size>
T Stack<T,size>::pop()
{
  if ( top == 0 )
    throw runtime_error ( "Stack is empty" );

  return arr[--top];
}

int main()
{
  Stack<string, 5> s;

  try {
    for ( int i = 0; i < 6; i++ )
      s.push ( "hello" );
  } catch ( exception& ex ) {
    cerr<< ex.what() <<'\n';
  }

  try {
    for ( int i = 0; i < 6; i++ )
      cout<< s.pop() <<'\n';
  } …
Narue 5,707 Bad Cop Team Colleague

Start by including the <string> header, which you failed to do. Also note that NULL isn't a compatible type with std::string; your stack class makes unwarranted assumptions about the type of T. Instead of NULL, you can generally use T() safely as a default value, though it's usually a better idea to design your class so as to not need a default value.

Narue 5,707 Bad Cop Team Colleague

>string a;
This is an empty string.

>a= tmp;
a doesn't exist. a is still an empty string. The subscript operator does not change the size of a collection.

freelancelote commented: Thanks a lot. +1
Narue 5,707 Bad Cop Team Colleague

>Hey guys. Just a question.
>Is it possible to [...]
The answer to any "Is it possible?" question is invariably "Yes!". Further, many of these questions can be answered with simple experimentation. So are you just lazy or what?

Narue 5,707 Bad Cop Team Colleague

>Is that the correct way to go?
No, you're passing entirely wrong types and the syntax is broken. What are you trying to do (aside from pass an ifstream reference)?

Narue 5,707 Bad Cop Team Colleague

You can't copy an istream object, pass a reference instead:

int wCount(ifstream& myFile);
Narue 5,707 Bad Cop Team Colleague

It's generally considered impolite to throw around non-universal acronyms without defining them.

Narue 5,707 Bad Cop Team Colleague

>I can cout the string literal by just stating the
>name of the object or I can use the data function.
Yes to the first part, no to the second. You can "cout the string" by passing just the string object, but it's not safe using the data member function because the data member function doesn't guarantee that the returned string is null terminated. If you change data to c_str, then it's safe.

That's the difference, by the way. c_str returns a null terminated C-style string, data returns a pointer to the first item in an array of characters (which may or may not be null terminated).

freelancelote commented: Thanks a lot. +1
Narue 5,707 Bad Cop Team Colleague

>I cant find it on my keyboard.
Oh dear. It's the vertical bar, placed as the shift value for my backslash key, but it could be somewhere else (or not present at all) depending on the keyboard. Note that the || operator is two vertical bars, not a single key on your keyboard. If you still can't find it, you may fall into the category of C programmers that need to take advantage of C's trigraph sequences:

#include <stdio.h>

int main ( void )
{
  if ( 0 ??!??! 1 )
    puts ( "True" );
  else
    puts ( "False" );

  return 0;
}

This does the same thing as my first example, except the ??! trigraph represents the vertical bar with a combination of universal characters. Here are all of the trigraphs if you discover you're missing other keys:

??>    }
??<    {
??)    ]
??(    [
??=    #
??!    |
??/    \
??'    ^
??-    ~

Before you use them, make absolutely sure that they're necessary, as trigraphs are clearly very detrimental to the readability of your code.

Narue 5,707 Bad Cop Team Colleague

If you don't mean the logical OR operator in C, example follows, then you need to be more specific about what exactly you want to do.

#include <stdio.h>

int main ( void )
{
  if ( 0 || 1 ) /* || is the logical OR operator */
    puts ( "True" );
  else
    puts ( "False" );

  return 0;
}
Narue 5,707 Bad Cop Team Colleague

>hoping someone can throw more light into this
It's quite simple on the surface. Your code is broken. ;) The long answer is that there's no intervening sequence point between the evaluation of function arguments, so you're invoking undefined behavior by modifying x multiple times between sequence points. Both of your compilers are correct, as is the hypothetical compiler that chooses to send a nasty email to your boss instead of printing anything.

Narue 5,707 Bad Cop Team Colleague

I can't decide if this is a joke or not. Anyway, the easiest way to look at the machine code (what people typically mean when they talk about "ones and zeros") is with a hex editor. Some hex editors even give you a binary view.

Narue 5,707 Bad Cop Team Colleague

>Im hoping that this might give me further insight.
Here's how I see it: You won't find out if the course is good until after they're taken your money, and chances are pretty good that at least one person on a forum such as Daniweb is way smarter than whoever designed the course. So why not save your money and ask for insights here instead?

On top of getting 1-on-1 help, specific answers to your specific questions, and the collective experience of a community of hackers and professionals, you're also $69 richer. It's a no-brainer. ;)

Narue 5,707 Bad Cop Team Colleague

It's your money, so you can spend it wherever you want. I wouldn't waste the money though; I have yet to hear about one of these online courses that wasn't a total rip off. You can learn more with free online resources than any course could provide.

Narue 5,707 Bad Cop Team Colleague

>Both will fulfill your need.
Though all things being equal, the first is arguably easier to prove correct without giving it much thought beyond knowing your "one past the end" value.

Narue 5,707 Bad Cop Team Colleague

>all right, i will take note of your advice.
>anyway,
Anyway, you clearly didn't bother to fully read and comprehend my previous post because my advice included a fix for your immediate problem.

>i just want to know why it does not work when
>i get the user to specify the file path instead.
Because you're doing it wrong. You're also comparing two different pieces of code as if they were the same. Here, look:

// This is what happens when you manually specify the name
// Note that I fixed your habitual syntax error by adding quotes
infile.open("C://cars.txt", ios::in);
// This is what happens when you use the string object,
// based on the exact contents of the string
infile.open("\"C://cars.txt\"", ios::in);

In the second example you're trying to open the file called "C://cars.txt", where the quotations are a part of the name. That's not the case on your file system, so the specified file does not exist. Is that clear enough for you?

And for future reference, you don't need to play games with double (back)slashes with input. The only time where a backslash makes a difference is in a string literal, where the backslash introduces an escape character:

const char *filename = "C:\file.txt"; // Wrong!

Since one backslash is an escape character, you need to use the escape character representing a backslash, which is two backslashes:

const char *filename = "C:\\file.txt"; // Correct

This doesn't apply to forward …

Luckychap commented: Simple great! +3
Narue 5,707 Bad Cop Team Colleague

>void main(){
main returns int. In C++ main returns 0 automagically, so you don't even have the excuse of saving keystrokes anymore.

>input2 = "\"" + input + "\"";
This is unnecessary. In fact, that's likely a big part of your problem.

>while(!infile.eof()){
The timing of eof() is such that this won't work. The eofbit is only set after you try and fail to read, which means that your loop has an off-by-one error.

Narue 5,707 Bad Cop Team Colleague

Then step through your code so you can at least pinpoint where the exception is thrown.

Narue 5,707 Bad Cop Team Colleague

>*What do I do to fix this?*
Figure out where you're trying to dereference a null pointer in your code.

Narue 5,707 Bad Cop Team Colleague

>when the list is in disorder for example (1,3,5,4) still
>says is in ascendent order. How could i fix that?
You wait until after the loop to print the result, obviously:

node *curr = head;

bool ascending = true;
bool descending = true;

while ( curr->next != 0 ) {
  if ( curr->data < curr->next->data )
    descending = false;
  else if ( curr->data > curr->next->data )
    ascending = false;

  curr = curr->next;
}

if ( ascending )
  cout<<"Ascending order\n";

if ( descending )
  cout<<"Descending order\n";

if ( !ascending && !descending )
  cout<<"No order\n";
Narue 5,707 Bad Cop Team Colleague

The nice thing about pseudocode is that you make up the rules. Most real languages do allow what you want, though, so you're not really deviating from common use.

Run.[it] commented: Cheers, top work as always! +2
Narue 5,707 Bad Cop Team Colleague

There aren't any. The only thing you'll get from a C certification is a lighter wallet.

Narue 5,707 Bad Cop Team Colleague

If you choose to make the table size prime, you should treat that as an invariant and make it prime with each resize as well. I say "if you choose to make the table size prime" because there are practical reasons for doing so, such as the hash function is weak and a non-prime table size promotes clustering, your collision strategy is known to work well with a prime size, has known issues with non-prime sizes, or you can't prove that your hash table will work correctly without a prime size (this is the most common situation).

So yes, if you choose a prime size, and it's not an arbitrary decision, you should maintain that decision throughout the life of the table.

Narue 5,707 Bad Cop Team Colleague

1) You know the size of the table and you can keep track of the load factor by modifying a counter when you add or remove a chain. This is pretty efficient.

2) Separate chaining is much more friendly when it comes to table size. Making it too small isn't a crisis because the chains grow as you need them, and making it too large will just waste space. Despite what some people will tell you, a lot of short chains is still fast, so as long as your hash function has a good distribution, you can get away with setting the initial size to the expected number of keys.

Narue 5,707 Bad Cop Team Colleague

>theres a special function for it?
Nope. The usual suggested solution is to programmatically simulate Alt+Enter. I do believe that searching our forums will give you the code to do so.

Narue 5,707 Bad Cop Team Colleague

>allow 10 accounts to be opened and then allow the user to search
>for each one and deposit and withdraw from each one
Well, start by allowing one account and work up from there. As a first attempt, I would suggest an array of account class objects. You need to write the account class, of course. Overall the problem is more tedious than difficult. Here's a basic example:

#include <ios>
#include <iostream>
#include <iomanip>
#include <limits>
#include <stdexcept>
#include <string>

class Account {
  std::string _name;

  // Represented by the number of pennies, so on a
  // 32-bit system these accounts are limited to
  // $42,949,672.96. Beware arithmetic overflow
  unsigned long _balance;
public:
  Account(): _balance ( 0 ) {}

  Account ( std::string name, unsigned long initial_balance )
    : _name ( name ), _balance ( initial_balance )
  {}

  std::string Name() const
  {
    return _name;
  }

  unsigned long Balance() const
  {
    return _balance;
  }

  unsigned long Credit ( unsigned long amount )
  {
    return _balance += amount;
  }

  unsigned long Debit ( unsigned long amount )
  {
    if ( amount > _balance ) {
      throw std::runtime_error ( 
        "Cannot debit more than the account contains" );
    }

    return _balance -= amount;
  }

  friend std::ostream& operator<< ( std::ostream& out, const Account& acct )
  {
    return out<< acct._name <<": "<< acct._balance / 100 <<"."
      << std::setfill ( '0' ) << std::setw ( 2 ) << acct._balance % 100;
  }
};

int main()
{
  Account accts[10];
  int n = 0;

  while ( true ) …
Narue 5,707 Bad Cop Team Colleague

Well, the answer is that the "average" person can easily corrupt Windows by randomly writing in the appropriate locations. That's a pretty surefire way to screw something up and make the system unusable. You don't even have to touch the kernel, there are thousands of critical files that can be corrupted to destroy a Windows installation.

Narue 5,707 Bad Cop Team Colleague

>So there's absolutely no way possible for the average person to write to it?
Why in the world are you even asking how to crash Windows by corrupting the kernel?

Narue 5,707 Bad Cop Team Colleague

>Do you have some insight as to why it was working in one place, but not in another?
You got unlucky where it worked and lucky in another because bugs are more obvious when they break immediately. As for the detailed why, the random address as temp's value in countWords happened to be in your address space and writing to it happened not to cross any boundaries that would cause a segmentation fault. In populateArts, the random address wasn't nearly as benign.

>while(*temp != '#' && !feof(fin))
For future reference, feof isn't designed to be used as a loop condition like that. Because the end-of-file indicator for a stream is only set after you've tried and failed to read from the stream, loops constructed like this have an off-by-one error where the last record in the stream will be processed twice. This is easily tested and proven with a simple program:

#include <stdio.h>

int main ( void )
{
  char buf[BUFSIZ] = "I'm a monkey! Ook ook!\n";

  while ( !feof ( stdin ) ) {
    fgets( buf, sizeof buf, stdin );
    printf ( "Processing a line: %s", buf );
  }

  return 0;
}
Narue 5,707 Bad Cop Team Colleague

>char* word; /* Temporary holding for each word */
>fscanf(fin, "%s", word);
Pointers aren't magic containers for infinite data. You need to allocate space to word before you can write to it. In this case, there's little point in using a pointer unless you want to get fancy with single character reads.

>arts[index] = (char*)malloc(strlen(word) * sizeof(char));
You cast the result of malloc in one call but not another. Consistency is more important than perfect style, but I'd still recommend removing the cast. Also, instead of sizeof(char) , you can get the same effect without specifying the type directly using sizeof *arts[index] . Also note that sizeof(char) is guaranteed to be 1.

Finally, when allocating memory for a string, you need to add an extra slot for the null character. If you don't do that, you'll end up with problems later when overflowing the buffer.

Try this:

void populateArts(char **arts, FILE *fin, int *numArts)
{
	int index;
	char word[BUFSIZ]; /* Temporary holding for each word */
	
	arts = malloc(*numArts * sizeof *arts);
	
	fscanf(fin, "%s", word); /* Skip over category */

	/* Fill articles array */
	for(index = 0; index < *numArts; index++)
	{
		fscanf(fin, "%s", word);
		printf("word is %s\n", word);
		
		arts[index] = malloc(strlen(word) + 1);
		strcpy(arts[index], word);
	}
}
Narue 5,707 Bad Cop Team Colleague

>Perheps Alt-F4 can Shut down windows ?
I meant that monkeying about in another program's process like that should give you the chills, and if it doesn't, you shouldn't be writing code.

Narue 5,707 Bad Cop Team Colleague

That doesn't sound like a bad thing to do at all. :icon_rolleyes: You might want to start reading The Old New Thing; there are plenty of horror stories about bad programmers who break the rules like that and screw up Windows for years to come.

Narue 5,707 Bad Cop Team Colleague

>Is that an issue I should worry about since it wastes computer time
If you can get away with an optimization, go for it. But keep in mind that you can be given any number of graphs, you're not just solving the problem for this one graph, so the optimization has to be generic enough to work across the board.

Narue 5,707 Bad Cop Team Colleague

>I figured I'd use something like an array to hold the points
Since this is a graph problem, so you need to hold the identity of the vertex (A, B, C, etc...), the the vertices that a vertex is connected to through an edge (A->B, A->C, B->C, etc...), and the weight of the edge (B->C=31, A->B=4, C->D=3, etc...). As long as you can represent all of that information, it really doesn't matter how you handle the storage. However, an adjacency matrix or adjacency list would be a good start, if you've studied those at this point.

>Then I figured you'd use a stack to keep track of the direction you went
Sounds good to me. You can also treat this as a more sophisticated find_min algorithm. When you find a path that's smaller than the current path, make a copy of the stack and the total weight so you can print the result:

stack<Vertex> min;

for (int i = 0; i < n_paths; i++ ) {
  // The magic is in weigh_graph ;-)
  stack<Vertext> curr = weigh_path ( graph, i );

  if ( min.empty() || weight ( curr ) < weight ( min ) )
    min = curr;
}

show_path ( min );

To help you do research, this is called the single pair shortest path problem. Several good algorithms already exist for solving it, but this assignment may be to get you to come up with something on your own.

DemonGal711 commented: Very helpful. Addressed my questions rather then given a general help solution. I would prefer more people do this since, normally, the questions people ask are opinions rather then something you can get from a book. +1
Narue 5,707 Bad Cop Team Colleague

>fin.open((char *)&str,ios::in);
Eew, use c_str instead:

fin.open ( str.c_str(), ios::in );

You only have to escape a backslash in literals, so the following will work fine:

string str="C:\\Documents and Settings\\shankhs\\Desktop\\ccs\\Assignment CCS.txt"

For input, you don't need to worry about escaping a backslash because it's already correct.

By the way, in your code you go to the effort of sanitizing str using temp, then you try to open str instead of temp... :icon_rolleyes:

Narue 5,707 Bad Cop Team Colleague

>Invalid operands of types const char[] and const char[] to binary 'operator +'
If you want string concatenation with the + operator, one of the two operands has to have a type of std::string. If it's a chain, then you can make sure that one of the first two operands is a std::string and all will be well because the result of the first concatenation will return a std::string which will then meet the requirement for all other concatenations in the chain:

string str;
str = string ( "this " ) + "is " + "a " + "string";
Narue 5,707 Bad Cop Team Colleague

>Is it necessary for a compiler to follow ANSI standards
To be strictly correct, it's the ISO standard. And yes, ideally your compiler should conform to the most recent standard as much as possible. However, complete conformance isn't necessary as most of the time the parts that aren't implemented are typically 1) not well understood 2) not often requested or 3) not something you'll find yourself needing.

>heard that vc++ does not
Visual C++ is actually one of the better compilers out there right now in terms of standard conformance.

>What are your views on the two mentioned compilers?
Visual C++ is good, but Dev-C++ is a dead project. If it does everything you want right now, go for it, but if you want an actively developed and improving IDE with the same underlying compiler, look at Code::Blocks.

>Could you suggest me a book for c programming.
C or C++? This is the C++ forum, so there's a bit of ambiguity in your question.

Narue 5,707 Bad Cop Team Colleague

find_if returns an iterator to the matched item, and for_each is retarded. ;)

CTest *it = b;
CTest *end = b + 150;

while ( ( it = find_if ( it, end, myCountIf ) ) != end ) {
  it->Set();
  ++it;
}
Alex Edwards commented: Excellent! =) +5
Narue 5,707 Bad Cop Team Colleague

The problem is I don't know how much space to allocate: students is declared as struct student **students;
What does it mean? is it
1) a single pointer to an array of type "struct student",
2) a single pointer to an array of pointers each pointing to a "struct student" or
3) an array of pointers each pointing to a "struct student" ?

It's a pointer to a pointer, nothing more. However, you can generally assume that T **p means that p is a dynamically sized array of pointers to T, and you allocate memory as such:

T **p = malloc ( N * sizeof *p );

for ( i = 0; i < N; i++ )
  p[i] = malloc ( sizeof *p[i] );
Narue 5,707 Bad Cop Team Colleague

>So, number[2] should give me the number I want
Nope, it should give you the character that the value returned by function represents. Characters are represented internally by integer values. For example, in ASCII you can expect the letter 'A' to be represented internally by the value 65.

If function returns an integer that's only one "character" long, that means it's a single digit value. Most character sets reserve such low values for control characters, which means you're trying to print a character that doesn't have a glyph.

What you want to do is convert the value returned by function to the equivalent character value of the digit:

number[2] = function() + '0';

By adding the integer value of '0' to the digit, you effectively shift the value of the digit into one of the representable values for the characters '0' - '9'.

Narue 5,707 Bad Cop Team Colleague

>malloc() always returns a void pointer. You need to typecast it.
C is kind enough to implicitly convert to and from pointers to void without the need for a cast. In fact, if you get into the habit of casting the result of malloc, your code is both more prone to subtle errors and harder to maintain.

The recommended way to use malloc is as follows (assuming a pointer called p is declared):

/* Allocate one item of the type p points to */
p = malloc ( sizeof *p );

/* Allocate N items of the type p points to */
p = malloc ( N * sizeof *p );

Notice that all of the type information is acquired dynamically rather than being hard coded.

Narue 5,707 Bad Cop Team Colleague

Read:

#include <fstream>
#include <iostream>
#include <string>

int main()
{
  std::ifstream in ( "file.txt" );
  std::string line;

  if ( in ) {
    while ( std::getline ( in, line ) )
      std::cout<< line <<'\n';
  }
}

Write:

#include <fstream>

int main()
{
  std::ofstream out ( "file.txt" );

  if ( out )
    out<<"This is a test";
}

Consider yourself blessed, I didn't tell you to RTFM and STFW for a non-smart question.

Narue 5,707 Bad Cop Team Colleague

The vector class is in the std namespace. Change vector<FrequencyNode> list; to std::vector<FrequencyNode> list; . You have other errors though.

Narue 5,707 Bad Cop Team Colleague

>int *x;
>fscanf(fin, "%i", x);
Where does x point?

Narue 5,707 Bad Cop Team Colleague

You have to loop it:

int var;
bool repeat;

do {
  repeat = false;
  cin>> var;

  switch ( var ) {
  //...
  default:
    repeat = true;
  }
} while ( repeat );
Narue 5,707 Bad Cop Team Colleague

In this case, only the client code knows how data can be serialized, so your best bet is to require the client to give you a serializer for the data (whose interface you provide). This also helps to make a clean break between the data, which is owned by the client, and the tree structure, which is owned by your class.

If you look at some of the libraries here, you'll see a similar genericity technique where the data-specific operations are detached and defined by the client to overcome the "I don't know what I can do with this" problem.

Narue 5,707 Bad Cop Team Colleague

>Any suggestions??
Open the file with the ios::app mode, then you don't have to worry about it. Every write will be an append.

Narue 5,707 Bad Cop Team Colleague

The classic solution is a union, but you can't have a union of points unless the Point class has a trivial constructor.

Another option is to store objects of a proxy class instead of storing Point objects directly. The proxy class will handle the disconnect between objects and pointers, and your Triangle class can largely ignore it.

You can also make your Triangle class a template class and then have a pointer specialization, but that's really just a cute way of having two separate classes in this case. ;)

Alex Edwards commented: I like option #2 =) +4
Narue 5,707 Bad Cop Team Colleague

>so save yourself a lot of trouble by not trying to report it to the FBI.
People who threaten to contact the authorities on a thread are nearly always harmless kooks who don't respond to rational arguments (translation: they're trolls). Just sit back and enjoy the show, because this guy will be gone as soon as everyone stops taking the bait.

Narue 5,707 Bad Cop Team Colleague

>I was wondering if anyone has used this book
Yes, though you've discovered independently that it's not suited for beginners.

>any recommendations for books that might be easier to understand
Accelerated C++ by Andrew Koenig and Barbara Moo. This book is designed for beginners and covers roughly 90% of the language that you'll find yourself using regularly.

Alex Edwards commented: Yeah! The C++ Programming language is totally a reference book and not a beginners tutorial @_@ +4