• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 09:36
CEST 15:36
KST 22:36
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
[ASL19] Finals Recap: Standing Tall9HomeStory Cup 27 - Info & Preview18Classic wins Code S Season 2 (2025)16Code S RO4 & Finals Preview: herO, Rogue, Classic, GuMiho0TL Team Map Contest #5: Presented by Monster Energy6
Community News
Weekly Cups (June 30 - July 6): Classic Doubles1[BSL20] Non-Korean Championship 4x BSL + 4x China7Flash Announces Hiatus From ASL64Weekly Cups (June 23-29): Reynor in world title form?13FEL Cracov 2025 (July 27) - $8000 live event22
StarCraft 2
General
Weekly Cups (June 30 - July 6): Classic Doubles Program: SC2 / XSplit / OBS Scene Switcher The SCII GOAT: A statistical Evaluation Statistics for vetoed/disliked maps Weekly Cups (June 23-29): Reynor in world title form?
Tourneys
RSL: Revival, a new crowdfunded tournament series FEL Cracov 2025 (July 27) - $8000 live event Sparkling Tuna Cup - Weekly Open Tournament WardiTV Mondays Korean Starcraft League Week 77
Strategy
How did i lose this ZvP, whats the proper response Simple Questions Simple Answers
Custom Maps
[UMS] Zillion Zerglings
External Content
Mutation # 481 Fear and Lava Mutation # 480 Moths to the Flame Mutation # 479 Worn Out Welcome Mutation # 478 Instant Karma
Brood War
General
SC uni coach streams logging into betting site BGH Auto Balance -> http://bghmmr.eu/ ASL20 Preliminary Maps Flash Announces Hiatus From ASL Player “Jedi” cheat on CSL
Tourneys
[BSL20] Grand Finals - Sunday 20:00 CET [BSL20] Non-Korean Championship 4x BSL + 4x China CSL Xiamen International Invitational The Casual Games of the Week Thread
Strategy
Simple Questions, Simple Answers I am doing this better than progamers do.
Other Games
General Games
Stormgate/Frost Giant Megathread Path of Exile Nintendo Switch Thread What do you want from future RTS games? Beyond All Reason
Dota 2
Official 'what is Dota anymore' discussion
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Heroes of StarCraft mini-set
TL Mafia
TL Mafia Community Thread Vanilla Mini Mafia
Community
General
US Politics Mega-thread Russo-Ukrainian War Thread Stop Killing Games - European Citizens Initiative Summer Games Done Quick 2024! Summer Games Done Quick 2025!
Fan Clubs
SKT1 Classic Fan Club! Maru Fan Club
Media & Entertainment
Anime Discussion Thread [Manga] One Piece [\m/] Heavy Metal Thread
Sports
Formula 1 Discussion 2024 - 2025 Football Thread NBA General Discussion TeamLiquid Health and Fitness Initiative For 2023 NHL Playoffs 2024
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread
TL Community
The Automated Ban List
Blogs
Culture Clash in Video Games…
TrAiDoS
from making sc maps to makin…
Husyelt
Blog #2
tankgirl
StarCraft improvement
iopq
Trip to the Zoo
micronesia
Customize Sidebar...

Website Feedback

Closed Threads



Active: 723 users

The Big Programming Thread - Page 154

Forum Index > General Forum
Post a Reply
Prev 1 152 153 154 155 156 1031 Next
Thread Rules
1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution.
2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20)
3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible.
4. Use [code] tags to format code blocks.
Ethenielle
Profile Blog Joined December 2005
Norway1006 Posts
August 06 2012 09:40 GMT
#3061
You can also save yourself a lot of pain.

auto join = [](const std::vector<std::string>& strings) -> std::string {
std::string joined;
std::for_each( begin(strings), end(strings), [&](const std::string& str) {
joined += str; //+ some delimiter
});
return joined;
};
Theres a fine line between fishing and just standing on the shore like an idiot.
netherh
Profile Blog Joined November 2011
United Kingdom333 Posts
Last Edited: 2012-08-06 10:58:55
August 06 2012 10:52 GMT
#3062
On August 06 2012 14:01 JeanLuc wrote:
And basically, if you're so inclined, please bash this code and tell me why its noob (somethign which I intuit it to be). Thanks for any help you can offer.


The primary reason your code "is noob", is because you don't use code already written and tested by other people, so that you don't have to roll your own. In C++ this is means using the Standard Library and the Boost libraries. While it's ok to write your own version of things to learn, you'll often find that your best solution will / should approach the already existing standard one. Yours is quite a way off.

Firstly, you want to eliminate doing memory management yourself. Never use char* when you can use std::string instead - this is C++, not C. (See Version 1 below).

Next, you want to eliminate the error prone passing of the array size. Why not use a standard container instead? (See Version 2 below). Note that we explicitly use a const reference now. The array actually degrades to a pointer, but we don't want to pass a standard container by value.

Now that the code is much simpler it's clear there're some cases that haven't been considered. What if the container is empty? Maybe there's a better way of adding the delimiter to cope with the fact that we don't want it appended at the end as well. (See Version 3 below). If there's no better existing solution, and all we need is a function to do this for a specific container and string in our code, it's fine to go this far and stop here.

But what if we don't want to pass in a std::vector, but a list / boost::array instead? What if someone's using something other than std::string? Well, that's where templates come in, to allow us to make the function generic (see Version 4). Things have started to get complicated though, and there are more things to worry about, like using insert instead of += (more standard). There are probably better ways to genericise this and detect string / iterator types. By this point we're almost certainly better off using boost.

+ Show Spoiler +



#include <string>
#include <vector>
#include <iostream>

#include <boost/array.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>


std::string string_join1(std::string* input, unsigned int input_size, const std::string& separator)
{
std::string output;

for (unsigned int i = 0; i != input_size; ++i)
{
output += input[i];

if (i < input_size - 1)
output += separator;
}

return output;
}

std::string string_join2(const std::vector<std::string>& input, const std::string& separator)
{
std::string output;

for (std::vector<std::string>::const_iterator i = input.begin(); i != input.end(); ++i)
{
output += *i;

if (i != input.end() - 1)
output += separator;
}

return output;
}

std::string string_join3(const std::vector<std::string>& input, const std::string& separator)
{
std::vector<std::string>::const_iterator begin = input.begin();
std::vector<std::string>::const_iterator end = input.end();

std::string output;

if (begin != end)
{
output += *begin;
++begin;
}

for ( ; begin != end; ++begin)
{
output += separator;
output += *begin;
}

return output;
}

template <typename ContainerT>
typename ContainerT::value_type string_join4(const ContainerT& input, const typename ContainerT::value_type& separator)
{
typedef ContainerT::const_iterator IteratorT;

IteratorT begin = input.begin();
IteratorT end = input.end();

ContainerT::value_type output;

if (begin != end)
{
output.insert(output.end(), begin->begin(), begin->end());
++begin;
}

for ( ; begin != end; ++begin)
{
output.insert(output.end(), separator.begin(), separator.end());
output.insert(output.end(), begin->begin(), begin->end());
}

return output;
}



int main(int, char*[])
{
const std::string separator = ", ";

{
// Version 1 - using std::string
std::string input[] = { "Test", "test", "test", "test." };

std::string output = string_join1(input, 4, separator);

std::cout << "string_join1: " << output << std::endl;
}

{
// Version 2 - using a std::foo container
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join2(input, separator);

std::cout << "string_join2: " << output << std::endl;
}

{
// Version 3 - fix dodgy edge cases
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join3(input, separator);

std::cout << "string_join3: " << output << std::endl;
}

{
// Version 4 - genericise (we can use a different container / string type now!)
boost::array<std::wstring, 4> input = { L"Test", L"test", L"test", L"test." };
const std::wstring wseperator = L", ";

std::wstring output = string_join4(input, wseperator);

std::wcout << "string_join4: " << output << std::endl;
}

{
// Version 5 - use Boost
boost::array<std::string, 4> input = { "Test", "test", "test", "test." };

std::string output = boost::algorithm::join(input, separator);

std::cout << "boost: " << output << std::endl;
}
}

netherh
Profile Blog Joined November 2011
United Kingdom333 Posts
August 06 2012 10:55 GMT
#3063
On August 06 2012 18:40 Ethenielle wrote:
You can also save yourself a lot of pain.

auto join = [](const std::vector<std::string>& strings) -> std::string {
std::string joined;
std::for_each( begin(strings), end(strings), [&](const std::string& str) {
joined += str; //+ some delimiter
});
return joined;
};


Won't this add the delimiter after the last string as well?
Ethenielle
Profile Blog Joined December 2005
Norway1006 Posts
August 06 2012 11:34 GMT
#3064
Yes, it would, easily solved by a pop_back after the foreach.
Theres a fine line between fishing and just standing on the shore like an idiot.
SRBNikola
Profile Blog Joined July 2011
Serbia191 Posts
August 06 2012 13:26 GMT
#3065
On August 06 2012 19:52 netherh wrote:
Show nested quote +
On August 06 2012 14:01 JeanLuc wrote:
And basically, if you're so inclined, please bash this code and tell me why its noob (somethign which I intuit it to be). Thanks for any help you can offer.


The primary reason your code "is noob", is because you don't use code already written and tested by other people, so that you don't have to roll your own. In C++ this is means using the Standard Library and the Boost libraries. While it's ok to write your own version of things to learn, you'll often find that your best solution will / should approach the already existing standard one. Yours is quite a way off.

Firstly, you want to eliminate doing memory management yourself. Never use char* when you can use std::string instead - this is C++, not C. (See Version 1 below).

Next, you want to eliminate the error prone passing of the array size. Why not use a standard container instead? (See Version 2 below). Note that we explicitly use a const reference now. The array actually degrades to a pointer, but we don't want to pass a standard container by value.

Now that the code is much simpler it's clear there're some cases that haven't been considered. What if the container is empty? Maybe there's a better way of adding the delimiter to cope with the fact that we don't want it appended at the end as well. (See Version 3 below). If there's no better existing solution, and all we need is a function to do this for a specific container and string in our code, it's fine to go this far and stop here.

But what if we don't want to pass in a std::vector, but a list / boost::array instead? What if someone's using something other than std::string? Well, that's where templates come in, to allow us to make the function generic (see Version 4). Things have started to get complicated though, and there are more things to worry about, like using insert instead of += (more standard). There are probably better ways to genericise this and detect string / iterator types. By this point we're almost certainly better off using boost.

+ Show Spoiler +



#include <string>
#include <vector>
#include <iostream>

#include <boost/array.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>


std::string string_join1(std::string* input, unsigned int input_size, const std::string& separator)
{
std::string output;

for (unsigned int i = 0; i != input_size; ++i)
{
output += input[i];

if (i < input_size - 1)
output += separator;
}

return output;
}

std::string string_join2(const std::vector<std::string>& input, const std::string& separator)
{
std::string output;

for (std::vector<std::string>::const_iterator i = input.begin(); i != input.end(); ++i)
{
output += *i;

if (i != input.end() - 1)
output += separator;
}

return output;
}

std::string string_join3(const std::vector<std::string>& input, const std::string& separator)
{
std::vector<std::string>::const_iterator begin = input.begin();
std::vector<std::string>::const_iterator end = input.end();

std::string output;

if (begin != end)
{
output += *begin;
++begin;
}

for ( ; begin != end; ++begin)
{
output += separator;
output += *begin;
}

return output;
}

template <typename ContainerT>
typename ContainerT::value_type string_join4(const ContainerT& input, const typename ContainerT::value_type& separator)
{
typedef ContainerT::const_iterator IteratorT;

IteratorT begin = input.begin();
IteratorT end = input.end();

ContainerT::value_type output;

if (begin != end)
{
output.insert(output.end(), begin->begin(), begin->end());
++begin;
}

for ( ; begin != end; ++begin)
{
output.insert(output.end(), separator.begin(), separator.end());
output.insert(output.end(), begin->begin(), begin->end());
}

return output;
}



int main(int, char*[]
{
const std::string separator = ", ";

{
// Version 1 - using std::string
std::string input[] = { "Test", "test", "test", "test." };

std::string output = string_join1(input, 4, separator);

std::cout << "string_join1: " << output << std::endl;
}

{
// Version 2 - using a std::foo container
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join2(input, separator);

std::cout << "string_join2: " << output << std::endl;
}

{
// Version 3 - fix dodgy edge cases
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join3(input, separator);

std::cout << "string_join3: " << output << std::endl;
}

{
// Version 4 - genericise (we can use a different container / string type now!)
boost::array<std::wstring, 4> input = { L"Test", L"test", L"test", L"test." };
const std::wstring wseperator = L", ";

std::wstring output = string_join4(input, wseperator);

std::wcout << "string_join4: " << output << std::endl;
}

{
// Version 5 - use Boost
boost::array<std::string, 4> input = { "Test", "test", "test", "test." };

std::string output = boost::algorithm::join(input, separator);

std::cout << "boost: " << output << std::endl;
}
}



Many of your arguments are debatable when to use and when not to, for example ALWAYS use string object and never char array is bad argument, just because its C++ there i plenty more things to think about when to use and when not to.
heishe
Profile Blog Joined June 2009
Germany2284 Posts
Last Edited: 2012-08-06 13:53:23
August 06 2012 13:44 GMT
#3066
On August 06 2012 22:26 SRBNikola wrote:
Show nested quote +
On August 06 2012 19:52 netherh wrote:
On August 06 2012 14:01 JeanLuc wrote:
And basically, if you're so inclined, please bash this code and tell me why its noob (somethign which I intuit it to be). Thanks for any help you can offer.


The primary reason your code "is noob", is because you don't use code already written and tested by other people, so that you don't have to roll your own. In C++ this is means using the Standard Library and the Boost libraries. While it's ok to write your own version of things to learn, you'll often find that your best solution will / should approach the already existing standard one. Yours is quite a way off.

Firstly, you want to eliminate doing memory management yourself. Never use char* when you can use std::string instead - this is C++, not C. (See Version 1 below).

Next, you want to eliminate the error prone passing of the array size. Why not use a standard container instead? (See Version 2 below). Note that we explicitly use a const reference now. The array actually degrades to a pointer, but we don't want to pass a standard container by value.

Now that the code is much simpler it's clear there're some cases that haven't been considered. What if the container is empty? Maybe there's a better way of adding the delimiter to cope with the fact that we don't want it appended at the end as well. (See Version 3 below). If there's no better existing solution, and all we need is a function to do this for a specific container and string in our code, it's fine to go this far and stop here.

But what if we don't want to pass in a std::vector, but a list / boost::array instead? What if someone's using something other than std::string? Well, that's where templates come in, to allow us to make the function generic (see Version 4). Things have started to get complicated though, and there are more things to worry about, like using insert instead of += (more standard). There are probably better ways to genericise this and detect string / iterator types. By this point we're almost certainly better off using boost.

+ Show Spoiler +



#include <string>
#include <vector>
#include <iostream>

#include <boost/array.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>


std::string string_join1(std::string* input, unsigned int input_size, const std::string& separator)
{
std::string output;

for (unsigned int i = 0; i != input_size; ++i)
{
output += input[i];

if (i < input_size - 1)
output += separator;
}

return output;
}

std::string string_join2(const std::vector<std::string>& input, const std::string& separator)
{
std::string output;

for (std::vector<std::string>::const_iterator i = input.begin(); i != input.end(); ++i)
{
output += *i;

if (i != input.end() - 1)
output += separator;
}

return output;
}

std::string string_join3(const std::vector<std::string>& input, const std::string& separator)
{
std::vector<std::string>::const_iterator begin = input.begin();
std::vector<std::string>::const_iterator end = input.end();

std::string output;

if (begin != end)
{
output += *begin;
++begin;
}

for ( ; begin != end; ++begin)
{
output += separator;
output += *begin;
}

return output;
}

template <typename ContainerT>
typename ContainerT::value_type string_join4(const ContainerT& input, const typename ContainerT::value_type& separator)
{
typedef ContainerT::const_iterator IteratorT;

IteratorT begin = input.begin();
IteratorT end = input.end();

ContainerT::value_type output;

if (begin != end)
{
output.insert(output.end(), begin->begin(), begin->end());
++begin;
}

for ( ; begin != end; ++begin)
{
output.insert(output.end(), separator.begin(), separator.end());
output.insert(output.end(), begin->begin(), begin->end());
}

return output;
}



int main(int, char*[]
{
const std::string separator = ", ";

{
// Version 1 - using std::string
std::string input[] = { "Test", "test", "test", "test." };

std::string output = string_join1(input, 4, separator);

std::cout << "string_join1: " << output << std::endl;
}

{
// Version 2 - using a std::foo container
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join2(input, separator);

std::cout << "string_join2: " << output << std::endl;
}

{
// Version 3 - fix dodgy edge cases
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join3(input, separator);

std::cout << "string_join3: " << output << std::endl;
}

{
// Version 4 - genericise (we can use a different container / string type now!)
boost::array<std::wstring, 4> input = { L"Test", L"test", L"test", L"test." };
const std::wstring wseperator = L", ";

std::wstring output = string_join4(input, wseperator);

std::wcout << "string_join4: " << output << std::endl;
}

{
// Version 5 - use Boost
boost::array<std::string, 4> input = { "Test", "test", "test", "test." };

std::string output = boost::algorithm::join(input, separator);

std::cout << "boost: " << output << std::endl;
}
}



Many of your arguments are debatable when to use and when not to, for example ALWAYS use string object and never char array is bad argument, just because its C++ there i plenty more things to think about when to use and when not to.


While the word "always" makes his statement a generalization, his advice is still good, since using std::string over char*, or std::vector<T> over T* and unsigned int size, etc. should be the standard choice in the large majority of cases.

In fact, it's very unlikely that you're ever going to be in a situation where you really need char* or T*. And don't start talking about performance critical applications:

First of all, these containers are so well optimized by the library writers and also compilers that everything a pure array will give you over the container is more code and no speed-up. Second, performance increases aren't hidden in these kinds of places, but rather in places like (besides algorithm optimization, of course) cache-friendly memory alignment, vectorization, thread or process parallelism, custom allocators, branch free programming etc.

So you'd be very hard pressed to find real-world examples where char* is actually to be preferred over std::string.

On boost, though: I avoid it like the plague, when I can. Everything in there bloats compile time and binary size like a motherfucker. Sometimes you can't really, though, since boost contains some excellent libraries (filesystem, or python, for example).

On August 06 2012 18:40 Ethenielle wrote:
You can also save yourself a lot of pain.

auto join = [](const std::vector<std::string>& strings) -> std::string {
std::string joined;
std::for_each( begin(strings), end(strings), [&](const std::string& str) {
joined += str; //+ some delimiter
});
return joined;
};


If you use a lambda expression, you might as well use built-in for-each as well


auto join = [](const std::vector<std::string>& strings) -> std::string {
std::string joined;
for(std::string &str : strings) {
joined += str; //+ some delimiter
});
return joined;
};

If you value your soul, never look into the eye of a horse. Your soul will forever be lost in the void of the horse.
Ethenielle
Profile Blog Joined December 2005
Norway1006 Posts
August 06 2012 16:57 GMT
#3067
Unfortunately that doesn't work in VS2010. Not mine, anyway... But yea, join is pretty much just a for loop, I don't see much point in complicating it.
Theres a fine line between fishing and just standing on the shore like an idiot.
KainiT
Profile Joined July 2011
Austria392 Posts
August 06 2012 20:45 GMT
#3068
I hope this doesn't make people angry since html and css aren't programming languages but i still think this is a better place than making a new thread like many people did in the past about similar problems

i have the classical "why is the body not from the top to the bottom?-problem" the thing is all those css "solutions" like body,html{height:100%;} don't work,
here's my example page: http://www.unet.univie.ac.at/~a1101537/
as you can see(with firebug etc, guess I don't have to explain this to the people that can help me^^) the body begins 60px below the top because appearantly it is affected by the div#kopfbereich css container which should be 60 px from the top... So what do I need to do in order to have a body that actually is 100%? Im obviously a html/css noob, any help much appreciated
With great power comes great responsibility.
JeanLuc
Profile Joined September 2010
Canada377 Posts
August 06 2012 20:56 GMT
#3069
On August 06 2012 19:52 netherh wrote:
Show nested quote +
On August 06 2012 14:01 JeanLuc wrote:
And basically, if you're so inclined, please bash this code and tell me why its noob (somethign which I intuit it to be). Thanks for any help you can offer.


The primary reason your code "is noob", is because you don't use code already written and tested by other people, so that you don't have to roll your own. In C++ this is means using the Standard Library and the Boost libraries. While it's ok to write your own version of things to learn, you'll often find that your best solution will / should approach the already existing standard one. Yours is quite a way off.

Firstly, you want to eliminate doing memory management yourself. Never use char* when you can use std::string instead - this is C++, not C. (See Version 1 below).

Next, you want to eliminate the error prone passing of the array size. Why not use a standard container instead? (See Version 2 below). Note that we explicitly use a const reference now. The array actually degrades to a pointer, but we don't want to pass a standard container by value.

Now that the code is much simpler it's clear there're some cases that haven't been considered. What if the container is empty? Maybe there's a better way of adding the delimiter to cope with the fact that we don't want it appended at the end as well. (See Version 3 below). If there's no better existing solution, and all we need is a function to do this for a specific container and string in our code, it's fine to go this far and stop here.

But what if we don't want to pass in a std::vector, but a list / boost::array instead? What if someone's using something other than std::string? Well, that's where templates come in, to allow us to make the function generic (see Version 4). Things have started to get complicated though, and there are more things to worry about, like using insert instead of += (more standard). There are probably better ways to genericise this and detect string / iterator types. By this point we're almost certainly better off using boost.

+ Show Spoiler +



#include <string>
#include <vector>
#include <iostream>

#include <boost/array.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/join.hpp>


std::string string_join1(std::string* input, unsigned int input_size, const std::string& separator)
{
std::string output;

for (unsigned int i = 0; i != input_size; ++i)
{
output += input[i];

if (i < input_size - 1)
output += separator;
}

return output;
}

std::string string_join2(const std::vector<std::string>& input, const std::string& separator)
{
std::string output;

for (std::vector<std::string>::const_iterator i = input.begin(); i != input.end(); ++i)
{
output += *i;

if (i != input.end() - 1)
output += separator;
}

return output;
}

std::string string_join3(const std::vector<std::string>& input, const std::string& separator)
{
std::vector<std::string>::const_iterator begin = input.begin();
std::vector<std::string>::const_iterator end = input.end();

std::string output;

if (begin != end)
{
output += *begin;
++begin;
}

for ( ; begin != end; ++begin)
{
output += separator;
output += *begin;
}

return output;
}

template <typename ContainerT>
typename ContainerT::value_type string_join4(const ContainerT& input, const typename ContainerT::value_type& separator)
{
typedef ContainerT::const_iterator IteratorT;

IteratorT begin = input.begin();
IteratorT end = input.end();

ContainerT::value_type output;

if (begin != end)
{
output.insert(output.end(), begin->begin(), begin->end());
++begin;
}

for ( ; begin != end; ++begin)
{
output.insert(output.end(), separator.begin(), separator.end());
output.insert(output.end(), begin->begin(), begin->end());
}

return output;
}



int main(int, char*[]
{
const std::string separator = ", ";

{
// Version 1 - using std::string
std::string input[] = { "Test", "test", "test", "test." };

std::string output = string_join1(input, 4, separator);

std::cout << "string_join1: " << output << std::endl;
}

{
// Version 2 - using a std::foo container
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join2(input, separator);

std::cout << "string_join2: " << output << std::endl;
}

{
// Version 3 - fix dodgy edge cases
std::vector<std::string> input;
input.push_back("Test");
input.push_back("test");
input.push_back("test");
input.push_back("test.");

std::string output = string_join3(input, separator);

std::cout << "string_join3: " << output << std::endl;
}

{
// Version 4 - genericise (we can use a different container / string type now!)
boost::array<std::wstring, 4> input = { L"Test", L"test", L"test", L"test." };
const std::wstring wseperator = L", ";

std::wstring output = string_join4(input, wseperator);

std::wcout << "string_join4: " << output << std::endl;
}

{
// Version 5 - use Boost
boost::array<std::string, 4> input = { "Test", "test", "test", "test." };

std::string output = boost::algorithm::join(input, separator);

std::cout << "boost: " << output << std::endl;
}
}



Much thanks for your input, and these examples. This will give me a lot to think about/pursue.
If you can't find it within yourself to stand up and tell the truth-- you don't deserve to wear that uniform
waxypants
Profile Blog Joined September 2009
United States479 Posts
August 06 2012 21:15 GMT
#3070
On August 06 2012 18:12 Abductedonut wrote:
Show nested quote +
On August 06 2012 14:01 JeanLuc wrote:
Hi guys,

I was hoping people who are studying C/C++ could help me with this. I have come back to C++ from a long sojourn learning "easier" languages such as Java, C#. My understanding of C++ was never that great, but I find myself confused about a lot of stuff. In this bit of code I tried writing a version of the common join() function you see in a lot of languages: basically, you give an array of strings to join() and it returns a string of the concatenated elements separated by a delimiter. What I have here seems to work but I have a bunch of questions to ask:

+ Show Spoiler +

//join.cpp
#include "join.h"
#include <iostream>
#include <cstring>
using namespace std;

int main(){
char * arr[]={"Yo","Adrian!","I","Did","It!","said","Rocky"};
char delimiter=',';

const char * phrase=join(arr,delimiter,sizeof(arr)/sizeof(char *));
cout<<phrase<<endl;
if(phrase!=NULL)
delete [] phrase;

}

const char * join(char * arr[], char delimiter, int words){
char * str;
int len=0;
int a=0;
for(int i=0; i<words; i++){
len+=strlen(arr[i])+1;
}
str=new char[len];
for(int i=0; i<words; i++){
for(int j=0; j<strlen(arr[i]); j++){
str[a++]=arr[i][j];
}
if(i<(words-1)) str[a++]=delimiter;
}
str[a]='\0';
return str;
}


One thing I'm curious about is.. whether the memory allocation/deallocation in this is handled OKAY. Is there a way to determine the length of the array of char pointers within the function so I don't need to pass that as a parameter? Is it necessary that the function return a const char *?


And basically, if you're so inclined, please bash this code and tell me why its noob (somethign which I intuit it to be). Thanks for any help you can offer.


Here's something to bash your code. Declaring arr as:
char *arr[]= {"Yo","Adrian!","I","Did","It!","said","Rocky",NULL};

Leads to a NULL pointer dereference which could potentially allow a hacker to control flow of execution in your program by Mapping address 0 to a pointer that points to a function of his choice. Alternatively, it can be used to crash your program. Not very good if it's a anti-virus

Happy Programming!


Whatchu talking about? He's not executing code pointed to by any of those pointers, just reading and copying data. If you somehow have NULL mapped to something, it will just treat whatever its pointing to as a string of bytes. Anyway if a hacker is able to remap your memory and change your page tables, then I think that the exploitability of this function is the least of your concerns.

Actually to address the question of array length, you could actually NULL terminate the array (as shown above) and calculate the length by searching for the NULL pointer. Thats how glib does it.
waxypants
Profile Blog Joined September 2009
United States479 Posts
August 06 2012 21:18 GMT
#3071
On August 06 2012 18:40 Ethenielle wrote:
You can also save yourself a lot of pain.

auto join = [](const std::vector<std::string>& strings) -> std::string {
std::string joined;
std::for_each( begin(strings), end(strings), [&](const std::string& str) {
joined += str; //+ some delimiter
});
return joined;
};

God damn this is why I hate C++. The ugliest syntax Ive seen. C ftw
Abductedonut
Profile Blog Joined December 2010
United States324 Posts
August 06 2012 23:17 GMT
#3072
On August 07 2012 06:18 waxypants wrote:
Show nested quote +
On August 06 2012 18:40 Ethenielle wrote:
You can also save yourself a lot of pain.

auto join = [](const std::vector<std::string>& strings) -> std::string {
std::string joined;
std::for_each( begin(strings), end(strings), [&](const std::string& str) {
joined += str; //+ some delimiter
});
return joined;
};

God damn this is why I hate C++. The ugliest syntax Ive seen. C ftw


Yeah, C++ is terrible. That looks like complete trash.
tofucake
Profile Blog Joined October 2009
Hyrule19031 Posts
August 06 2012 23:36 GMT
#3073
it'd look a bit better if he declared his namespace
Liquipediaasante sana squash banana
Ethenielle
Profile Blog Joined December 2005
Norway1006 Posts
August 06 2012 23:51 GMT
#3074
Yea, that'd save about 10 characters of code...

Syntax arguments and opinions. God save us all. I might as well chime in.

BLAH BLAH C BLAH RAW POINTER ARITHMETIC BLAH BLAH URGH.
Theres a fine line between fishing and just standing on the shore like an idiot.
tofucake
Profile Blog Joined October 2009
Hyrule19031 Posts
Last Edited: 2012-08-06 23:55:03
August 06 2012 23:54 GMT
#3075
30 actually, but that's because I'm counting. Besides, my point was that it'd be slightly less ugly, not necessarily that it's a time saver or anything
Liquipediaasante sana squash banana
EscPlan9
Profile Blog Joined December 2006
United States2777 Posts
Last Edited: 2012-08-07 05:52:55
August 07 2012 05:46 GMT
#3076
I notice many employers looking for people who have experience with Mobile App Development, Mobile Web Development, or Social Networking APIs. I have none of those. Any recommendations for books or sites to get myself into learning and practicing the fundamentals and eventually making my own? I skimmed through a book called Building Android Adds using HTML, CSS and Javascript by Starks and it seemed like it might be good?
http://www.amazon.com/Building-Android-Apps-HTML-JavaScript/dp/1449316417/ref=wl_it_dp_o_pC_nS_nC?ie=UTF8&coliid=IOUCW0NYIJPFL&colid=WVLO8POCVYWQ

If possible, in the process of learning Mobile App/Web dev and Social Networking APIs I'd like to solidify my web development skills using HTML, CSS, Javascript, and jQuery mostly. That's a big part about why I think I might like that book.

Thanks for any suggestions!

edit: A little background on my current skills. I'm most experienced with programming in C#, and have mild experience with C++, Java, VBScript, Perl, batch processing, CSS, and HTML.
Undefeated TL Tecmo Super Bowl League Champion
ShoCkeyy
Profile Blog Joined July 2008
7815 Posts
August 08 2012 02:13 GMT
#3077
Anybody know anything about parallax scrolling and setting heights to certain "pages"?
Life?
weishime
Profile Joined August 2011
65 Posts
August 08 2012 04:35 GMT
#3078
On August 08 2012 11:13 ShoCkeyy wrote:
Anybody know anything about parallax scrolling and setting heights to certain "pages"?


If you mean web, yeah. There are a few libraries for that. A nice one is Stellar.js.
DanceSC
Profile Blog Joined March 2008
United States751 Posts
Last Edited: 2012-08-08 06:24:28
August 08 2012 06:20 GMT
#3079
On August 07 2012 14:46 EscPlan9 wrote:
I notice many employers looking for people who have experience with Mobile App Development, Mobile Web Development, or Social Networking APIs. I have none of those. Any recommendations for books or sites to get myself into learning and practicing the fundamentals and eventually making my own? I skimmed through a book called Building Android Adds using HTML, CSS and Javascript by Starks and it seemed like it might be good?
http://www.amazon.com/Building-Android-Apps-HTML-JavaScript/dp/1449316417/ref=wl_it_dp_o_pC_nS_nC?ie=UTF8&coliid=IOUCW0NYIJPFL&colid=WVLO8POCVYWQ

If possible, in the process of learning Mobile App/Web dev and Social Networking APIs I'd like to solidify my web development skills using HTML, CSS, Javascript, and jQuery mostly. That's a big part about why I think I might like that book.

Thanks for any suggestions!

edit: A little background on my current skills. I'm most experienced with programming in C#, and have mild experience with C++, Java, VBScript, Perl, batch processing, CSS, and HTML.

android aps are mostly done in java, you will want to download eclipse, im very certain it is free software.
for html / css / javascript check out w3schools.com i use to go there for php. java on the other hand... that one is difficult, any troubles you run into will most likely lead you to vogella for tutorials or stack overflow. imo very difficult to find what you are looking for and trouble shooting is a bitch TT

Edit: I should say debugging is a bitch, the try / catches are annoying when you forget them, the null points, and ofc the cannot run on main thread > assync tasks.
Dance.943 || "I think he's just going to lose. There's only so many ways you can lose. And he's going to make some kind of units. And I'm going to attack him, and then all his stuff is going to die. That's about the best prediction that I can make" - NonY
tofucake
Profile Blog Joined October 2009
Hyrule19031 Posts
August 08 2012 12:17 GMT
#3080
w2schools is awful
don't use it
Liquipediaasante sana squash banana
Prev 1 152 153 154 155 156 1031 Next
Please log in or register to reply.
Live Events Refresh
Wardi Open
11:00
#43
WardiTV1322
OGKoka 522
Harstem427
IndyStarCraft 169
Rex167
CranKy Ducklings122
Liquipedia
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
OGKoka 522
Harstem 427
Hui .184
IndyStarCraft 169
Rex 167
StarCraft: Brood War
Bisu 2963
Flash 2112
Jaedong 1818
Hyuk 1166
firebathero 688
EffOrt 645
ZerO 538
Larva 508
actioN 436
Soulkey 387
[ Show more ]
Stork 378
Snow 308
Soma 275
GuemChi 168
Mind 132
sSak 113
Pusan 111
Light 98
PianO 80
hero 77
Sharp 74
JulyZerg 72
TY 55
Barracks 46
Sea.KH 44
Yoon 38
Aegong 35
sorry 32
Free 30
GoRush 26
soO 24
zelot 23
Movie 22
JYJ20
HiyA 20
yabsab 19
IntoTheRainbow 11
Terrorterran 10
Shine 8
ivOry 4
Dota 2
qojqva3148
Gorgc2576
XaKoH 621
XcaliburYe297
syndereN293
League of Legends
singsing2548
Counter-Strike
byalli263
markeloff128
Super Smash Bros
Mew2King169
Other Games
hiko1144
B2W.Neo1138
crisheroes383
Beastyqt345
Lowko310
ArmadaUGS128
Liquid`VortiX84
ZerO(Twitch)24
Organizations
Other Games
gamesdonequick37693
StarCraft: Brood War
UltimateBattle 889
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 13 non-featured ]
StarCraft 2
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
Dota 2
• C_a_k_e 2960
• WagamamaTV335
League of Legends
• Nemesis5594
Upcoming Events
RotterdaM Event
2h 25m
Replay Cast
10h 25m
Sparkling Tuna Cup
20h 25m
WardiTV European League
1d 2h
MaNa vs sebesdes
Mixu vs Fjant
ByuN vs HeRoMaRinE
ShoWTimE vs goblin
Gerald vs Babymarine
Krystianer vs YoungYakov
PiGosaur Monday
1d 10h
The PondCast
1d 20h
WardiTV European League
1d 22h
Jumy vs NightPhoenix
Percival vs Nicoract
ArT vs HiGhDrA
MaxPax vs Harstem
Scarlett vs Shameless
SKillous vs uThermal
uThermal 2v2 Circuit
2 days
Replay Cast
2 days
RSL Revival
2 days
ByuN vs SHIN
Clem vs Reynor
[ Show More ]
Replay Cast
3 days
RSL Revival
3 days
Classic vs Cure
FEL
4 days
RSL Revival
4 days
FEL
4 days
FEL
5 days
BSL20 Non-Korean Champi…
5 days
Bonyth vs QiaoGege
Dewalt vs Fengzi
Hawk vs Zhanhun
Sziky vs Mihu
Mihu vs QiaoGege
Zhanhun vs Sziky
Fengzi vs Hawk
Sparkling Tuna Cup
5 days
RSL Revival
5 days
FEL
6 days
BSL20 Non-Korean Champi…
6 days
Bonyth vs Dewalt
QiaoGege vs Dewalt
Hawk vs Bonyth
Sziky vs Fengzi
Mihu vs Zhanhun
QiaoGege vs Zhanhun
Fengzi vs Mihu
Liquipedia Results

Completed

BSL Season 20
HSC XXVII
Heroes 10 EU

Ongoing

JPL Season 2
BSL 2v2 Season 3
Acropolis #3
KCM Race Survival 2025 Season 2
CSL 17: 2025 SUMMER
Copa Latinoamericana 4
Jiahua Invitational
Championship of Russia 2025
RSL Revival: Season 1
Murky Cup #2
BLAST.tv Austin Major 2025
ESL Impact League Season 7
IEM Dallas 2025
PGL Astana 2025
Asian Champions League '25
BLAST Rivals Spring 2025
MESA Nomadic Masters
CCT Season 2 Global Finals
IEM Melbourne 2025

Upcoming

2025 ACS Season 2: Qualifier
CSLPRO Last Chance 2025
CSL Xiamen Invitational
2025 ACS Season 2
CSLPRO Chat StarLAN 3
K-Championship
uThermal 2v2 Main Event
SEL Season 2 Championship
FEL Cracov 2025
Esports World Cup 2025
StarSeries Fall 2025
FISSURE Playground #2
BLAST Open Fall 2025
BLAST Open Fall Qual
Esports World Cup 2025
BLAST Bounty Fall 2025
BLAST Bounty Fall Qual
IEM Cologne 2025
FISSURE Playground #1
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Disclosure: This page contains affiliate marketing links that support TLnet.

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2025 TLnet. All Rights Reserved.