I have created my custom function to turn a wstring into lower case. However, it is pretty slow in DebugMode. Yes, I know ReleaseMode is what counts, but anyway it is pretty unnerving.
wstring wstringToLower(wstring u)
{
wstring s;
for (int i=0;i<u.size();i++)
{
wstring sChar;
sChar=u.substr(i,1);
int iChar=static_cast<int>(sChar[0]);
int iNewChar=charCodeToLower(iChar);
wstring sNewChar=wstring(1,iNewChar);
s.append(sNewChar);
}
return s;
}
Does anybody see anything obvious that I could improve to speed up the code, even in DebugMode?
Thank you!
There's no need to make temporary strings.
So, for start, instead of:
wstring sNewChar=wstring(1,iNewChar);
s.append(sNewChar);
This should do the trick:
s.push_back(iNewChar);
Then, instead of:
wstring sChar;
sChar=u.substr(i,1);
int iChar=static_cast<int>(sChar[0]);
This should work:
int iChar=static_cast<int>(u[i]);
And, of course, as noted by Marcel, you can do everything on the passed copy, avoiding the extra string allocation.
Also, as noted in the comments: How to convert std::string to lower case? . Also, read all answers (and comments) here: how to Make lower case letters for unicode characters :
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;
int main()
{
::setlocale(LC_ALL,"");
std::wstring data = L"НЕМАЊА БОРИЋ"; // Wide chars
std::transform(data.begin(), data.end(), data.begin(), ::towlower);
// prints немања борић
std::wcout << data << std::endl;
return 0;
}
http://en.cppreference.com/w/cpp/string/wide/towlower
First of all I would avoid to allocate memory for variables each run, since allocating is a heavy operation.
Then do not call u.size() in the for-loop declaration. It will be called every loop otherwise. Every function call less that you call in a loop is a good win for performance.
Next everything Nemanja Boric said in the other answer.
And since the variable u is passed as copy, you can use it as return value and operate directly on it.
wstring wstringToLower(wstring u)
{
int size = u.size();
for (int i = 0; i < size; ++i)
{
u[i] = charCodeToLower(static_cast<int>(u[i]));
}
return u;
}
Conclusion: Basically avoid to allocate memory or calling functions in loops. Do just as much as you really have to.
There is actually no need for the wstringToLower function at all. You can use <algorithm> to do most of the work:
std::wstring str = "Some String";
std::transform(str.begin(), str.end(), str.begin(), ::towlower);
If you are trying to localize it, you may want to modify it slightly:
std::wstring str = "Some String";
std::locale loc; // set your locale
std::transform(str.begin(), str.end(), str.begin(), [](wchar_t c)
{
return use_facet<ctype<wchar_t>>(loc).tolower(c);
});
Related
I am new to C++17 and to std::string_view.
I learned that they are not null terminated and must be handled with care.
Is this the right way to printf() one?
#include<string_view>
#include<cstdio>
int main()
{
std::string_view sv{"Hallo!"};
printf("=%*s=\n", static_cast<int>(sv.length()), sv.data());
return 0;
}
(or use it with any other printf-style function?)
This is strange requirement, but it is possible:
std::string_view s{"Hallo this is longer then needed!"};
auto sub = s.substr(0, 5);
printf("=%.*s=\n", static_cast<int>(sub.length()), sub.data());
https://godbolt.org/z/nbeMWo1G1
As you can see you were close to solution.
You can use:
assert(sv.length() <= INT_MAX);
std::printf(
"%.*s",
static_cast<int>(sv.length()),
sv.data());
The thing to remember about string_view is that it will never modify the underlying character array. So, if you pass a C-string to the string_view constructor, the sv.data() method will always return the same C-string.
So, this specific case will always work:
#include <string_view>
#include <cstdio>
int main() {
std::string_view sv {"Hallo!"};
printf("%s\n", sv.data());
}
Hello I am very new to programming and C++. I'm trying to make a program that checks if a string is a palindrome (a word that is the same backwards as it is forwards).
In order to do that I searched online about how to reverse a string and came across the reverse(string.begin(), string.end()) function from <bits/stdc++.h>.
I've made a function that can reverse the string written in the parameters and it works fine:
#include <iostream>
#include <vector>
#include <string>
#include <bits/stdc++.h>
std::string reverseStr(std::string str) {
reverse(str.begin(), str.end());
return str;
}
int main() {
std::cout << reverseStr("word");
}
But when I want to assign the reversed string into a new variable "reversedStr":
#include <iostream>
#include <vector>
#include <string>
#include <bits/stdc++.h>
std::string reverseStr(std::string str) {
std::string reversedStr;
reversedStr = reverse(str.begin(), str.end());
return reversedStr;
}
int main() {
std::cout << reverseStr("word");
}
Then when I try and compile it, it gives me this error.
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/basic_string.h:776:7: note: no known conversion for argument 1 from 'void' to 'std::initializer_list<char>'
The terminal process "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command g++ -g main.cpp" terminated with exit code: 1.
If you wouldn't mind explaining what is happening that would be great! Thank you!
reverse reverses a collection in place and doesn't return it. If you want to do it to a new variable, then first copy the string to the variable then reverse that:
// pass the str argument by reference to avoid unnecessary copies
std::string reverseStr(const std::string& str) {
std::string reversedStr = str;
std::reverse(reversedStr.begin(), reversedStr.end());
return reversedStr;
}
As stated in documentation std::reverse() does not return anything so you cannot assign it's return value to a variable. Simplest solution would be:
std::string reverseStr(const std::string &str)
{
return std::string( str.rbegin(), str.rend() );
}
using reverse iterators to initialize and return temporary std::string
std::reverse() is used to reverse the elements within the range given by the two parameters, str.begin() and str.end() in your case. This does not return a new reversed string, instead it reverses the collection itself.
If you want the reversed content in a new variable, you must first copy the original string into a new string and then reverse the new string. Alternatively you could use std::reverse_copy() which copies the reverse contents to a new string without affecting the original. It takes in a third parameter that tells where the reversed content must be copied. Do note the reversed string variable must first be resized to the original string's size.
std::string reverseStr(std::string& str) {
std::string reversedStr;
reversedStr.resize(str.size());
std::reverse_copy(str.begin(), str.end(), reversedStr.begin());
return reversedStr;
}
Some additional info: std::reverse() and std::reverse_copy() are present in the <algorithm> header file. <bits/stdc++.h> is non-standard and compiler specific and hence should be avoided. Check this answer for more details: Why should I not #include <bits/stdc++.h>?
This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 7 years ago.
I was wondering if there was an alternative to itoa() for converting an integer to a string because when I run it in visual Studio I get warnings, and when I try to build my program under Linux, I get a compilation error.
In C++11 you can use std::to_string:
#include <string>
std::string s = std::to_string(5);
If you're working with prior to C++11, you could use C++ streams:
#include <sstream>
int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
Taken from http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/
boost::lexical_cast works pretty well.
#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
std::string foo = boost::lexical_cast<std::string>(argc);
}
Archeology
itoa was a non-standard helper function designed to complement the atoi standard function, and probably hiding a sprintf (Most its features can be implemented in terms of sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html
The C Way
Use sprintf. Or snprintf. Or whatever tool you find.
Despite the fact some functions are not in the standard, as rightly mentioned by "onebyone" in one of his comments, most compiler will offer you an alternative (e.g. Visual C++ has its own _snprintf you can typedef to snprintf if you need it).
The C++ way.
Use the C++ streams (in the current case std::stringstream (or even the deprecated std::strstream, as proposed by Herb Sutter in one of his books, because it's somewhat faster).
Conclusion
You're in C++, which means that you can choose the way you want it:
The faster way (i.e. the C way), but you should be sure the code is a bottleneck in your application (premature optimizations are evil, etc.) and that your code is safely encapsulated to avoid risking buffer overruns.
The safer way (i.e., the C++ way), if you know this part of the code is not critical, so better be sure this part of the code won't break at random moments because someone mistook a size or a pointer (which happens in real life, like... yesterday, on my computer, because someone thought it "cool" to use the faster way without really needing it).
Try sprintf():
char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"
sprintf() is like printf() but outputs to a string.
Also, as Parappa mentioned in the comments, you might want to use snprintf() to stop a buffer overflow from occuring (where the number you're converting doesn't fit the size of your string.) It works like this:
snprintf(str, sizeof(str), "%d", num);
Behind the scenes, lexical_cast does this:
std::stringstream str;
str << myint;
std::string result;
str >> result;
If you don't want to "drag in" boost for this, then using the above is a good solution.
We can define our own iota function in c++ as:
string itoa(int a)
{
string ss=""; //create empty string
while(a)
{
int x=a%10;
a/=10;
char i='0';
i=i+x;
ss=i+ss; //append new character at the front of the string!
}
return ss;
}
Don't forget to #include <string>.
С++11 finally resolves this providing std::to_string.
Also boost::lexical_cast is handy tool for older compilers.
I use these templates
template <typename T> string toStr(T tmp)
{
ostringstream out;
out << tmp;
return out.str();
}
template <typename T> T strTo(string tmp)
{
T output;
istringstream in(tmp);
in >> output;
return output;
}
Try Boost.Format or FastFormat, both high-quality C++ libraries:
int i = 10;
std::string result;
WIth Boost.Format
result = str(boost::format("%1%", i));
or FastFormat
fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);
Obviously they both do a lot more than a simple conversion of a single integer
You can actually convert anything to a string with one cleverly written template function. This code example uses a loop to create subdirectories in a Win-32 system. The string concatenation operator, operator+, is used to concatenate a root with a suffix to generate directory names. The suffix is created by converting the loop control variable, i, to a C++ string, using the template function, and concatenating that with another string.
//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>
using namespace std;
string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an */
/* integer as input and as output, */
/* returns a C++ string. */
/* itoa() returned a C-string (null- */
/* terminated) */
/* This function is not needed because*/
/* the following template function */
/* does it all */
/**************************************/
string r;
stringstream s;
s << x;
r = s.str();
return r;
}
template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of */
/* C++ templates. This function will */
/* convert anything to a string! */
/* Precondition: */
/* operator<< is defined for type T */
/**************************************/
string r;
stringstream s;
s << argument;
r = s.str();
return r;
}
int main( )
{
string s;
cout << "What directory would you like me to make?";
cin >> s;
try
{
mkdir(s.c_str());
}
catch (exception& e)
{
cerr << e.what( ) << endl;
}
chdir(s.c_str());
//Using a loop and string concatenation to make several sub-directories
for(int i = 0; i < 10; i++)
{
s = "Dir_";
s = s + toString(i);
mkdir(s.c_str());
}
system("PAUSE");
return EXIT_SUCCESS;
}
Allocate a string of sufficient length, then use snprintf.
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
I wrote this thread-safe function some time ago, and am very happy with the results and feel the algorithm is lightweight and lean, with performance that is about 3X the standard MSVC _itoa() function.
Here's the link. Optimal Base-10 only itoa() function? Performance is at least 10X that of sprintf(). The benchmark is also the function's QA test, as follows.
start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
if (i != atoi(_i32toa(buff, (int32_t)i))) {
printf("\nError for %i", i);
}
if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));
There are some silly suggestions made about using the caller's storage that would leave the result floating somewhere in a buffer in the caller's address space. Ignore them. The code I listed works perfectly, as the benchmark/QA code demonstrates.
I believe this code is lean enough to use in an embedded environment. YMMV, of course.
The best answer, IMO, is the function provided here:
http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
It mimics the non-ANSI function provided by many libs.
char* itoa(int value, char* result, int base);
It's also lightning fast and optimizes well under -O3, and the reason you're not using c++ string_format() ... or sprintf is that they are too slow, right?
If you are interested in fast as well as safe integer to string conversion method and not limited to the standard library, I can recommend the format_int method from the {fmt} library:
fmt::format_int(42).str(); // convert to std::string
fmt::format_int(42).c_str(); // convert and get as a C string
// (mind the lifetime, same as std::string::c_str())
According to the integer to string conversion benchmarks from Boost Karma, this method several times faster than glibc's sprintf or std::stringstream. It is even faster than Boost Karma's own int_generator as was confirm by an independent benchmark.
Disclaimer: I'm the author of this library.
Note that all of the stringstream methods may involve locking around the use of the locale object for formatting. This may be something to be wary of if you're using this conversion from multiple threads...
See here for more. Convert a number to a string with specified length in C++
On Windows CE derived platforms, there are no iostreams by default. The way to go there is preferaby with the _itoa<> family, usually _itow<> (since most string stuff are Unicode there anyway).
Most of the above suggestions technically aren't C++, they're C solutions.
Look into the use of std::stringstream.
This question already has answers here:
Easiest way to convert int to string in C++
(30 answers)
Closed 7 years ago.
I was wondering if there was an alternative to itoa() for converting an integer to a string because when I run it in visual Studio I get warnings, and when I try to build my program under Linux, I get a compilation error.
In C++11 you can use std::to_string:
#include <string>
std::string s = std::to_string(5);
If you're working with prior to C++11, you could use C++ streams:
#include <sstream>
int i = 5;
std::string s;
std::stringstream out;
out << i;
s = out.str();
Taken from http://notfaq.wordpress.com/2006/08/30/c-convert-int-to-string/
boost::lexical_cast works pretty well.
#include <boost/lexical_cast.hpp>
int main(int argc, char** argv) {
std::string foo = boost::lexical_cast<std::string>(argc);
}
Archeology
itoa was a non-standard helper function designed to complement the atoi standard function, and probably hiding a sprintf (Most its features can be implemented in terms of sprintf): http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html
The C Way
Use sprintf. Or snprintf. Or whatever tool you find.
Despite the fact some functions are not in the standard, as rightly mentioned by "onebyone" in one of his comments, most compiler will offer you an alternative (e.g. Visual C++ has its own _snprintf you can typedef to snprintf if you need it).
The C++ way.
Use the C++ streams (in the current case std::stringstream (or even the deprecated std::strstream, as proposed by Herb Sutter in one of his books, because it's somewhat faster).
Conclusion
You're in C++, which means that you can choose the way you want it:
The faster way (i.e. the C way), but you should be sure the code is a bottleneck in your application (premature optimizations are evil, etc.) and that your code is safely encapsulated to avoid risking buffer overruns.
The safer way (i.e., the C++ way), if you know this part of the code is not critical, so better be sure this part of the code won't break at random moments because someone mistook a size or a pointer (which happens in real life, like... yesterday, on my computer, because someone thought it "cool" to use the faster way without really needing it).
Try sprintf():
char str[12];
int num = 3;
sprintf(str, "%d", num); // str now contains "3"
sprintf() is like printf() but outputs to a string.
Also, as Parappa mentioned in the comments, you might want to use snprintf() to stop a buffer overflow from occuring (where the number you're converting doesn't fit the size of your string.) It works like this:
snprintf(str, sizeof(str), "%d", num);
Behind the scenes, lexical_cast does this:
std::stringstream str;
str << myint;
std::string result;
str >> result;
If you don't want to "drag in" boost for this, then using the above is a good solution.
We can define our own iota function in c++ as:
string itoa(int a)
{
string ss=""; //create empty string
while(a)
{
int x=a%10;
a/=10;
char i='0';
i=i+x;
ss=i+ss; //append new character at the front of the string!
}
return ss;
}
Don't forget to #include <string>.
С++11 finally resolves this providing std::to_string.
Also boost::lexical_cast is handy tool for older compilers.
I use these templates
template <typename T> string toStr(T tmp)
{
ostringstream out;
out << tmp;
return out.str();
}
template <typename T> T strTo(string tmp)
{
T output;
istringstream in(tmp);
in >> output;
return output;
}
Try Boost.Format or FastFormat, both high-quality C++ libraries:
int i = 10;
std::string result;
WIth Boost.Format
result = str(boost::format("%1%", i));
or FastFormat
fastformat::fmt(result, "{0}", i);
fastformat::write(result, i);
Obviously they both do a lot more than a simple conversion of a single integer
You can actually convert anything to a string with one cleverly written template function. This code example uses a loop to create subdirectories in a Win-32 system. The string concatenation operator, operator+, is used to concatenate a root with a suffix to generate directory names. The suffix is created by converting the loop control variable, i, to a C++ string, using the template function, and concatenating that with another string.
//Mark Renslow, Globe University, Minnesota School of Business, Utah Career College
//C++ instructor and Network Dean of Information Technology
#include <cstdlib>
#include <iostream>
#include <string>
#include <sstream> // string stream
#include <direct.h>
using namespace std;
string intToString(int x)
{
/**************************************/
/* This function is similar to itoa() */
/* "integer to alpha", a non-standard */
/* C language function. It takes an */
/* integer as input and as output, */
/* returns a C++ string. */
/* itoa() returned a C-string (null- */
/* terminated) */
/* This function is not needed because*/
/* the following template function */
/* does it all */
/**************************************/
string r;
stringstream s;
s << x;
r = s.str();
return r;
}
template <class T>
string toString( T argument)
{
/**************************************/
/* This template shows the power of */
/* C++ templates. This function will */
/* convert anything to a string! */
/* Precondition: */
/* operator<< is defined for type T */
/**************************************/
string r;
stringstream s;
s << argument;
r = s.str();
return r;
}
int main( )
{
string s;
cout << "What directory would you like me to make?";
cin >> s;
try
{
mkdir(s.c_str());
}
catch (exception& e)
{
cerr << e.what( ) << endl;
}
chdir(s.c_str());
//Using a loop and string concatenation to make several sub-directories
for(int i = 0; i < 10; i++)
{
s = "Dir_";
s = s + toString(i);
mkdir(s.c_str());
}
system("PAUSE");
return EXIT_SUCCESS;
}
Allocate a string of sufficient length, then use snprintf.
int number = 123;
stringstream = s;
s << number;
cout << ss.str() << endl;
I wrote this thread-safe function some time ago, and am very happy with the results and feel the algorithm is lightweight and lean, with performance that is about 3X the standard MSVC _itoa() function.
Here's the link. Optimal Base-10 only itoa() function? Performance is at least 10X that of sprintf(). The benchmark is also the function's QA test, as follows.
start = clock();
for (int i = LONG_MIN; i < LONG_MAX; i++) {
if (i != atoi(_i32toa(buff, (int32_t)i))) {
printf("\nError for %i", i);
}
if (!i) printf("\nAt zero");
}
printf("\nElapsed time was %f milliseconds", (double)clock() - (double)(start));
There are some silly suggestions made about using the caller's storage that would leave the result floating somewhere in a buffer in the caller's address space. Ignore them. The code I listed works perfectly, as the benchmark/QA code demonstrates.
I believe this code is lean enough to use in an embedded environment. YMMV, of course.
The best answer, IMO, is the function provided here:
http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
It mimics the non-ANSI function provided by many libs.
char* itoa(int value, char* result, int base);
It's also lightning fast and optimizes well under -O3, and the reason you're not using c++ string_format() ... or sprintf is that they are too slow, right?
If you are interested in fast as well as safe integer to string conversion method and not limited to the standard library, I can recommend the format_int method from the {fmt} library:
fmt::format_int(42).str(); // convert to std::string
fmt::format_int(42).c_str(); // convert and get as a C string
// (mind the lifetime, same as std::string::c_str())
According to the integer to string conversion benchmarks from Boost Karma, this method several times faster than glibc's sprintf or std::stringstream. It is even faster than Boost Karma's own int_generator as was confirm by an independent benchmark.
Disclaimer: I'm the author of this library.
Note that all of the stringstream methods may involve locking around the use of the locale object for formatting. This may be something to be wary of if you're using this conversion from multiple threads...
See here for more. Convert a number to a string with specified length in C++
On Windows CE derived platforms, there are no iostreams by default. The way to go there is preferaby with the _itoa<> family, usually _itow<> (since most string stuff are Unicode there anyway).
Most of the above suggestions technically aren't C++, they're C solutions.
Look into the use of std::stringstream.
I am trying to iterate over all the elements of a static array of strings in the best possible way. I want to be able to declare it on one line and easily add/remove elements from it without having to keep track of the number. Sounds really simple, doesn't it?
Possible non-solutions:
vector<string> v;
v.push_back("abc");
b.push_back("xyz");
for(int i = 0; i < v.size(); i++)
cout << v[i] << endl;
Problems - no way to create the vector on one line with a list of strings
Possible non-solution 2:
string list[] = {"abc", "xyz"};
Problems - no way to get the number of strings automatically (that I know of).
There must be an easy way of doing this.
C++ 11 added initialization lists to allow the following syntax:
std::vector<std::string> v = {"Hello", "World"};
Support for this C++ 11 feature was added in at least GCC 4.4 and only in Visual Studio 2013.
You can concisely initialize a vector<string> from a statically-created char* array:
char* strarray[] = {"hey", "sup", "dogg"};
vector<string> strvector(strarray, strarray + 3);
This copies all the strings, by the way, so you use twice the memory. You can use Will Dean's suggestion to replace the magic number 3 here with arraysize(str_array) -- although I remember there being some special case in which that particular version of arraysize might do Something Bad (sorry I can't remember the details immediately). But it very often works correctly.
Also, if you're really gung-ho about the one line thingy, you can define a variadic macro so that a single line such as DEFINE_STR_VEC(strvector, "hi", "there", "everyone"); works.
Problems - no way to get the number of strings automatically (that i know of).
There is a bog-standard way of doing this, which lots of people (including MS) define macros like arraysize for:
#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))
Declare an array of strings in C++ like this : char array_of_strings[][]
For example : char array_of_strings[200][8192];
will hold 200 strings, each string having the size 8kb or 8192 bytes.
use strcpy(line[i],tempBuffer); to put data in the array of strings.
One possiblity is to use a NULL pointer as a flag value:
const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
cout << *iList;
}
You can use the begin and end functions from the Boost range library to easily find the ends of a primitive array, and unlike the macro solution, this will give a compile error instead of broken behaviour if you accidentally apply it to a pointer.
const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));
You can use Will Dean's suggestion [#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))] to replace the magic number 3 here with arraysize(str_array) -- although I remember there being some special case in which that particular version of arraysize might do Something Bad (sorry I can't remember the details immediately). But it very often works correctly.
The case where it doesn't work is when the "array" is really just a pointer, not an actual array. Also, because of the way arrays are passed to functions (converted to a pointer to the first element), it doesn't work across function calls even if the signature looks like an array — some_function(string parameter[]) is really some_function(string *parameter).
Here's an example:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
int main() {
const char* const list[] = {"zip", "zam", "bam"};
const size_t len = sizeof(list) / sizeof(list[0]);
for (size_t i = 0; i < len; ++i)
std::cout << list[i] << "\n";
const std::vector<string> v(list, list + len);
std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));
}
Instead of that macro, might I suggest this one:
template<typename T, int N>
inline size_t array_size(T(&)[N])
{
return N;
}
#define ARRAY_SIZE(X) (sizeof(array_size(X)) ? (sizeof(X) / sizeof((X)[0])) : -1)
1) We want to use a macro to make it a compile-time constant; the function call's result is not a compile-time constant.
2) However, we don't want to use a macro because the macro could be accidentally used on a pointer. The function can only be used on compile-time arrays.
So, we use the defined-ness of the function to make the macro "safe"; if the function exists (i.e. it has non-zero size) then we use the macro as above. If the function does not exist we return a bad value.
#include <boost/foreach.hpp>
const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
cout << str << endl;
}
#include <iostream>
#include <string>
#include <vector>
#include <boost/assign/list_of.hpp>
int main()
{
const std::vector< std::string > v = boost::assign::list_of( "abc" )( "xyz" );
std::copy(
v.begin(),
v.end(),
std::ostream_iterator< std::string >( std::cout, "\n" ) );
}
You can directly declare an array of strings like string s[100];.
Then if you want to access specific elements, you can get it directly like s[2][90]. For iteration purposes, take the size of string using the
s[i].size() function.