It is currently Sun Sep 24, 2017 2:25 pm




 Page 1 of 1 [ 7 posts ] 
Author Message
 Post subject: FINDING THE SIZE OF AN ARRAY OF STRINGS
PostPosted: Fri Feb 27, 2009 2:58 pm 

Joined: Fri Jan 04, 2008 2:11 pm
Posts: 72
Suppose i have an array of strings str[] , how do i find the size of this array?

one method i found in the net was

            //string *s passed to function

int size=sizeof(s)/sizeof(s[0]; // every string has the same memory length
                                           //equal to the largest string's size in the array


but this doesn't give a correct result as sizeof(s) was 4..maybe the pointers size in memory ??


Offline
 Profile  
 
 Post subject: It is not every question that deserves an answer. :)
PostPosted: Fri Feb 27, 2009 10:28 pm 

Joined: Wed Aug 06, 2008 7:53 pm
Posts: 182
Location: Russia
If you are in the same scope where the array of std::strings was declared, e.g. string sa[], you can find the size of this array using
the macro
#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( array[0] ) )
or using macro _countof().

_countof is defined in <stdlib.h>, you may read MSDN to find out more about it. In particular _countof is able to differentiate a pointer from array (pointers are not acceptable and will stop the compilation).

#ifndef ARRAY_SIZE
#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( array[0] ) )
#endif

// sizeof( array ) / sizeof( array[0] )
void foo1() {
    string sa[] = { string( "one" ), string( "two" ), string( "three" ) };
    for ( size_t t = 0; t < ARRAY_SIZE( sa[0] ); ++t )
        cout << sa[t] << endl ;
}

// _countof
void foo2() {
    string sa[] = { string( "one" ), string( "two" ), string( "three" ) };
    for ( size_t t = 0; t < _countof( sa ); ++t )
        cout << sa[t] << endl ;
}


BUT when you pass an array to some function the compiler actually passes the pointer. Thus it is impossible to deduce (inside that new function scope) the size of array, because the pointer does not contain such information as the size of the object it points to. You have to explicitly inform the function what is the number of items in your array. Or you can use the classes that know the number of items they contain, such as std::vector or boost::array (for arrays of constant size) instead of plain arrays.

void show_names( string * p, const size_t N ) {
    for ( size_t t = 0; t < N; ++t )
        cout << p[t] << endl ;
}

void starships() {
    string sa[] = { string( "Phobos" ), string( "Pioneer" ), string( "Babilon5" ) };
    show_names( sa, _countof( sa ) );
}



Here is the definition of _countof from <stdlib.h>
/* _countof helper */
#if !defined(_countof)
#if !defined(__cplusplus)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#else
extern "C++"
{
template <typename _CountofType, size_t _SizeOfArray>
char (*__countof_helper(UNALIGNED _CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray];
#define _countof(_Array) sizeof(*__countof_helper(_Array))
}
#endif
#endif


BTW, sizeof( std::string ) does not depend on the length of the string it contains, since std::string uses heap memory. Sizeof() does not take into account the size of dynamically allocated memory.


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 12:46 am 

Joined: Fri Jan 04, 2008 2:11 pm
Posts: 72
Quote:
If you are in the same scope where the array of std::strings was declared, e.g. string sa[], you can find the size of this array using
the macro
#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( array[0] ) )
or using macro _countof().


the problem is it's not in the same scope..here's the problem

#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( array[0] ) )

using namespace std;

class Lottery
{
   public:
   string sortByOdds(string s[]);
   
};

string Lottery::sortByOdds(string s[])
{
   vector<string> iv1;
   string::iterator si1;
   int i=0,size=0;

   size=sizeof(s[0]);      //32
   size=sizeof(s);         //4

   int size_of_a =  sizeof(s)/sizeof(s[0]);      // gives 0, size_of_a = 4/32 ??

   //for ( size_t t = 0; t < _countof( (s) ); ++t )
    //    cout << s[t] << endl ;




   while(s[i].length() != NULL)
   {
      iv1.push_back(s[i]);
      cout<<iv1[i];
      i++;
   }
   return *s;
}

void main()
{
   string s[]={"INDIGO: 93 8 T F",
            "ORANGE: 29 8 F T",
            "VIOLET: 76 6 F F",
            "BLUE: 100 8 T T",
            "RED: 99 8 T T",
            "GREEN: 78 6 F T",
            "YELLOW: 75 6 F F"};
   
   Lottery l;
   l.sortByOdds(s);
}


_countof gives an error..thus pointers size is shown as 4...


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 7:18 am 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1105
Location: Ontario Canada
Instead of using string s[], use std::vector<std::string> s;

To know how large your array is, call s.size();


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 7:55 am 

Joined: Fri Jan 04, 2008 2:11 pm
Posts: 72
i can't do that..it's a programming challenge and the online judge will test the code with string s[] as argument...using other variables results in errors


Offline
 Profile  
 
 Post subject: more ideas
PostPosted: Sat Feb 28, 2009 9:20 am 

Joined: Wed Aug 06, 2008 7:53 pm
Posts: 182
Location: Russia
The task is somewhat odd.

Btw, of course _countof() will produce the error, because it was intentionally written to raise compile time error if you pass the pointer instead of array name. You can use _countof() ONLY in the same scope, when the array was declared. :P

What else can be done? :roll:
Keep the size of array inside the Lottery class (as member data) or in global variable.

class Lottery
{
   public:
   string sortByOdds(string s[]);
   int size; // new field
};

void main()
{
   string s[]={"INDIGO: 93 8 T F",
            "ORANGE: 29 8 F T",
            "VIOLET: 76 6 F F",
            "BLUE: 100 8 T T",
            "RED: 99 8 T T",
            "GREEN: 78 6 F T",
            "YELLOW: 75 6 F F"};
   
   Lottery l;
   l.size = _countof(s); // not very good
   l.sortByOdds(s);
}


Or add additional parameter to the sortByOdds()

string* Lottery::sortByOdds(string s[], size_t N) {
...
}

void main()
{
   string s[]={"INDIGO: 93 8 T F",
            "ORANGE: 29 8 F T",
            "VIOLET: 76 6 F F",
            "BLUE: 100 8 T T",
            "RED: 99 8 T T",
            "GREEN: 78 6 F T",
            "YELLOW: 75 6 F F"};
   
   Lottery l;
   l.sortByOdds(s, _countof(s));
}


Or you can use special marker in the array of strings for the last item.

void main()
{
   string s[]={"INDIGO: 93 8 T F",
            "ORANGE: 29 8 F T",
            "VIOLET: 76 6 F F",
            "BLUE: 100 8 T T",
            "RED: 99 8 T T",
            "GREEN: 78 6 F T",
            "YELLOW: 75 6 F F",
            "" }; // empty string means the END. Be careful.
   
   Lottery l;
   l.sortByOdds(s);
}

string * Lottery::sortByOdds(string s[])
{
    int size = 0;
   
    while (s[size].size()) // while (s[size] != "")
        size++;

}


Offline
 Profile  
 
 Post subject:
PostPosted: Sat Feb 28, 2009 1:17 pm 

Joined: Fri Jan 04, 2008 2:11 pm
Posts: 72
well the main function is not to be written by me..i'm supposed to write the class Lottery and it's member functions only...i wrote there so my code compiles in vc++ , the contest page allows only to write the class & functions(with pre-specified arguments) ..neways it's time i move onto another problem wasted too much time on this one.


Offline
 Profile  
 
Display posts from previous:  Sort by  
 Page 1 of 1 [ 7 posts ] 


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  

cron