Thread: pointers in arrays... Declaring objects in a loop.

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    10

    pointers in arrays... Declaring objects in a loop.

    Hi deeee Ho again! ^_^

    I was bugging you guys with my questions about creatin a class for handling files (to update my webpages). Well, I managed to create the class (class tiedosto), and implement most of the functions I needed in it

    Now I'm building main to actually utilize the class, and to actually update the files...

    In order to do that, I should create new tiedosto class object, corresponding to every single file of my pages. Constructor of my tiedosto-class takes paths and filenames as arguments. So I thought I'll do a txt file, containing paths and names of my files on separate lines, and then just make the program to read the paths and names from the file.

    Well, I tried to create new objects in a for loop... But I have problems in understanding how pointers work.. My goal was to have an array which each cell holds one object (or pointer to object..), so I could use the array[i] when I refer to a certain file. Am I making myself clear? Well, as I told, I have problems in understanding how pointers work in such cases.. So all help would be appreciated I'll post the code I have managed to produce this far below...


    Code:
    #include <iostream>
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    #include "tiedosto.h"
    
    using namespace::std;
    
    main(){
        char *pagenames[250]; //arrays for filenames
        char *paths[250]; //arrays for paths
        
        int i=0,number_of_pages=0,lkm=0;
        FILE *readindex; // stream to read pagenames and paths from indexfile
        
        readindex=fopen("kotisivindex.txt","r"); //opens indexfile for reading
        while(feof(readindex)==0){
            if(fgetc(readindex)=='\n'){  
            number_of_pages++;  //if character that was read is '\n', increases number_of_pages.
        }
        }
        number_of_pages=number_of_pages/2; //because theres path in 1st. line, and name of the file in 2nd line.
        fclose(readindex); 
        readindex=fopen("kotisivindex.txt","r"); 
        for(i=0;i<number_of_pages;i++){
            fgets(*paths[i],500,readindex); //stores paths in arrays
            fgets(*pagenames[i],500,readindex); //stores filenames in arrays
        
        tiedosto *pagefiles[i] = new tiedosto(pagenames[i],paths[i]); /*creates new object.
        constructor is "tiedosto(char filename[],char path[]); So pagenames and paths should be given 
        as char arrays.*/
        
        //ignore the rest, it I can make working on my own, and if I cant, then I'll ask again :p
        
            cout << "kasittelyssa " << (*pagefiles[i]).kokonimi << endl; 
            lkm=*pagefiles[i].lisaa_loppuun("</LI>","\n");
            cout << "</LI> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("</UL>","\n");
            cout << "</UL> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("-->","\n");
            cout << "--> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("<TR>","\n");    
            cout << "<TR> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("<TD>","\n");
            cout << "<TD> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("</TR>","\n");
            cout << "</TR> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("</TD>","\n");
            cout << "</TD> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("<TABLE>","\n");
            cout << "<TABLE> " << lkm << " kappaletta" << endl;
            lkm=*pagefiles[i].lisaa_loppuun("</TABLE>","\n");
            cout << "</TABLE> " << lkm << " kappaletta" << endl;
        }
    }

  2. #2
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    here's an example using ints. it's basically the same with objects.

    (to the vets: no need for nitpicking - dev-c++ generated the skeleton)
    Code:
    #include <iostream>
    #include <stdlib.h>
    
    using namespace std;
      
    int main()
    {
    	int *x[50];
    	for(int i = 0; i < 50; i++)
    	{
    		x[i] = new int;
    		*x[i] = i;
    		cout << (*x[i]) << endl;
                      //if x where pointers to classes, you would do   x[i]->classMethod()
    	}
    
        system("PAUSE");	
        return 0;
    }
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Code:
    #include <iostream>
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    Header files don't end in .h unless you wrote them yourself.

    I think this:

    using namespace::std;

    should be written like this:

    using namespace std;

    Your syntax works, but I've never seen a using declaration in that format before.

    Instead of this:

    char *pagenames[250]; //arrays for filenames
    char *paths[250]; //arrays for paths

    you can use string types which are much easier to work with. If a function requires a char* argument, you can do this:

    string str = "somefile.txt";
    somefuntion(str.c_str());

    Here is an example of what I think you are trying to do:

    C:\\TestData\\filenames.txt:
    Code:
    C:\someFolder\
    file1.txt
    C:\anotherFolder\
    file2.txt
    C:\
    file3.txt
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    using namespace std;
    
    class File
    {
    public:
    	string path;
    	string name;
    
    	File(string a_path, string a_name)
    	{
    		path = a_path;
    		name = a_name;
    	}
    	File()
    	{
    		path = "";
    		name = "";
    	}
    
    	~File()
    	{
    		cout<<"destructor called"<<endl; //displays when a File is being destroyed
    	}
    };
    
    int main()
    {
    	File* files[10];
    	
    	//open the input file:
    	ifstream inFile("C:\\TestData\\filenames.txt");
    	if(!inFile)
    	{
    		cout<<"bad file name";
    		return 1;
    	}
    
    	string input_path;
    	string input_name;
    	int i = 0;
    	while(!inFile.eof())
    	{
    		getline(inFile, input_path); //read in a whole line of input
    		getline(inFile, input_name); //read in a whole line of input
    		
    		files[i++] = new File(input_path, input_name);//allocate memory for a new File created 
    								//with the input data and assign its address
    								//to the pointer files[i]:
    		
    	}
    	
    	//display some of the input data:
    	cout<<files[0]->path<<endl;
    	cout<<files[0]->name<<endl;
    	
    	//delete memory:
    	for(int j=0; j< i; j++)
    	{
    		delete files[j];
    	}
    
    	return 0;
    }
    Last edited by 7stud; 04-05-2005 at 04:04 AM.

  4. #4
    Registered User
    Join Date
    Apr 2005
    Posts
    10
    Rhaaa.

    Either I'm stupid, or this is difficult :|

    I still cant make it working :/ I used:

    Code:
        char **pagenames[250]; //arrays for filenames
        char **paths[250]; //arrays for paths
    .
    .
    .
     fgets(*paths[i],250,readindex); //stores paths in arrays
            fgets(*pagenames[i],250,readindex); //stores filenames in arrays
    to store the names & paths, and it seemed to work. (well, compiler didn't tell me I shouldn't do that, as it told if I had just char* paths[250] there.. )

    But the prolem is the class thingee...

    Code:
    tiedosto *pagefiles[250];
    .
    .
    .
    tiedosto *pagefiles[i] = new tiedosto(*pagenames[i],*paths[i]);
    just simply makes the compiler to tell me, that the "variable-sized object 'pagefiles' may not be initialized". :|

    If I use

    Code:
    tiedosto pagefiles[i] = new tiedosto(*pagenames[i],*paths[i]);
    It gives me the same error, and also tells me "no matching function for call to tiedosto::tiedosto()"
    candidates are tiedosto::tiedosto(const tiedosto&)
    and tiedosto::tiedosto(char*,char*).

    mmm.. My wild guess is that it is related to the fact my constructor needs arguments. (I did not do constructor without arguments in the class... I bet there is a way to do it without creating such constructor :| )

    Thanks for the example anyways
    10 ?"Do you want to know a good site?"
    20 Get a$
    30 IF a$ == "" THEN GOTO 20
    40 IF a$ == "y" THEN GOTO 70
    50 IF a$ == "n" THEN GOSUB 20000
    60 sys 64738
    70 GOTO <insert your fav site here>
    80 END
    20000 ?"Then I cant see why you use computer. So blind shall be you too"
    20010 FOR I = 1 to 10000
    20020 NEXT I
    20030 poke 53265,11
    20040 END
    Does this make sence?

  5. #5
    Registered User
    Join Date
    Apr 2005
    Posts
    10
    Thanks 7stud

    I am not really familiar with strings, I'm Ol' school c programmer I know I should learn them too..

    Since you suggested me to create constructor without arguments too, I think I'll try that.. If I'll run into problems again, I'll post more

    Thousand thanks to you both
    10 ?"Do you want to know a good site?"
    20 Get a$
    30 IF a$ == "" THEN GOTO 20
    40 IF a$ == "y" THEN GOTO 70
    50 IF a$ == "n" THEN GOSUB 20000
    60 sys 64738
    70 GOTO <insert your fav site here>
    80 END
    20000 ?"Then I cant see why you use computer. So blind shall be you too"
    20010 FOR I = 1 to 10000
    20020 NEXT I
    20030 poke 53265,11
    20040 END
    Does this make sence?

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Code:
    char **pagenames[250];
    
    new tiedosto(*pagenames[i],*paths[i]);
    1) pagenames is an array of pointers which point to other pointers.

    pagenames
    --------------
    pagenames[0] -------->char* p1 ---->"some text"
    pagenames[1] -------->char* p2 ---->"other text"

    2) *pagenames[0] is the pointer p1, and similarly *paths[0] is a pointer. Do you have a contructor for your class that accepts two pointers?

    [edit]: I guess you do:
    candidates are tiedosto::tiedosto(const tiedosto&)
    and tiedosto::tiedosto(char*,char*).
    This looks suspicioso though:
    Code:
    tiedosto *pagefiles[250];
    .
    .
    .
    tiedosto *pagefiles[i] = new tiedosto(*pagenames[i],*paths[i]);
    It looks like you are trying to redeclare pagefiles[]. The new operator returns an address which has to be assigned to a pointer, so you wouldn't do this either:

    *pagenames[i] = new tiedosto(*pagenames[i],*paths[i]);

    you would do this:

    pagenames[i] = new tiedosto(*pagenames[i],*paths[i]);
    Last edited by 7stud; 04-05-2005 at 04:26 AM.

  7. #7
    Registered User
    Join Date
    Apr 2005
    Posts
    10
    tiedosto.h
    Code:
    #ifndef _TIEDOSTO_H
    #define _TIEDOSTO_H
    class tiedosto 
    {
    private:
    public:
           
           tiedosto(char nim[], char pol[]); //luo uuden olion (constructor)
           
           ~tiedosto(); //destruktori (destructor)
    .
    .
    .
    This is what I have.

    I added constructor

    tiedosto(){ ; }

    but that didn't help :|

    Now I'm starting to regret I decided to learn C++
    10 ?"Do you want to know a good site?"
    20 Get a$
    30 IF a$ == "" THEN GOTO 20
    40 IF a$ == "y" THEN GOTO 70
    50 IF a$ == "n" THEN GOSUB 20000
    60 sys 64738
    70 GOTO <insert your fav site here>
    80 END
    20000 ?"Then I cant see why you use computer. So blind shall be you too"
    20010 FOR I = 1 to 10000
    20020 NEXT I
    20030 poke 53265,11
    20040 END
    Does this make sence?

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Here is my example with the class members changed to C char arrays:
    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <cstring>
    using namespace std;
    
    class File
    {
    public:
    	char path[256];
    	char name[256];
    
    	File(const char* a_path, const char* a_name) //adding const means the function
    					              //is prevented from changing the arrays
    	{
    		strcpy(path, a_path);
    		strcpy(name, a_name);
    	}
    	File()
    	{
    		strcpy(path, "");
    		strcpy(name, "");
    	}
    
    	~File()
    	{
    		cout<<"destructor called"<<endl; //displays when a File is being destroyed
    	}
    };
    
    int main()
    {
    	File* files[10];
    	
    	//open the input file:
    	ifstream inFile("C:\\TestData\\filenames.txt");
    	if(!inFile)
    	{
    		cout<<"bad file name";
    		return 0;
    	}
    
    	char input_path[256];
    	char input_name[256];
    	int i = 0;
    	while(!inFile.eof())
    	{
    		inFile.getline(input_path, 256); //read in a whole line of input
    		inFile.getline(input_name, 256); //read in a whole line of input
    		
    		files[i++] = new File(input_path, input_name);//allocate memory for a new File created 
    						             //with the input data and assign its address
    						             //to the pointer files[i]:
    		
    	}
    	
    	//display some of the input data:
    	cout<<files[0]->path<<endl;
    	cout<<files[0]->name<<endl;
    	
    	//delete memory:
    	for(int j=0; j< i; j++)
    	{
    		delete files[j];
    	}
    
    	return 0;
    }
    Last edited by 7stud; 04-05-2005 at 04:43 AM.

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    ...or you can do it like this:
    Code:
    class File
    {
    public:
    	char path[256];
    	char name[256];
    
    	File(const char a_path[256], const char a_name[256]) //adding const means the function
    							//is prevented from changing the arrays
    	{
    		strcpy(path, a_path);
    		strcpy(name, a_name);
    The name of a char array is actually a pointer to type char. When you do this:

    char text[] = "some text";

    C++ tacks a '\0' character onto the end of the string literal "some text" and puts it in memory somewhere, so it looks like this:

    some text\0

    Then, the address of that location is assigned to the name text. So, text is actually a pointer to type char. That means a function accepting an argument that is a char array with size 256 can list the parameter as either:

    char an_array[256]

    or

    char* a_pointer
    Last edited by 7stud; 04-05-2005 at 04:55 AM.

  10. #10
    Registered User
    Join Date
    Apr 2005
    Posts
    10
    I see stud

    You did the pathname & filename arrays much more clever than I That way the program updates 2 arrays instead of creating 2arrays/file

    Well, the code is still not working O_o I have no idea why :| I still get the same "variable-sized object 'pagefiles' may not be initialized"
    and build error 1.

    The class I have looks as follows:
    tiedosto.h

    Code:
    #ifndef _TIEDOSTO_H
    #define _TIEDOSTO_H
    class tiedosto 
    {
    private:
    public:
           
           tiedosto(char nim[], char pol[]); //luo uuden olion (constructor)
           tiedosto(){ ; }
           ~tiedosto(); //destruktori (destructor)
          int polunmitta; //path lenght
          int nimenmitta; //name lenght
          int kokomitta;  //path+name lenght
            char nimi[50]; //name (of the file)
            char polku[100]; //name of the path
            char kokonimi[151]; //path+name       
            FILE *ylikirjoita, *lisaa, *lue, *valiaikainen;  //filestreams
            
           int Alusta(); //alustaa (luo uuden tyhjan tiedoston palauttaa 1 jos onnistuu, 0 jos ei)
          // formats a file returns 1 if success, 0 if not.
           int korvaa(char korvattava_teksti[],char korvaava_teksti[]);//palauttaa korvattujen lkmn, -1 jos epaonnistui.
           //replaces a certain occurrance (korvattava_teksti[]) from the file with korvaava_teksti[]
           //returns amount of replaced words, -1 if fails.
           int lisaa_alkuun(char lisayskohta[],char lisattava[]); //palauttaa lis lkm:n, -1 jos epaonn
           int lisaa_loppuun(char lisayskohta[], char lisattava[]); //palauttaa lis lkm:n, -1 jos epaonn
           int kopioi(tiedosto lahde);
           int tarkista_lue();// palauttaa 0 jos kiinni, 1 jos auki
           int tarkista_lisaa();// palauttaa 0 jos kiinni, 1 jos auki
           int tarkista_ylikirjoita();// palauttaa 0 jos kiinni, 1 jos auki
           int tarkista_valiaikainen();// palauttaa 0 jos kiinni, 1 jos auki
           int close_all(); //palauttaa 1 jos onnistuu, -1 jos ei
           int avaa(char moodi); //l,k,y moodit (lue,kirjoita,ylikirjoita) palauttaa 1 (onnistui), -1(ei)
           int avaa(int n); // valiaikainen auki, 1=w,2=r,3=a palauttaa 1 (onnistui), -1(ei)
           int sulje(char moodi); //(l)ue,(k)irjoita,(y)likirj,(v)aliaik. 1 onnistui, -1 epaonn.
           /*kopioi kunnes lahdetiedostosta loytyy*/
           int lisaa_loppuun(tiedosto lahde, char paatekohta[]); //kopioi matchin loppuun: 1 onnist, -1 epaonn
           int lisaa_alkuun(tiedosto lahde, char paatekohta[]); //kopioi matchin alkuun: 1 onnist, -1 epaonn
           int lisaa_alkuun(tiedosto lahde); //palautta 1 jos onnistuu, -1 jos ei.
           int lisaa_loppuun(tiedosto lahde);
           /*kopioi kunnes lahdetiedostosta alkaa*/
           //int kopioi_alkaen_l(tiedosto lahde, char alkukohta[]); //kopioi matchin loppusta: 1 onnist, -1 epaonn
           //int kopioi_alkaen_a(tiedosto lahde, char alkukohta[]); //kopioi matchin alusta: 1 onnist, -1 epaonn
           /*kopioi paikkaan kohdetiedostossa*/
           //int kopioi_kohteeseen_l(tiedosto lahde, char alkukohta[]);
           //int kopioi_kohteeseen_a(tiedosto lahde, char alkukohta[]);
    };
    
    #endif
    The functions of the class are defined in tiedosto.cpp I won't paste it here, unless absolutely necessary, since it is

    1. Long(ish)
    2. badly written (Hey, I do not like people laughing at me)


    main now looks like :
    Code:
    #include <iostream>
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <string.h>
    #include "tiedosto.h"
    
    using namespace::std;
    
    main(){
        char pagenames[250]; //arrays for filenames
        char paths[250]; //arrays for paths
        tiedosto* pagefiles[250];
        int i=0,number_of_pages=0,lkm=0;
        FILE *readindex; // stream to read pagenames and paths from indexfile
        
        readindex=fopen("kotisivindex.txt","r"); 
            while(feof(readindex)==0){
            fgets(paths,250,readindex); //stores paths in arrays
            fgets(pagenames,250,readindex); //stores filenames in arrays
            number_of_pages++;
        tiedosto pagefiles[number_of_pages] = new tiedosto(pagenames,paths); /*creates new object.
        constructor is "tiedosto(char filename[],char path[]); So pagenames and paths should be given 
        as char arrays.*/
        }
    .
    .
    .
    }
    The creation of new object seems to be the problem. I just fail to see what's so differen't from stud's example? O_o
    Last edited by Guest852; 04-05-2005 at 06:02 AM.
    10 ?"Do you want to know a good site?"
    20 Get a$
    30 IF a$ == "" THEN GOTO 20
    40 IF a$ == "y" THEN GOTO 70
    50 IF a$ == "n" THEN GOSUB 20000
    60 sys 64738
    70 GOTO <insert your fav site here>
    80 END
    20000 ?"Then I cant see why you use computer. So blind shall be you too"
    20010 FOR I = 1 to 10000
    20020 NEXT I
    20030 poke 53265,11
    20040 END
    Does this make sence?

  11. #11
    Registered User
    Join Date
    Apr 2005
    Posts
    10
    Finally got it working...

    I used
    Code:
    tiedosto *pagefiles = new tiedosto[250]; /*creates new object.
    .
    .
    .
     while(feof(readindex)==0){
            fgets(paths,250,readindex); //stores paths in arrays
            i=strlen(paths);
            paths[i-1]='\0';
            fgets(pagenames,250,readindex); //stores filenames in arrays
            i=strlen(pagenames);
            pagenames[i-1]='\0';
            number_of_pages++;
        pagefiles[number_of_pages].maaraa(pagenames,paths); //this does basically same thing as the original constructor.
        }
    .
    .
    .
    If someone notices a mistake/bug/etc. in it, please tell me

    7stud, thanks for all help
    10 ?"Do you want to know a good site?"
    20 Get a$
    30 IF a$ == "" THEN GOTO 20
    40 IF a$ == "y" THEN GOTO 70
    50 IF a$ == "n" THEN GOSUB 20000
    60 sys 64738
    70 GOTO <insert your fav site here>
    80 END
    20000 ?"Then I cant see why you use computer. So blind shall be you too"
    20010 FOR I = 1 to 10000
    20020 NEXT I
    20030 poke 53265,11
    20040 END
    Does this make sence?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Arrays, pointers and strings
    By Apropos in forum C++ Programming
    Replies: 12
    Last Post: 03-21-2005, 11:25 PM
  2. Vectors of pointers to objects
    By Myownworstenemy in forum C++ Programming
    Replies: 3
    Last Post: 09-01-2003, 11:23 PM
  3. pointers to arrays of structures
    By terryrmcgowan in forum C Programming
    Replies: 1
    Last Post: 06-25-2003, 09:04 AM
  4. Help understanding arrays and pointers
    By James00 in forum C Programming
    Replies: 2
    Last Post: 05-27-2003, 01:41 AM
  5. Array pointers to Multi-Dimensional Arrays
    By MethodMan in forum C Programming
    Replies: 3
    Last Post: 03-18-2003, 09:53 PM