Skip to main content
gamedev.net
🔒 Locked

Pointer syntax

Started by Daaark Apr 14, 2006 at 5:43 PM 7 replies 1.6k views
Original Post
Daaark
Daaark
This is driving me crazy. I've compiled and had my program crash every time. I am writing a small program which loads some lines from a file into an array of strings. Everything was working fine, but I've been adding different categories of strings, and different arrays, and I got tired of copying and pasting the code to load all the different arrays. So I decided to make the function below, so I could add string arrays and fill them as I pleased without rewritting the code again and replacing variable names every time I wanted another category. ie: int names = 0; string *name = NULL; int places = 0; string *place = NULL; ... ... FileToArray("names.txt",names,name); FileToArray("places.txt",places,place); ... ... This crashes to the point of having to use the task manager to kill the process, and then sometimes having to log back in to be able to compile a new copy of the .exe because windows still has it in use even after I kill it. So I've been messing around with the function argument list to try and fix this problem, and now I'm thinking I'll need **array for pointer to a pointer? But this gives me syntax errors on the lines where I try to access array array = new array = [wow] Hopefully I explained this good enough to not get 15 replies wondering what the hell I'm talking about
[source lang=cpp]
bool FileToArray(char *cFilename, int #, string *array)
{
    fstream fa;
    char ca[1024];

    fa.open(cFilename,fstream::in);
    if (!fa.is_open()) return false;

    //count the number of lines in the
    //file, and allocate enough strings to hold them
    num = 0;
    while (!fa.eof())
    {
        fa.getline(ca,sizeof(ca));
        if (ca[0] == '#') continue;     //don't count comment lines
        if (strlen(ca) == 0) continue;  //don't count blank lines
        ++num;
    }

    //allocate strings
    array = new string[num];
    if (array == NULL)
    {
        fa.close();
        return false;
    }

    //return to the start of the file
    fa.clear();
    fa.seekg(0,fstream::beg);

    //read the lines into the new allocated string array
    int i = 0;
    while (!fa.eof())
    {
        fa.getline(ca,sizeof(ca));
        if (ca[0] == '#') continue;     //don't count comment lines
        if (strlen(ca) == 0) continue;  //don't count blank lines
        array = ca; ++i;
        if (i >= num) break;
    }

    fa.close();

    return true;
}


[Edited by - Vampyre_Dark on April 14, 2006 6:45:53 PM]
wendigo23
wendigo23
When you add a level of pointiness (* to **) you need to dereference it once during access. array --> *array. Under some circumstances you might need to parenthesize that, (*array).
Daaark
Daaark
++r

Okay that compiles. What is the proper syntax when calling the function? &,*???
cherryhouse
cherryhouse
By the way vampyre, you have a memory leak.

array = new string[num];
You are allocating new memory here but you don't delete the memory (that I can see).
Hello?
Daaark
Daaark
Quote:
Original post by cherryhouse
By the way vampyre, you have a memory leak.
No I don't. I have pointer syntax problem. :) My resources are nuked properly when my program is done with them.
Daaark
Daaark
I've upgraded from the hard crash to Process terminated with status 1 (0 minutes, 0 seconds) As soon as FileToArray() runs. Perhaps I don't need a pointer to pointer to access 'array'?

int names = 0; string* name = NULL;if (!FileToArray("names.txt",names,&name) ...bool FileToArray(char *cFilename, int #, string **array){    fstream fa;    char ca[1024];    fa.open(cFilename,fstream::in);    if (!fa.is_open()) return false;    //count the number of lines in the    //file, and allocate enough strings to hold them    num = 0;    while (!fa.eof())    {        fa.getline(ca,sizeof(ca));        if (ca[0] == '#') continue;     //don't count comment lines        if (strlen(ca) == 0) continue;  //don't count blank lines        ++num;    }    //allocate strings and bail out    //if there wasn't enough memory    *array = new string[num];    if (*array == NULL)    {        fa.close();        return false;    }    //return to the start of the file    fa.clear();    fa.seekg(0,fstream::beg);    //read the lines into the new allocated string array    int i = 0;    while (!fa.eof())    {        fa.getline(ca,sizeof(ca));        if (ca[0] == '#') continue;     //don't count comment lines        if (strlen(ca) == 0) continue;  //don't count blank lines        *array = ca; ++i;        if (i >= num) break;    }    fa.close();    return true;}
wendigo23
wendigo23
This is one of the cases where you need to use parenthesis. Operator[] has higher precedence than operator*. (*array) = ca;
Zahlman
Zahlman
If you're going to use C++, please, please, really use C++.

// Normally I don't preserve other people's whitespace etc. conventions// when posting here, but it's your lucky day I guess ;svector<string> names;if (!FileToArray("names.txt",names) ...bool FileToArray(const char *filename, vector<string>& names){    ifstream fa(filename);    if (!fa.is_open()) return false;    while (!fa.eof())    {        string current;        getline(fa, current);        if (current.length() != 0 && current[0] != '#')         {            //don't count comment or blank lines            names.push_back(name);        }    }    return true; // fa is implicitly closed here by its destructor.}


Much shorter, cleaner (free of details that get in the way of the meaningful abstractions), easier (no manual memory management - by the way, 'new' does NOT return null on failure, unless you tell it to; and it's been that way for years now - and only one pass through the file) and oh, it will actually work. :)
Will F
Will F
My guess is that you want to call
if (strlen(ca) == 0) continue;  //don't count blank lines

before
if (ca[0] == '#') continue;     //don't count comment lines


But i'm a bit rusty with working with C style arrays and strings, so I might be wrong

Anyways, here's a more C++ way to do it

#include <fstream>#include <string>#include <vector>#include <iostream>bool FileToArray(const std::string &cFilename, std::vector<std::string> &vec){    std::string line;    std::ifstream fa( cFilename.c_str() );        if ( !fa.is_open() )        return false;         while ( !fa.eof() ) {        getline(fa, line);        if ( line.empty() ) continue;        if ( line[0] == '#') continue;                // if you are reading a very large file the next line could potentially be slow        // you could fix it by either knowing how many lines will be in the file and using        // std::vector's reserve() method, or using another container instead, perhaps std::list        vec.push_back(line);     }        // the ifstream will automatically close the file in it's destructor    // and since it is about to go out of scope, the destructor is about to be called        // it doesn't relate to this problem, but if a fstream already has an open file and you want to    // open a different file you must .close() the stream before you open the next file        return true;}int main (){    std::vector<std::string> foo;    FileToArray("somefile.txt", foo);    std::cout << "Num lines in vector: " << foo.size() << "\n\n";    std::cout << "Contents of vector:\n";    for (unsigned int i = 0; i < foo.size(); ++i)        std::cout << "Line " << i << ": " << foo << "\n";}


given the filesomefile.txt containing:
this is a test#commentfinal


it will output:
Num lines in vector: 2Contents of vector:Line 0: this is a testLine 1: final



EDIT: took too long writing this and Zahlman beat me to it

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.