Clinton Portis 211 Practically a Posting Shark
//this
length = is.tellg();
//should be this
length = fin.tellg();
Clinton Portis 211 Practically a Posting Shark

I will offer few improvements to your code and propose a possible pseudo-coded solution to your initial question.

Firstly, reading in an entire file character at a time is inefficient should be avoided. There may be some situations where this approach may be warranted; however, I believe that this isn't one of them.

Although modern day processors will blast through your file in an instant reading character at a time, extra unnecessary milliseconds can add up depending on your application. I guess it's better to learn about optimization early on so that your future employer will not look at you like a buffoon when there are more obvious optimal methods.

In your defense, I do have suspicions that other methods of reading a file, such as getline() may at some point internally break down to a char-at-a-time memcpy opearation; however, this is unsubstantiated since I do not have access to the secret internal workings of c++ standard functions.

For your current application needs, I would suggest reading the entire file in at once into a char type buffer using the read() function. We'll also be using the seekg() and tellg() functions which we can use easily to get the size of the file (number of characters in file). Lastly, we will be declaring a dynamic array equal to the number of characters contained in the file, as opposed to having to arbitrarily declare an array of a fixed size (very inefficient and could potentially …

Clinton Portis 211 Practically a Posting Shark

laugh out loud :D

How about this:

for(int i=0; i==0; i=0)
    for(int j=0; j<1; j++)
          cout << "M";

OP: you might want to check this out before you continue to act a fool up in here.

Clinton Portis 211 Practically a Posting Shark

FirstPerson... I think the OP asked for a nested for loop :P

Clinton Portis 211 Practically a Posting Shark

I think you mean to do this, if your2darray is an array of cstrings:

//this
your2darray[x][y] = "asdf";

//should be this:
strcpy(your2darray[x], "asdf");
Clinton Portis 211 Practically a Posting Shark

I was just driving down the road and I was thinking, "Hmm.. i forgot to allocate memory for each char* of the vector... so I think this will work better:

for(int i=0; i<wordcount; i++)
{
     char* temp = new char[20];
     cout << "Enter a word (19 chars or less): ";
     cin >> temp;

     words.push_back(temp);
}

Pecet, I was first considering a 'vector of a vector of char pointers' I soon realized that was overkill.. a simple vector of char* is similar to a char[][] 2d array.

ghering,

MyArray[0][1]="hello"

will give you the 'e' in "hello".. if you wanted to access the entire word, just dereferrence the first dimension, which is a pointer to the beginning of the cstring

cout << MyArray[0];

As long as the 2nd dimension is null terminated, your cout operation will not run out of bounds into the rest of the array.

Clinton Portis 211 Practically a Posting Shark

I would just like to say one more thing about this technique...

I'm gonna throw out some figures here, feel free to argue their validity...

I would guess that a file loaded into memory is probably accessed less than 1% of the time they are loaded into memory.. the remaining 99% of the time, the loaded file just sits in your memory card, just taking up space (which my ex wife would argue would be similar to my performance.)

Having the ability to access your file on demand can allow you to free up a block of memory that can last the entire life span of your running application.

Clinton Portis 211 Practically a Posting Shark

What you are asking for can be a very useful data structure... if created dynamically can have about the same performance as a vector and might even be more efficient (a vector might allocate more memory than what you actually need based on the number of push_back() opearations) In either case, here is how you can do both:

The creation of a 2d array is like having a 'pointer to a bunch of pointers':

//create the array pointer (holds the address to the beginning of a block of allocated memory)

//create 2d array of pointers to cstrings
char* words = new char*[wordcount];

//allocate memory for each cstring pointer
for(int i=0; i<wordcount; i++)
{
     wordcount[i] = new char[20];
}
//Now you have words[word#][individual char] array of cstrings, each can hold a word of (in this case 19 chars or less)

//Now you can perform cool cstring operations:
//'Add' to an existing cstring (in this case, the second cstring of the array)
strcat(words[2], " a good day");

If you want to use more modern c++ techniques as opposed to using the older C style character arrays, here is how ye' would declare a 'vector of char vectors'

//Notice that this is one of the very few instances in c++ where spacing matters
//Be sure to add a space in between the > > or else your compiler will think it's a >> extraction operator
vector<char*> words;

//create a temporary cstring we will push into the vector anytime we want …
Clinton Portis 211 Practically a Posting Shark

That is also a good solution.. reading line at a time into a string, clearing the string until you find the one you want.

However, this implementation will require multiple visits back to the file in order to find additional lines requested by the user.

With my implementation, once you pay the price at the beginning, any queries for lines are made very efficiently.. no additional searching needed.

Clinton Portis 211 Practically a Posting Shark

try this string parsing algorithm to split your line up into individual strings:

#include<string>
#include<vector>

int prev = 0;
int curr = 0;
string temp;
string line = "The man is 67 years old and driving an Oldsmobile Rocket 88";
vector<string> vstring;

do{
     prev = curr;
     curr = line.find(' ');

     if(curr == string::npos)
          temp = line.substr(prev);
     else     
          temp = line.substr(prev, curr-1);

     vstring.push_back(temp);
     
  }while(curr != string::npos);

Now you can just test elements of the vstring vector to get what you want:

string word;

cout << "Enter word to find: ";
cin >> word;

for(int i=0, size=vstring.size(); i<=size; i++)
{
     if(word == vstring[i])
          break;
}

if(i == size)
     cout << "word not found";

else
     cout << word << " found at element " vstring[i];
iamthwee commented: It's pi +11
Clinton Portis 211 Practically a Posting Shark

Unfortunately in c++, there is really no good way go locate lines in your file without reading the entire file 'character at a time.'

So, if you have to read only a single line from a file, we know we are at some point going to have to be inefficient... so let's only be inefficient once. The following code traverses the entire file once, char at a time, but saves the positions of all '\n' new lines... so any queries for specific lines from the file can be made efficiently:

#include<iostream>
#include<cctype>
#include<fstream>
#include<string>
#include<vector>

using namespace std;

int main()
{
    int linecount = 0;
    int linetoget = 0;
    int pos = 0;
    char c = '\0';
    char again = '\0';
    string line_str;
    vector<int> linepos;
    ifstream infile;

//Be sure to open in binary mode when messing about with file pointers    
infile.open("C:\\Users\\Dave\\Documents\\resume.txt", ios::binary);

    if(!infile.is_open())
    {
        cout << "\a\nError opening file!";
        cin.get();
        exit(1);
    }

    //Set first line position
    linepos.push_back(0);
    linecount++;

    //Populate line positions from the rest of file
    //This part sucks, but we only have to do it once.
    do{
        infile.get(c);
        if(c == '\n')
        {
            pos = infile.tellg();
            linepos.push_back(pos);
            linecount++;
        }
    }while(infile.good());

    //Reset error flags from the failing good() condition
    infile.clear();

    do{
        do{
            cout << "\nEnter line of file to get: ";
            cin >> linetoget;

            if(linetoget < 1 || linetoget > linecount)
            {
                cout << "\a\nOut of Range.  Please select line number 0 to " << linecount << endl;
            }
        }while(linetoget < 1 || linetoget > linecount);

        infile.seekg(linepos[linetoget-1], ios::beg);
        getline(infile, …
Clinton Portis 211 Practically a Posting Shark

I think the problem is here...

for (int i=-1;ip!=" ";i--)

Since you are using the 'end' flag in seekg(), all offset is relevent to the end of the file.. therefore, you should increment your way from the end of the file, stepping your way backwards into the text file.

You might also have a problem with initializing 'i' to -1.. keep this in mind if you continue to have problems.

Also, I would highly recommend opening your file in binary mode when messing about with the file pointers.. for some reason, when opened in regular ascii mode, it seems to dramatically affect the pointer offset position (you think you are at one place when you are really not)

You have an interesting scheme in place here, getting the line after each character test...

Clinton Portis 211 Practically a Posting Shark

Looks like ye' need to perform a good ol' int-to-string conversion. Today we'll be creating an 'ostringstream' object derived from the <sstream> library in order to facilitate our int-to-string needs:

#include<sstream>
#include<string>
#include<iostream>

using namespace std;

int main()
{
     ostringstream int_to_str;
     string temp;
     int a = 0;

     cout << "Enter a number fool: ";
     cin >> a;

     int_to_str << a;
     temp = int_to_str.str();

     cout << "String " << temp << " == int " << a;

     return 0;
}
Clinton Portis 211 Practically a Posting Shark

Here is one possible way:

int i = 0;
int line = 0;
int number = 0;
char c = '\0';
string temp;

//Make sure your file is opened in binary mode when manipulating file pointers
infile.open("C:\\Documents\\test.txt", ifstream::binary);

cout << "Enter line number to read from file: ";
cin >> number;

//Search character by character for new line
//Increment counter when "new lines" are found.
do{
     infile.get(c);
     i++;
     if(c == '\n')
          line++;
     }while(line != number && infile.good());

//Set 'get' ponter to beginning of desired line to read
infile.seekg((i+1), ios:beg);

//Get the line.
getline(infile, temp);

Like ancient dragon says, there is no real automatic way to find where you want to be in the file without reading your way through it. Unless you already no exactly how many characters each line contain, and they all will always contain the same about of characters at all times, then you can just seekg() to the specific line.. but this is a very rare case.

nunchuckie commented: educational helpful +1
Clinton Portis 211 Practically a Posting Shark

Does anyone understand this...? or is it just me...

Clinton Portis 211 Practically a Posting Shark

right now all that I see that might cause stack overflow might be this..

std::vector<BaseEntity> BaseEntity::sm_vEntities = std::vector<BaseEntity>(100000);
Clinton Portis 211 Practically a Posting Shark

Is the buffer NULL terminated..???

Getting garbage at the end of a cstring is a common sign of mising NULL termination. After briefly looking at the getcwd() documentation, it does not say anything about providing a null terminator at the end of the array.

Clinton Portis 211 Practically a Posting Shark

Here is documentation for getcwd():

Clinton Portis 211 Practically a Posting Shark

I imagine this would require some sort of DLL injection.. where applications would send messages back to your program about their status, specifically if they have the input focus.. window is active or minimized.

I believe the last chapter of "Advanced Windows" by Jeffrey Richter covers dll injection, reading and writing to process memory.

Clinton Portis 211 Practically a Posting Shark

I find the concept of polymorphism (inheritance) to be a quite interesting topic.. although I am by no means an expert in this (I just do enough of this to get by) I believe it is a powerful OOP concept and in my opinion, is probably the main construct that defines OOP languages.

class women
{
     //Attributes common to all women
     //functions common to all women
};

class blondes : public women
{
     //Now you get all the womanly stuff
     //plus 'blonde' attributes and behaviors
};

class brunetts : public women
{
     //Brown hair
     //Nice rear end
     // etc etc...
};
Clinton Portis 211 Practically a Posting Shark
//Also this
}while(c >= 'A' && c <= 'Z');
//should be this
}while(c < 'A' && c > 'Z');
Clinton Portis 211 Practically a Posting Shark

I like your solution in that it opens the file with the get ponter already set to the end of the file.

I opted to use the the ios::end flag in setg() though because then I can just increment my way from the end of the file until I get to where I want to go.

Perhaps the best solution would have been to combine our efforts; open the file 'at the end' and then seekg( , ios::end) step backwards through the file.

Clinton Portis 211 Practically a Posting Shark

Line #6 of my code should be:

infile.seekg(i, ios::end);
Clinton Portis 211 Practically a Posting Shark

You seem to be interested in extracting only the last line of a text file, without having to read in the entire file.

If this is the case, I will provide a possible way to accomplish this.

You can set the 'get' pointer to the end of the document using seekg()

//Any offset provided as the first argument will be relative to the end of the file
infile.seekg (0, ios::end);

Work your way backwards until at such time you have reached the beginning of a line.. but how do you know when you are at the beginning? Based on your example file, a beginning of a line starts with a capital letter:

int i=0;
char c = '\0';
string sentence;

do{
     seekg(i, ios::end);
     c = infile.peek();
     i++;
     }while(c >= 'A' && c <= 'Z');

//Extract last line of file
getline(infile, sentence);

The above code is untested, uncompiled, and may contain small easy to fix errors. It is intended as one possible solution out of many possible for a given task.

Clinton Portis 211 Practically a Posting Shark

Important to know is that this file also only can consist of one line.

3 lines in a file:

Do you people not speak english as a native language... or enjoy confusing the rest of the world.

Here is an important excerpt from, "How to ask questions the smart way"

Write in clear, grammatical, correctly-spelled language
We've found by experience that people who are careless and sloppy writers are usually also careless and sloppy at thinking and coding (often enough to bet on, anyway). Answering questions for careless and sloppy thinkers is not rewarding; we'd rather spend our time elsewhere.

So expressing your question clearly and well is important. If you can't be bothered to do that, we can't be bothered to pay attention. Spend the extra effort to polish your language. It doesn't have to be stiff or formal — in fact, hacker culture values informal, slangy and humorous language used with precision. But it has to be precise; there has to be some indication that you're thinking and paying attention.

Spell, punctuate, and capitalize correctly. Don't confuse “its” with “it's”, “loose” with “lose”, or “discrete” with “discreet”. Don't TYPE IN ALL CAPS; this is read as shouting and considered rude. (All-smalls is only slightly less annoying, as it's difficult to read. Alan Cox can get away with it, but you can't.)

More generally, if you write like a semi-literate boob you will very likely be ignored. So don't use instant-messaging …

Clinton Portis 211 Practically a Posting Shark

I think it looks really good.. best I've seen in awhile.

Clinton Portis 211 Practically a Posting Shark
//This
for(int row=0, col=0; row<6; col++)
//Should be this
for(int row=0, col=0; col<5; col++)
//Make row-to-row transitions
     else 
     {
          x += (x-1);
         //This
          row --;
          //Might have to be this
          row -= 2;
          col--;          
     }
Clinton Portis 211 Practically a Posting Shark

Here is just one possible solution to the first part of the problem, there are probably much better loop(s) you can come up with but I am lazy. It is pretty much self explanitory. You can give the second part of your problem a try. Let me know if you have any questions.

int x = 3;
for(int row=0, col=0; row<6; col++)
{
     
     //Account for the offset required for the last loop iteration in order to display the 2d_array[2][4] special case.
     if(row == 3)

          col++;

     
     //If all array counters jive, then display data, else adjust array counters to get the results we want.
     else if(row > x)

          cout << 2d_array[row][col];  

     //Make row-to-row transitions
     else 
     {
          x += (x-1);
          row++;
          col--;          
     }
}
Clinton Portis 211 Practically a Posting Shark

Do you mean like this?

str1 += str2;
str1 += str3;
str1 += str4;
str1 += str5;

cout << str1;
Clinton Portis 211 Practically a Posting Shark

People always ask, "Why do you always have to initialize your variables?"

This is why:

//Here you create something.  It is never initialized; therefore probably contains some sort of value..   what exactly it contains, we don't know.

long double points;

So when you start using this varible for accumulation, you are just adding to an unknown value:

points += 100;

Usually one would use a simple = assignment to initialize a variable, but since your variable is part of a class, it can only be initialize via use of a class constructor:

class games
{  
     public:

     games();
     long double points;   
     int tictactoe(void);    
};

games::games()
{
     points = 0.0;
}

Now, everytime a 'game' object is created, it's contents will automatically be initialized. You can then safely add your points to it and recieve expected results.

Lesson of the day: Take the time to initialize EVERYTHING.. ALL THE TIME. Then you will always get expected performance.

mrnutty commented: Exactly, many problems comes from un-initialized variables! +2
Clinton Portis 211 Practically a Posting Shark

This:

#define LEFT TRUE;
#define RIGHT FALSE;

should be this:

#define LEFT TRUE
#define RIGHT FALSE
Clinton Portis 211 Practically a Posting Shark

But how do I do this without knowing which name that object got?

Give ye' who is nameless a name:

point* mypoint = new Point(Point::SPHERE, 300.0f, i);
out.add_primitive(obj, mypoint);
Clinton Portis 211 Practically a Posting Shark

How can I check whether my code has memory leak or not?

  • objects allocated memory using 'new' must be deleted.
  • anytime you access an array out of bounds
  • anytime you try to dereferrence a NULL pointer.
  • anytime you leave a dangling pointer, for example:
int* a, b, c;

a = new int;
b = a;
c = a;
delete a;

//What are b and c pointing to..??!?  NOTHING!

This is all I can think of for now as far as memory leakage.

Clinton Portis 211 Practically a Posting Shark

1. We'll have to prompt for an equation that we can understand. We can identify individual reactants easily. We can assume than any compound that begins with a number is a coefficient, any subsequent numbers in the compound will be subscripts. With this protocol established, we can make life a little simpler for the user in that they can enter formulas like so:

C2H6 + O2 2CO2 + 3H2O

Should be:

C2H6 + O2 = 2CO2 + 3H2O

Clinton Portis 211 Practically a Posting Shark

This brings back memories.. I found the website you are thusly describing to me in your tutorial btw. Your copy/paste skills are impressive.

Based on the above example, we can crank out a possible pseduo code:

1. We'll have to prompt for an equation that we can understand. We can identify individual reactants easily. We can assume than any compound that begins with a number is a coefficient, any subsequent numbers in the compound will be subscripts. With this protocol established, we can make life a little simpler for the user in that they can enter formulas like so:

C2H6 + O2 2CO2 + 3H2O

The first character of each term will have to be tested, if isdigit(), then handle the leading coefficient.

2. There are several ways to go at this point, but I will be decisive and implement my own scheme. Since the nature of an equation is "left side vs. right side", I am going to parse each side into a container:

#include<string>

string equation;
string left_side;
string right_side;
int pos = 0;

cout << "Enter equation to balance: ";
cin >> string equation;

pos = equation.find('=');
left_side = equation.sub_str(0, (pos-1));
right_side = equation.sub_str( (pos+1), (equation.size() - (pos-1)) );

3. Again, being decisive with my scheme, I decided that it would be easy to peform equation analysis if everything was packaged up nicely, so I am going to package each 'term' of the equation:

struct chemical
{
     string …
Clinton Portis 211 Practically a Posting Shark

I am intruiged with this assignment.. although it's been years since I balanced a chemical equation.. I would find this to be a fun challenge.

You teach me how to balance chemical equations.. I'll give you some code.

Start me off with something simple.. and I'll code you an answer (as much as I can in accordance with daniweb policy.)

Clinton Portis 211 Practically a Posting Shark

How could i make the program that could limit the input integer the user try to enter

int x=0;

//Force user compliance..!!!
do{
     cout << "Enter a number between 1 and 20: ";
     cin >> x;

     if(x<1 || x>20)
     {
          cout "\aNumber out of range, try again!";
     }
}while(x<1 || x>20);

and how to make the program calculate the sum and all of that??

cout << "How many numbers do ye' wish to enter? ";
cin >> amount;

// "Dynamic Array", You can create an array of whatever size you want
int* integers = new int[amount];

//After your array has been populated, you can perform a summation:
for(int i=0; i<amount; i++)
{
     //perform accumulation
     average += integers[i];
}

//calculate average
average /= amount;

//display useful information (with a cast as per your assignment requirement)
cout << "The average of entered integers is: " << static_cast<double>(average);
Clinton Portis 211 Practically a Posting Shark

These variables are uninitialized and could contain any value that happened to reside in their memory location at the time of their creation:

//These could be any value..!  we don't know what they are..!
int x,factorial;

How can x equal 1 and 0 at the same time?

if (x==1 && x==0)
//Should be
if (x==1 || x==0)

Try this:

factorial = x;
while (x > 1)	
{		
     factorial =* (x - 1);
     x--;
}
Clinton Portis 211 Practically a Posting Shark

Based on your while loop condition, you can assume that score will equal -999 after the loop exits.. at which time you can make the appropriate adjustments.

Clinton Portis 211 Practically a Posting Shark

What do you want to happen when the sentinal value is entered?

This is what I would do, but I'm not sure if this is what you want:

if(score == -999)
{
     exit(0);
}
Clinton Portis 211 Practically a Posting Shark

By doing this, you have established a direct relationship between the two arrays:

//We can assume that 'votes[3]' corrosponds to 'candidates[3]', for example.
if ( inFile >> candidates[i] >> votes[i] )

So all you really need to do is extract the largest value from the votes[] array:

int index = 0;
int max = 0;

for(int i=0; i<6; i++)
{
     if(votes[i] > max)
     {
          max = votes[i];
          index = i;         
     }
}

cout << "The winner is " << candidates[index] << " with a winning vote count of " << votes[index];
Clinton Portis 211 Practically a Posting Shark

Although I am not an inheritance expert, I have a feeling your inputInfo() outputInfo() functions of your parent class need to be labeled 'virtual' because they are overridden in the child class.

Clinton Portis 211 Practically a Posting Shark

try making this small adjustment to your 'while' loop condition:

while((score < 0 || score > 100) && (score != -999));
Clinton Portis 211 Practically a Posting Shark
//This
char * DecData = new char (stringlen+1);
//Should be this:
char* DecData = new char[(stringlen+1)];

//This
int * NewData = new int (strlen(Data));
//Should be this:
int* NewData = new int[(strlen(Data))];
Clinton Portis 211 Practically a Posting Shark

Then try this..

//line #24:  Load ascii values
array[i] = rand()%58 + 'A';

//Then whenever you want to use the array as a 'char', do this:  Line #27
cout << static_cast<char>(array[i]);
Clinton Portis 211 Practically a Posting Shark

Yes, line #24 would be the logical place to give this a try. (sorry for not being specific enough)

Clinton Portis 211 Practically a Posting Shark

I'm not sure right off hand what is going on, but here is a couple of things that I like to try when the unexpected starts to happen in my file i/o operations:

  • try opening your file in binary mode
  • it seems like you might be using your ofstream object in other places, be sure to clear() your object after each use (resets error state flags)
Clinton Portis 211 Practically a Posting Shark
//Loads the array with ascii values ranging from 65 to 122 ('A' thru 'z')
static_cast<char>(array[i]) = rand()%58 + 'A';
Clinton Portis 211 Practically a Posting Shark

scroll down..

|
|
|
\ /
\ /
\ /
\/

Clinton Portis 211 Practically a Posting Shark

Mainly because I have too much free time, I was just thinking about why there wasn't a c++ standard function developed that would just load your entire file all at once.. so we don't have to deal with these issues.

[Edit] I guess it already exists
http://www.cplusplus.com/reference/iostream/istream/read/

I'll definitely keep this in mind and recommend it whenever possible, if nothing else to avoid eof() issues.