Reputation: 99
I have a 2D character array (I don't want to use array of std::string). How can I sort the strings (char*) in ascending order according to the length of the string using std::sort()?
I have tried the following. But it doesn't work.
char names[100][30];
bool comp(const char* a, const char* b){
return strlen(a)<strlen(b);
}
int main(){
...
//I want to sort the first n strings
sort(names,names+n,comp); //n<=100
...
}
I have found these errors:
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3128) : error C2075: '_Val' : array initialization needs curly braces
1> e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3150) : see reference to function template instantiation 'void std::_Insertion_sort1<_BidIt,bool(__cdecl *)(const char *,const char *),char[30]>(_BidIt,_BidIt,_Pr,_Ty (*))' being compiled
1> with
1> [
1> _BidIt=char (*)[30],
1> _Pr=bool (__cdecl *)(const char *,const char *),
1> _Ty=char [30]
1> ]
1> e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3270) : see reference to function template instantiation 'void std::_Insertion_sort<_RanIt,bool(__cdecl *)(const char *,const char *)>(_BidIt,_BidIt,_Pr)' being compiled
1> with
1> [
1> _RanIt=char (*)[30],
1> _BidIt=char (*)[30],
1> _Pr=bool (__cdecl *)(const char *,const char *)
1> ]
1> e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3279) : see reference to function template instantiation 'void std::_Sort<char(*)[30],int,bool(__cdecl *)(const char *,const char *)>(_RanIt,_RanIt,_Diff,_Pr)' being compiled
1> with
1> [
1> _RanIt=char (*)[30],
1> _Diff=int,
1> _Pr=bool (__cdecl *)(const char *,const char *)
1> ]
1> e:\projects visual studio2008\sample\sample\sorting.cpp(51) : see reference to function template instantiation 'void std::sort<char(*)[30],bool(__cdecl *)(const char *,const char *)>(_RanIt,_RanIt,_Pr)' being compiled
1> with
1> [
1> _RanIt=char (*)[30],
1> _Pr=bool (__cdecl *)(const char *,const char *)
1> ]
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3133) : error C2106: '=' : left operand must be l-value
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3140) : error C2106: '=' : left operand must be l-value
1>e:\program files (x86) in e\microsoft visual studio 9.0\vc\include\algorithm(3141) : error C2106: '=' : left operand must be l-value
1>Build log was saved at "file://e:\projects visual studio2008\sample\sample\Debug\BuildLog.htm"
1>sample - 4 error(s), 3 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Upvotes: 4
Views: 1778
Reputation: 28826
As already mentioned, arrays can't be assigned. Structures can be assigned, so this might be close to what you want. The array of structures might be padded for alignment. In the case of Visual Studio 2015, the array of structures was not padded, so the memory layout was the same as a 2d array.
update - changed to using references for compare parameters and switched to strnlen as suggested by Jarod42.
#include <algorithm>
#include <cstring>
using namespace std;
typedef struct
{
char name[30];
}name;
name names[4] = { { "12345678" },{ "123" },{ "12345" },{ "12" } };
bool comp(const name &a, const name &b)
{
return strnlen(a.name,30) < strnlen(b.name,30);
}
int main(){
sort(names, names+4, comp);
return 0;
}
Upvotes: 1
Reputation: 42909
std::sort
requires that its iterator type parameter must be:
The type of dereferenced iterator type must meet the requirements of:
Unfortunately, arrays are not swappable (i.e., you cannot assign one to the other). Consequently, you can't use std::sort
with arrays.
What you can do is use std::array<std::array<char, N>, M>
in the following manner:
template<std::size_t N, std::size_t M>
void custom_sort(std::array<std::array<char, M>, N> &arrs) {
std::sort(std::begin(arrs), std::end(arrs), [](auto const &a, auto const &b){ return strnlen(a.data(), M) < strnlen(b.data(), M); });
}
Impovements to code thanks to @Jarod42
Upvotes: 2
Reputation: 2480
You can try this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define M 10000
int main()
{
char names[M][15];
int n, i;
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%s", names[i]);
qsort(names, n, 15, (int (*)(const void *, const void *))strcmp);
for(i = 0; i < n; i++)
printf("%s\n", names[i]);
}
Upvotes: 0
Reputation: 114539
If your data is in
char names[100][30];
then you cannot sort "the pointers" because that data structure has no pointers at all... just 100*30 = 3000 characters one after another. Therefore to do the sorting you will need to actually move around the 100 rows will all their content.
std::sort
cannot be used directly because the data structure is an array of arrays, and arrays are in C++ second-class citizens (for example you cannot assign an array to another).
Upvotes: 5