LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-05-2004, 01:23 PM   #1
Travis86
Member
 
Registered: Dec 2002
Location: The land of GMT -6
Distribution: OS X, PS2 Linux, Ubuntu, IRIX 6.5
Posts: 399

Rep: Reputation: 31
Same code, two different results. (C++)


I've never had much luck with C++, but I'm giving it another go. This program takes a list of first names and last names and puts them into two arrays. The first name loop goes fine, but the lastname loop crashes right at "lastnames[tmpCounter] = buffer;". It's the same code! Why won't it work?!

I've replaced the lastnames file with the firstnames file, but even with two identical files, it still won't work. I can't figure it out. Am I missing something?

Here's the code:

Code:
#include <iostream.h> 
#include <fstream.h>

int main() {

    char buffer[80];
    ifstream firstNamesFile;
    ifstream lastNamesFile;

    char **firstnames;
    char **lastnames;
    int firstnamesLength = 0;
    int lastnamesLength = 0;

    firstNamesFile.open("firstnames.txt", ios::in);
    if (!firstNamesFile) {
        cout << "Unable to open firstnames." << endl;
        return 1;
    }
    lastNamesFile.open("lastnames.txt", ios::in);
    if (!lastNamesFile) {
        cout << "Unable to open lastnames." << endl;
        return 1;
    }

    for (int tmpCounter = 0; !lastNamesFile.eof(); tmpCounter++) {
        lastNamesFile.getline(buffer, 80);
        lastnames[tmpCounter] = buffer;
        lastnamesLength = tmpCounter; // Make this better.
    }
    lastNamesFile.close();

    for (int tmpCounter = 0; !firstNamesFile.eof(); tmpCounter++) {
        firstNamesFile.getline(buffer, 80);
        firstnames[tmpCounter] = buffer;
        firstnamesLength = tmpCounter;
    }
    firstNamesFile.close();

/*
    for (int x=0; x<firstnamesLength; x++) {
      cout << firstnames[x] << endl;
    }
*/   
    return 0;
}
 
Old 11-05-2004, 01:59 PM   #2
wapcaplet
LQ Guru
 
Registered: Feb 2003
Location: Colorado Springs, CO
Distribution: Gentoo
Posts: 2,018

Rep: Reputation: 48
It looks like you neglected to allocate space for the strings that you will be referring to through 'firstnames' and 'lastnames'. As it is, they are just pointers (to pointers); if you plan to store strings using those variables, you have to allocate space for the strings. Though, a much simpler approach would be to just declare them as 2D arrays at the outset:

Code:
char firstnames[X][Y];
where X and Y are the maximum number of strings, and maximum length of each string, respectively. If you want to do dynamic allocation (which I wouldn't recommend here, unless X or Y need to be really huge), you could use the C++ 'new' operator after reading each name into the buffer.

Also, assigning firstnames[foo] = buffer does not do what you may expect - it simply makes the pointer residing in firstnames[foo] point to the buffer variable; when buffer is overwritten by something else, the "assignment" of the original string goes away. Using strcpy() to copy the string would be one solution; using the C++ 'string' data type might be better, since it would allow assignment using '='.

Last edited by wapcaplet; 11-05-2004 at 02:02 PM.
 
Old 11-05-2004, 02:19 PM   #3
sirclif
Member
 
Registered: Sep 2004
Location: south texas
Distribution: fedora core 3,4; gentoo
Posts: 192

Rep: Reputation: 30
if you do want to use the char**, you would do it like this:

char **firstnames;
firstname = new char*[n];
for(int i = 0; i < n; i++)
{
firstnames[i] = new char[80];
}

where n is the number of names. this means that you need to know the number of names before you create the arrays. i usually read the file once, to find out how many entries there are going to be, then allocate the memory. you have to do some tricks with rewinding the file pointer if you choose this way. if you want to allocate the memory on the fly, you are either going to have to write some ugly code, or use the list<> template.
 
Old 11-05-2004, 04:06 PM   #4
Travis86
Member
 
Registered: Dec 2002
Location: The land of GMT -6
Distribution: OS X, PS2 Linux, Ubuntu, IRIX 6.5
Posts: 399

Original Poster
Rep: Reputation: 31
Thanks wapcaplet and zerkliph. Looks like I'm going to have to spend some more time "understanding" rather than "doing." I think you have me on the right track now, though.
 
Old 11-05-2004, 11:37 PM   #5
Travis86
Member
 
Registered: Dec 2002
Location: The land of GMT -6
Distribution: OS X, PS2 Linux, Ubuntu, IRIX 6.5
Posts: 399

Original Poster
Rep: Reputation: 31
On second thought. I think I'll just put C++ back on the shelf before I go postal.

I can find no correlation between what it says in my book, my program, and my output. And as I have no idea how to figure out how to figure out what to do (no, I didn't mistype), I don't see much point in keeping at it.

Last edited by Travis86; 11-05-2004 at 11:46 PM.
 
Old 11-06-2004, 10:21 AM   #6
randyding
Member
 
Registered: May 2004
Posts: 552

Rep: Reputation: 31
Code:
#include <iostream.h>

int main(int argc, char *argv[]) {
    typedef char Tmystring[64];
    Tmystring *strarray;
    int j;

    strarray=new Tmystring[8];

    for (j=0; j<8; j++) {
        snprintf(strarray[j],sizeof(Tmystring)-1,"%d",j);
        strarray[j][sizeof(Tmystring)-1]='\0';
    }

    for (j=0; j<8; j++) {
        cout << strarray[j] << endl;
    }

    delete [] strarray;
    return 0;
}
 
Old 11-06-2004, 10:28 AM   #7
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Since your code uses iostream.h and fstream.h, I'm going to assume that your book is teaching C++ pre-ANSI 92... The latest ANSI/ISO spec for C++ has the standard headers placed in files that drop the .h (and prepend a 'c' for standard C headers), put everything in a std namespace, and declares the headers with the .h as deprecated...

e.g.
#include <iostream.h>
becomes
#include <iostream>

and
#include <stdlib.h>
becomes
#include <cstdlib>


If it doesn't discuss that, then it also probably doesn't discuss any of the STL classes, which would very likely help you out here. In this particular case, instead of saving your string lists as a char**, it might be a lot easier to understand if you saved them as a std::vector<std::string>. That way, all your memory management is going to be handled for you.

You'll still want to learn pointers eventually, but the STL stuff may or may not make your initial C++ learning a bit easier... Anyway, it's just a thought.
 
Old 11-07-2004, 04:36 PM   #8
Travis86
Member
 
Registered: Dec 2002
Location: The land of GMT -6
Distribution: OS X, PS2 Linux, Ubuntu, IRIX 6.5
Posts: 399

Original Poster
Rep: Reputation: 31
Hmmmm... Newer books. Now that might be an idea. The one I have been using is copyrighted in 1992 and has a section on how do make Windows 3.1 dialog boxes. I found one that is copyrighted in 1999, and I might start using that one.

Anyway, I've been away for a while (as you can tell by my late post) and have had time to take a good number of deep breaths. Seeing randyding's bit of code that looked promising, I decided to have another go at it, and this time it worked.

It seems to me that the things that you should really be happy that you've gotten to work take so much out of you that once you're done, you don't have any energy left to rejoice.

Thank you all for your help. Here's the final code:
Code:
#include <fstream.h>
#include <iostream.h>

int main() {

    typedef char Tmystring[64];
    Tmystring *firstnames;
    Tmystring *lastnames;
    firstnames = new Tmystring[10000];
    lastnames = new Tmystring[90000];

    char buffer[80];
    ifstream firstNamesFile;
    ifstream lastNamesFile;
    int firstnamesLength = 0;
    int lastnamesLength = 0;

    firstNamesFile.open("firstnames.txt", ios::in);
    if (!firstNamesFile) { cout << "Unable to open firstnames." << endl;
                           return 1; }
    lastNamesFile.open("lastnames.txt", ios::in);
    if (!lastNamesFile) { cout << "Unable to open lastnames." << endl;
                          return 1;  }


    for (int tmpCounter = 0; !firstNamesFile.eof(); tmpCounter++) {
        firstNamesFile.getline(buffer, 80);
        snprintf(firstnames[tmpCounter],sizeof(Tmystring)-1,"%s",buffer);
        firstnamesLength = tmpCounter;
    }
    firstNamesFile.close();

    for (int tmpCounter = 0; !lastNamesFile.eof(); tmpCounter++) {
        lastNamesFile.getline(buffer, 80);
        snprintf(lastnames[tmpCounter],sizeof(Tmystring)-1,"%s",buffer);
        lastnamesLength = tmpCounter;
    }
    lastNamesFile.close();

    for (int x=0; x<firstnamesLength; x++) cout << firstnames[x] << endl;
    for (int x=0; x<lastnamesLength; x++) cout << lastnames[x] << endl;

    delete [] firstnames;
    delete [] lastnames;
    return 0;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
small syntax problem with C code (implemented in Code Composer Studio) illiniguy3043 Programming 6 01-07-2008 02:14 AM
User Preferences: Use HTML code instead of vB code? (vB code is overrated) stefanlasiewski LQ Suggestions & Feedback 5 07-26-2005 01:37 AM
Using [code] inside of [color] results in very small text scuzzman LQ Suggestions & Feedback 1 03-28-2005 02:14 AM
Editing buttons (quote, code etc.) add the code to the end vharishankar LQ Suggestions & Feedback 2 09-13-2004 09:32 AM
Same C code different results Veteq Programming 17 07-24-2004 03:26 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:33 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration