nucleon 114 Posting Pro in Training

OP> In all of my googling when learning how to work with C
OP> commands I found that you can use strncpy like substring

No one's saying you can't. It's just that if you only do this strncpy( dest, src + start, length); and it actually copies length characters (as it often will when being used as a substr function) it will not automaticlly put a null character at the end to properly terminate the string. You must do that yourself, like so: dest[length] = 0;

nucleon 114 Posting Pro in Training

I don't know if the following image will show up, but you could maybe write something to guesstimate the number of galaxies in this little picture, but certainly not the number of start in a galaxy. You should check the assignment specs.
[img]http://img147.imageshack.us/img147/1565/galaxies.jpg[/img]

nucleon 114 Posting Pro in Training

> correct me if I'm wrong, but this seems to be designed for ints.

No, it's for any type that has < defined (or you can pass in a comparison function).

The reason I mentioned lower_bound instead of simply find (not string's find but the algorithm find) is that your use of binary_search suggested you had a sorted array.

If your array is NOT sorted then you want find as it will work on a sorted or unsorted list; but it is less efficient than the binary search performed by lower_bound.

lower_bound is easy to use, as shown in the test code below.

// lower_bound returns an iterator to the greatest element not
// less than the search element. If the search element is greater
// than all elements, then one past the last element is returned
// (i.e., the end iterator).

#include <iostream>
#include <algorithm>

void test_lower_bound( std::string *searchIn,
                       size_t       searchInSize,
                       std::string  searchFor )
{
    std::string *it = std::lower_bound( searchIn,
                                        searchIn + searchInSize,
                                        searchFor );
    // We need to check not only that the returned itereator is
    // in range, but that the element it refers to actually is
    // equal to the one we were looking for.
    if( it - searchIn >= searchInSize || *it != searchFor )
        std::cout << searchFor << " not found: fits in at index "
                  << it - searchIn << '\n';
    else
        std::cout << searchFor << " found at index: "
                  << it - searchIn << '\n';
} …
nucleon 114 Posting Pro in Training

> I am seeing 2:00 pm listed as "2:00 pm", '\0' <repeats 17 times>

Is the size of the buffer 25? Those zeros are normal.

But in general, you can't use strncpy like that. It will not null-terminate the strings. To use it as a substring operator, you must do something like this:

strncpy(Hour, ConvertTime, 2);
Hour[2] = 0; /* Ensure null termination */

As a better strcpy, it's used something like this:

char dest [ DestSize ];
strncpy ( dest, src, DestSize - 1 );
dest [ DestSize - 1 ] = 0;
nucleon 114 Posting Pro in Training

You didn't post myMath.h.

nucleon 114 Posting Pro in Training

What exactly is the state of the program at the moment? Is it running properly, except for not being able to read in multiple files of objects?

BTW, you could have put all the files in ONE zip file. :)

nucleon 114 Posting Pro in Training

Can we see the function? Remember to use code tags.

nucleon 114 Posting Pro in Training

Good point. I'll try to remember to do that. The line numbers can be useful to. Can't edit it now, though. :(

nucleon 114 Posting Pro in Training

Breaking a program into functions helps you to think about it, forcing you to name parts and parameters and think in a hierarchical instead of a linear manner. Here's a version of your program broken into functions.

The code compiles but I have no data to run it with (nor a clear enough understanding of your data structure to create test data). It should perform (or not) about the same as your old code. (But note the comments beginning with //! .)

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>


typedef unsigned char uchar;

// This structure is used to store all of the words in the plain text.
// Each word contains an attribute that tells its position (literally
// how many words it is into the sentence)
// and an attribute that tracks the line number that it appears on.
struct Word {
   char word[1000];  //! Should be dynamically allocated?
   int lineno;
   int position;
};


void wSort(struct Word*, int, int);
int myrc4(FILE *f, char *passwd, struct Word *words);
void myrc4_init(struct Word *words, char *passwd, uchar *S, uchar *K);
void calc_keystream(FILE *a, struct Word *words, int wordCount, uchar *A);


int main(int argc, char **argv)
{
  FILE *f, *a;
  struct Word words[256];
  int wordCount = 0;
  uchar A[256];  // Alice's generated keystream
  char passwd[] = "5ne10nemo"; // password used to make encrypted .drm file

  if(argc != 3) // Check command line args.
  {
    printf("Usage: %s <YOUdrmFile> <ALICEdrmFile> \n", argv[0]);
    return 1;
  }

  //! Should maybe be opening these in binary …
nucleon 114 Posting Pro in Training

ddanbe> I would reserve more bit space for the mantissa.
Maybe it's a "special purpose" trade off: massive range at the expense of precision. Purpose unspecified. ;)

But the OP may be confusing mantissa and exponent. In the usual types, the mantissa always has more bits than the exponent. Here's how your layout compares:

Bits allocated for:
              exp  mant
stnd single:    8    23
stnd double:   11    52
yours:         95    31
nucleon 114 Posting Pro in Training

Such flat, lifeless code. Why? No code tags! ;)

You're reading over and over to the same part of the buffer (and zeroing it before every read). Move the zeroing (if necessary) outside the loop, and either move along the buffer (read into buffer+size) or do the file operations on a buffer by buffer basis, as below.

memset(buffer,0x0,BUFFER_SIZE); // init line
pFile = fopen ( "new.jpg" , "wb" );

for(;;)
{
  rc = read (sd, buffer, BUFFER_SIZE);
  if (rc <= 0) break;
  size += rc;
  fwrite (buffer, 1 , rc, pFile );
}

fclose (pFile);
printf("\n Total received response bytes: %d\n",size);
nucleon 114 Posting Pro in Training

IDC_EASTERN_TIME is (presumably) an integer control id. You need an HWND to pass to SetWindowText. If you have an hwnd to your dialog (or whatever) window, try this: SetWindowText ( GetDlgItem ( hwndDialog, IDC_EASTERN_TIME ), cETime ); Also, cETime has too-little space allocated to it. It should be at least 24; may as well make it 32.

nucleon 114 Posting Pro in Training

Is there no way to pass the object I want to load into the methods so that I don't have to create almost identical methods everytime I want a new shape though?

It is my understanding that object is a dynamically allocated array of objects. Do you mean you want to be able to load sets of objects from multiple files?

The countObjects method doesn't work if I use fullFile as a parameter, only if I pass 'char fileName[20]' as it was before.

That makes no sense to me.

Try zipping and attaching your code this time. :)

nucleon 114 Posting Pro in Training

You want to look at lower_bound. It has the same complexity as binary_search (and also needs a sorted list). But it returns an iterator.

nucleon 114 Posting Pro in Training

And, yes, the Float3 thing is a mistake. :)

nucleon 114 Posting Pro in Training

Change these two function signatures from this:

void loadShape(char filename[20], struct Object3D *object);
void countObjects(char fileName[20], struct Object3D *object);

to this:

void loadShape(char filename[20]);
void countObjects(char *fullFile);

Change the call to countObjects (in loadShape) from this: countObjects(fileName, object); to this: countObjects(fullFile); Change the call to loadShape (in main) frm this: loadShape("scene.ASE", object); to this: loadShape("scene.ASE");

nucleon 114 Posting Pro in Training

I see. Then REMOVE those ampersands I added to glVertex3fv's argument, and try changing this:

// A type to hold 3 floats
typedef struct Point3Df {
    float x, y, z;
} Point3Df;

to this:

// Point3Df is an array of 3 floats.
typedef float Point3Df[3];

And this:

if(strcmp(pch, "MESH_VERTEX") == NULL)
		{
			v = atoi(strtok (NULL, delim));
			printf("v=%d\n", v);
			object[nObj].vertices[v].x = atof(strtok (NULL, delim));
			object[nObj].vertices[v].y = atof(strtok (NULL, delim));
			object[nObj].vertices[v].z = atof(strtok (NULL, delim));
		}

to this:

typedef float Float3[3];

		if(strcmp(pch, "MESH_VERTEX") == NULL)
		{
			v = atoi(strtok (NULL, delim));
			printf("v=%d\n", v);
                        for (i = 0; i < 3; ++i)
				object[nObj].vertices[v][i] = atof(strtok (NULL, delim));
		}

Damn these spaces and tabs! ;)

nucleon 114 Posting Pro in Training

Try this. Note the ampersands.

void polygon(int a, int b, int c, int i)
{
	glBegin(GL_POLYGON);
		glColor3ub(128,64,0);
		glVertex3fv(&object[i].vertices[a]);
		glVertex3fv(&object[i].vertices[b]);
		glVertex3fv(&object[i].vertices[c]);
	glEnd();
}
nucleon 114 Posting Pro in Training

You just want one call to srand((unsigned)time(0)); . Put it as the first statement in main and remove it from everywhere else (it's in two functions now).

nucleon 114 Posting Pro in Training
struct WordCatch words[256];
  unsigned char S[256];
  unsigned char K[256];
  unsigned char A[256];  // Alice's generated keystream
  char buffer1[100];
  char buffer2[10];
  char passwd[] = "5ne10nemo";
  char temp[2];
  int c, i, j, k, t, N, x, y, n;
  int wordCount = 0;
  int lineCount = 1;
  int beginning, ending, current;
  FILE *f, *a;

24 variables! Usually that indicates the need for more functions. It would be easier to read with function names, too.

nucleon 114 Posting Pro in Training

Here's a go at the new data structure and file-handling. Note that the new data structure is easier to use and initialize. I just hope it works. I've made object global (for now) since that is most consonant with the bulk of your design.

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "glut.h"
#include <GL\gl.h>
#include <GL\glu.h>

// A type to hold there ints
typedef struct ThreeInts {
    int a, b, c;
} ThreeInts;

// A type to hold a 3 floats
typedef struct Point3Df {
    float x, y, z;
} Point3Df;

// A type to hold the information for a single 3D object.
typedef struct Object3D {

    // Dynamically-allocated array of facets.
	ThreeInts *facets;
	int        nFacets; // Size of facets array.

    // Dynamically-allocated array of vertices.
	Point3Df  *vertices;
	int        nVertices; // Size of vertices array.

} Object3D;


// A global pointer to hold a dynamically-allocated array of objects.
Object3D *object
int numObjects;  // Size of object array.


GLfloat rquad;
GLfloat rShapeY = 0.0;
GLfloat rShapeX = 0.0;
GLfloat rShapeZ = 0.0;


GLfloat cubeVert[][3] = {
    {-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,1.0,-1.0},{-1.0,1.0,-1.0},
    {-1.0,-1.0,1.0},{1.0,-1.0,1.0},{1.0,1.0,1.0},{-1.0,1.0,1.0}};

GLfloat colors[][3] = {
    {0.0,0.0,0.0},{1.0,0.0,0.0},{1.0,1.0,0.0},{0.0,1.0,0.0},
    {0.0,0.0,1.0},{1.0,0.0,1.0},{1.0,1.0,1.0},{0.0,1.0,1.0}};


void display();
void adjustSize(GLsizei, GLsizei);
void animate();
//void mouse(int btn, int state, int x, int y);
void Keyboard(unsigned char key, int x, int y);
void SpecialKeys(int key, int x, int y);
void polygon(int a, int b, int c, int i);
void shape();
void DrawGround();
//void windCube();
//void cube(int a, int b, int c, int d);
void loadShapes(char filename[20]);
char *readFile(FILE *sceneFile);
void countObjects(char *fullFile);


int main(int …
nucleon 114 Posting Pro in Training

Please change your data structure and file-handling as I asked above and repost your code. I had asked you some questions, too.

nucleon 114 Posting Pro in Training

This compiles, but there's got to be a better way. It's probably not generally worth it in this case.

#include <fstream>
#include <string>
#include <map>

namespace sss {

    using namespace std;

    class node {
    public:
        multimap<string, string>  values;
        multimap<string, node>    children;
    };

    typedef pair<string, string> value;
    typedef pair<string, node>   child;
    typedef multimap<string, string>::iterator valueiterator;
    typedef multimap<string, node>::iterator   childiterator;

    template <typename Container, typename ReturnType>
    ReturnType&
    insert (Container& con, std::string  name,
            int index, ReturnType retType) { // retType just used for type
        typename Container::iterator it = con.find (name);
        try {
            int i;
            if (it == con.end()) throw 0;
            for (i = 0; i < index; i++) {
                if (++it == con.end()) throw 0;
            }
        } catch (int e) {
            it = con.insert(
                    std::pair <std::string, ReturnType>
                              (name, ReturnType()));
        }
        return it->second;
    }
}

int main() {
    sss::node n;
    std::string str;
    std::string& strRef = sss::insert (n.values, "aaa", 1, str);
    sss::node& nodeRef = sss::insert (n.children, "bbb", 1, n);
}
nucleon 114 Posting Pro in Training

Basically you just say "start a new thread of execution here". It shares the same address space as your main (or original) line of execution, which can be handy. How about something like this:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <pthread.h>


void*
KeyboardThread (void *unused)
{
    printf ("In keyboard thread\nPress Enter...");
    getchar();
    printf ("Exiting keyboard thread\n:);
    return NULL; /* Or pthread_exit(NULL) */
}


pthread_t
StartKeyboardThread (void)
{
    pthread_t thread;
    if (pthread_create (&thread,        /* Thread id */
                        NULL,           /* Default attributes */
                        KeyboardThread, /* Thread start routine */
                        NULL)           /* Arg to start routine */
            != 0)
    {
        perror ("StartKeyboardThread");
        exit (-1);
    }
    return thread;
}


int
main (void)
{
    /* To start it */
    pthread_t thread = StartKeyboardThread();

    /* And when you want to kill it */
    pthread_cancel (thread);

    return 0;
}
JimD C++ Newb commented: Great idea and easy to understand +1
nucleon 114 Posting Pro in Training

I was forgetting that you've already written the server, so you must know about select (?). In the client, you can try using select the same way, adding STDIN_FILENO to the fds, but it is system dependent whether that will work. If it doesn't, there may be some other system dependent way to do it (like setting it up so a signal is sent every keystroke, interrupting the select).

Alternatively, the threaded solution is actually very clean. The "keyboard" thread reads keys, sending its buffer to the "main" thread (either when enter is pressed or even char by char) which communicates with the server.

nucleon 114 Posting Pro in Training

Just to check, are each of the following statements correct?
1. Each object is made up of an arbitrary number of facets.
2. Each facet is made up of three integers (used as indices into vertices)
3. vertices is a list of all the float-3D points used by all the facets.

If the above is true, then numCols never changes from 3 and in fact simply represents the fact that your points are 3D and your facets are triangles. This allows us to remove another level of indirection from both facets and vertices and replace it with a 3-element struct.

typedef struct Point3Df {
	float x, y, z;
} Point3Df;

typedef struct ThreeInts {
	int a, b, c;
} ThreeInts;

typedef struct Object3D {
	ThreeInts *facets;       // List of facets
	int        nFacets;
	Point3Df  *vertices;     // List of vertices
	int        nVertices;
} Object3D;

This structure is used like this:

Object3D  aCube;    // A single object
Object3D *objects;  // A list of objects
// As I understand it, you need a list of objects.

// Get first index of a facet
a = objects[objectNum].facets[facetNum].a;

// Retrieve the x coord of the point represented by that index.
x = objects[objectNum].vertices[a].x;

I have not yet looked through your code carefully (this time), but you MUST change the way you deal with the file. So at least make this change (as your posted code has no line-numbers (use code=c for line-numbers) you'll have to match up the text below …

nucleon 114 Posting Pro in Training

>If you uncomment the typename, you are intentionally telling compiler
> that T::Baz is a type which is, off course logically wrong.

Telling the compiler that T::Baz is a type (as far as meep is concerned) is not the error. In the given example, that is actually what we want. The logic error here (when typename is in play) is that Bar misdefines Baz as an object and not a type.

> This was exactly Narue point;

I know. I was just posting a runnable (or not) example of what she said.

nucleon 114 Posting Pro in Training

You do not need multi-threading for this task.

Your program proceeds in lockstep because your I/O calls are of the "blocking" type and you are calling them without knowing that they are "ready". If they are not ready, they'll wait until something is ready to return. This includes fgets, which waits until the Enter key is pressed to return (line-buffered input).

You have 4 I/O statements in the loop, a simplified version of which appears below (error handling removed):

for ( ; ; ) {

    gets ( msg );   /* IO_1 */
    if ( strcmp ( msg, "q" ) == 0 ) break;

    write ( ... );  /* IO_2 */

    read ( ... );   /* IO_3 */
    printf ( ... ); /* IO_4 */
  }

Instantly, the gets() blocks reading from the terminal, waiting for an Enter keypress. If the other client had sent us a message, we won't see it until we send our message. To fix that you must read the keyboard in a non-blocking manner and yet avoid active polling.

You avoid active polling with the select() function, which will block until one of a given set of file descriptors are "ready". Blocking is good because it means you're not looping and testing (active polling), which is worse than wasteful in a multitasking environment! select() allows you to block on a set of file descriptors, waiting until any one of them is ready. (I don't know how standardized select() is, but it should …

nucleon 114 Posting Pro in Training

vbapi is no longer supported. Your article actually says so, but not very clearly (just under the article title, to the left). Try this article instead.
This one might be even newer/better.

nucleon 114 Posting Pro in Training

StuXYZ> Narue's explanation is really well done

No doubt! That was a good one. :)

So even in a situation like this (where T is a template param) for (vector<T>::iterator it = v.begin(); ...) where it seems that it MUST be a type, it's interpreted as a non-type, enforcing a simple, consistent rule. And so it gives an error essentially along the lines of "Hey, idiot, you just put two variable names in a row." So you MUST put typename before all such uses.

Narue> It shouldn't be hard to see more subtle errors that will compile

Making p a shadow of an int p sneaks the error past the compiler in your example.

class Bar {
public:
    static int Baz;
};

int p;

template <typename T>
void meep()
{
//    typename  // Compiles with logic error if commented out
        T::Baz *p;
}

int main() {
    meep<Bar>();
}
nucleon 114 Posting Pro in Training

You should still make these changes, it could save you marks!

In main, no need to say the file exists, and it should exit the program if the file does not exist (after reporting so).

In InputData(), do the following. Otherwise it adds a final blank entry into your tree (unless there's no newline on the last line, which is not something to be counted on). This will also skip blank lines without adding a blank entry to the tree.

string name;
    while(getline(InFile, name))
    {
        // Skip if no non-blanks.
        if (name.find_first_not_of(" \t") == string::npos)
            continue;

        Leaf = new AVLNode;
        Leaf->Name = name;
nucleon 114 Posting Pro in Training

I saw that no one had responded. The reason I had not responded was because I was "sick of trees". That can happen, you know. Maybe everyone else was sick of trees too. And it was a fair amount of code. And it was the weekend.

I'll take a look at the new stuff when you post it.

nucleon 114 Posting Pro in Training

> yeah, that was really abrasive

Nah, not really. I just had to get used to your style. The fact is that my avatar should be a foot in a mouth.

jephthah commented: mine too. without a doubt. +6
nucleon 114 Posting Pro in Training

I don't know exactly why it's needed either. The compiler seems to be saying that's it's syntactically unclear (at that point in the compilation anyway) whether or not vector<T>::iterator is a typename, so you need to provide the clue. But that leads to the question, what else could it be?

nucleon 114 Posting Pro in Training

You may not actually want to wait in real time. You would normally do that only for a realtime animation of the process.

It depends on what output you want. You seem to just want a line by line output of what happens after each input event. Each input event should probably have a time_delta to say whether it is for the current second (0) the next (1) or something further in the future. Each output line should start with the current_time, which would usually start at zero.

nucleon 114 Posting Pro in Training

You need to use typename. for (typename vector<T>::iterator it = x.begin(); it != x.end(); it++) {

nucleon 114 Posting Pro in Training

jephthah is correct, in his abrasive way. :) As he himself might say, my "solution" (actually my code for your solution) is both half-assed and of the git-er-done variety.

It is better to search for some identifying string in whatever line it happens to be in, and strstr() is useful in that regard.

nucleon 114 Posting Pro in Training

Your main problem is that you need to do the sscanf before you do the strtok(NULL,"..."). Couple other problems: no use passing in txt to use as local variable; return type doesn't match what you're trying to return; renamed a couple variables. And I changed sscanf to strcpy; but sscanf was not the problem.

#include <stdio.h>
#include <string.h>

int displayFile (const char* filename)
{
	char strArr[100][100];
	char txt[200];
	char *toks;
	int size = 0;
	int i;
	FILE *rfPtr;

	rfPtr=fopen(filename,"r");

	if (rfPtr==NULL)
	{
		printf("File cannot be opened!\n");
		return -1;
	}

	while(fgets(txt,200,rfPtr)){
		toks=strtok(txt," .\n");
		while(toks){
			strcpy (strArr[size++], toks);
			toks=strtok(NULL," .\n");
		}
	}

	for(i=0;i<size;i++) printf("[%s]\n",strArr[i]);

	fclose(rfPtr);
	return 0;
}

int main() {
	displayFile ("DisplayFile.txt");
}
nucleon 114 Posting Pro in Training

Here's a parital fix. I fixed a couple of problems (noted in comments), and a couple of stylistic things in your first two functions. I didn't even look at the other functions, but it works better. It seems to still be missing one name.

int main()
{
    ifstream fin ("a6.txt");
    if (!fin) {
        cout << "Input file does not exist.\n\n";
        return -1;
    }

    AVLNode* head = AVLCreation (fin);
    fin.close();

    InorderTraversal (head);
    cout << "\n\n";

    PreorderTraversal (head);

    cin.sync(); cin.get(); // Will work on more systems.
}

AVLNode *AVLCreation(ifstream &InFile)
{
    AVLNode *Root = NULL;
    AVLNode *Leaf, *temp, *Scan;

/*** Moved getline into the while condition since it is
     a getline attempt that will inform you of the EOF.
     You should add a check for blank names (or all spaces). */
    string name;
    while (getline (InFile, name))
    {
        temp = Root;
        Leaf = new AVLNode;
        Leaf->Name = name;
        Leaf->Balance = 0;
        Leaf->RightChild = NULL;
        Leaf->LeftChild = NULL;

        if (!Root)
        {
            Root = Leaf;
            Scan = Root;
        }
        else
        {
            while (1)
            {
                if (Leaf->Name > temp->Name && !temp->RightChild)
                {
                    temp->RightChild = Leaf;
                    temp->Balance--;
                    break;
                }
                else if (Leaf->Name < temp->Name && !temp->LeftChild)
                {
                    temp->LeftChild = Leaf;
                    temp->Balance++;
                    break;
                }

                if (Leaf->Name > temp->Name && temp->RightChild)
                {
/*** Switched the order of the next two lines */
                    temp = temp->RightChild;
                    temp->Balance--;
                }
                else if(Leaf->Name < temp->Name && temp->LeftChild)
                {
/*** Ditto. */
                    temp = temp->LeftChild;
                    temp->Balance++;
                }
            }
            PreorderScan(Root, Scan);
        }
    }
    return Root;
}
nucleon 114 Posting Pro in Training

Nice one AD! :)
I did not spot that call tucked away in there.
getCommandId is being called with a string literal (constant),
which it tries to modify in strToUpper: getCommandId("move"));

nucleon 114 Posting Pro in Training

Do you still get the error if you remove:
* the file stuff? (replace it with a single buf load to tokenize)
* the token stuff?
Post a single file minimal version that recreates the error.

nucleon 114 Posting Pro in Training

> Whats SkipNChars?

That's it right there. No guarantees. I'm unsure about the design decision to return the str pointer (pointing to the null character) when the end of string is reached; it could return a NULL ptr instead. It should also be renamed; maybe SkipNDelims.

But forget about that one. Here's a simplified version, just for newlines.

char* SkipNewlines (char* str, size_t n) {
    while (n--)
        do {
             if (!*str) return str; /* Returns pointer to '\0' */
        } while (*str++ != '\n');
    return str; /* Returns one past nth '\n' */
}

Use it like this:

char buffer[] = "here is your text\nline after line\netc....\n";
/* Init a char pointer. */
char *pLine = buffer;
/* Skip the first 34 lines. */
pLine = SkipNewlines (pLine, 34);
/* Now pLine points to beginning of 35th line;
    or the end of the string (the '\0')
    if there were less than 35 lines. */
nucleon 114 Posting Pro in Training

You can use this as char* pLine = SkipNChars (xmlText, 34, '\n'); to skip the first 34 lines in a string buffer.

char* SkipNChars (char* str, size_t n, char c) {
    while (n--)
        do {
             if (!*str) return str; /* Returns end of string */
        } while (*str++ != c);
    return str; /* Returns one past nth char c */
}
nucleon 114 Posting Pro in Training

Upon re-reading the above, I notice that finding the splitting point for the left and right subtrees (after discarding the root of the current subtree) is as easy as looking for the preorder list's first element in the postorder list's elements. The index of that element (in the postorder list) is the splitting point. If it is not the last element, then it and everything before it is on the left and everything past it is on the right. But if it is the last element, then you don't actually know whether this is a left or right branch. Again, you may as well attach it to the left, unless there is more information to go on (like the inorder traversal).

nucleon 114 Posting Pro in Training

There would seem to be method in such madness. But, as Narue said, you cannot entirely solve the tree without an inorder traversal as well.

The problem should be solved recursively, as you might expect.

pre:  C B A E D F H
post: A B D H F E C

Either the first node of preorder or the last node of postorder gives you the top node in the current subtree. So in this case it is C. Enter that into the tree diagram and remove it from both lists, realigning them:

pre:  B A E D F H
post: A B D H F E
                                  C

Note that the lists divide into two parts indicated by the repetition of letters in different permutations. These are the left and right subtrees of the current subtree:

pre:   B A   E D F H
post:  A B   D H F E

Divide the problem into those two subtrees, go back and solve recursively.
That's basically it.

Continuing on, for instance, we have:

pre:   B A
post:  A B

which is either of the two possibilities we cannot distinguish between (A connected as left or right subtree). So, arbitrarily choosing to connect A to the left:

C
                                 B
                              A

The right subtree is this:

pre:   E D F H
post:  D H F E

E is clearly the top node, so remove it, realign the lists, add it to the tree:

pre: …
nucleon 114 Posting Pro in Training

Got it. It was a combination of two things.
Firstly, you do need to say STEP = ....erase(STEP).
Secondly, if you do erase an element, you must not increment STEP.

vector<int>::iterator STEP;
for (STEP=CAR_VEC[i].PASSD.begin(); STEP!=CAR_VEC[i].PASSD.end(); ) {
  if ( *STEP==ROAD_STOP[j]->NUM){
    cout <<"ok- bus:"<<i<<" pass:"<< *STEP
         <<" stop:"<<ROAD_STOP[j]->NUM<<endl;
    STEP = CAR_VEC[i].PASSD.erase(STEP);
  }
  else
    ++STEP
}
nucleon 114 Posting Pro in Training

You find the = sign just like you found the # sign. Like this: posEqual = search.find("="); If posEqual is equal to string::npos, there was no = sign. Maybe skip that line (and print an error msg).

If posEqual is equal to line.size() - 1 then the = sign is at the very end of the string, which is a special case. Basically the value is a null string, or maybe you consider this to be an error.

If posEqual < line.size() - 1 then

value = line.substr(posEqual + 1, string::npos);

You may wish to trim spaces from before and after the value thus retrieved.

kelechi96 commented: THANKS ! +1
nucleon 114 Posting Pro in Training

It should probably be:

STEP = CAR_VEC[i].PASSD.erase(STEP);
nucleon 114 Posting Pro in Training

Just put some spaces or tabs, that is, \t characters at the beginning of the menu lines.

nucleon 114 Posting Pro in Training

Yes, I forgot the following after strncpy: word[pComma - pColon] = 0;