swapping parts of an array around

What would a good way to swap artistfirstname with artistlastname in array[9999][80] = {{ "artistfirstname artistlastname 'song name'",}, ..........} the array will be in this format!

For example
{"Brian Hollan 'Where Did Our Love Go'",}

becomes {"Hollan Brian 'Where Did Our Love GO'"}
Unless they are both separate variables or the names are of a fixed length, any way you do the swapping will be very inefficient. If the first/last name were fixed length, you can just access the array index right after the copy from arrray[x][0] to array[x][fixed_name_length] and array[x][fixed_name_length] to end; and put these into 2 variables then just recreate the information at that index the way you want
Well, it might be easier to make that into an array of strings, instead of an array of characters. Have the first part be first name, second part be second name, and third be the song title. That way, you just switch the first array value with the second. Otherwise, you're going to need to go through the array and find the first space. Take everything preceding the first space, and switch that with what is between the first and second spaces.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <algorithm>
#include <functionnal>
#include <cstring>
#include <cctype>

int main()
{
	char s[1][80] = {"Hollan Brian 'Where Did Our Love GO'"};

	std::function<bool ( char )> IsSpace( [] ( char c ) { return ( std::isspace( c ) != 0 ); } );
	size_t n = std::strlen( s[0] );

	std::cout << s[0] << std::endl;

	char *word_1st_end;
		
	if ( 
		( word_1st_end = std::find_if( s[0], s[0] + n, std::not1( IsSpace ) ) ) != s[0] + n
		&& ( word_1st_end = std::find_if( word_1st_end, s[0] + n, IsSpace ) ) != s[0] + n )
	{
		char *word_2nd_start = std::find_if( word_1st_end, s[0] + n, std::not1( IsSpace ) );
		char *word_2nd_end = std::find_if( word_2nd_start, s[0] + n, IsSpace );

		char t[80];

		char *pos = std::copy( word_2nd_start, word_2nd_end, t );
		pos = std::copy( word_1st_end, word_2nd_start, pos );
		pos = std::copy( s[0], word_1st_end, pos );
		strcpy( pos, word_2nd_end );
			
		std::cout << t << std::endl;
	}
}
Last edited on
If you found the boundaries of the words to be swapped in the array, you can just call std::swap_ranges() on them.

It's finding those boundaries that may not be trivial: what if there's a middle name? What if there's a two-word last name (van Damme) or even three-word last name (van der Waals). What if there is no last name (Madonna)?
Last edited on
@Cubbi


Maybe I am mistaken but std:;swap_ranges may not be applied because it requires equal ranges of the swapped sequences.
I think that it is supposed in the original post that each record consists at most of three words and words can be absent starting from the right to the left.
Last edited on
good point about swap_ranges, scratch that.

What I'm trying to lead to is that if the program operates in terms of "first name", "last name", then it should store those objects: first name separately from last name. Then they can be swapped, abbreviated, capitalized, or otherwise formatted for output.
std::rotate() will work if we don't mind having an extra space at the end. (And assuming that name itself doesn't contain a single quote.)

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <algorithm>

int main()
{
    char str[] = "Brian Hollan 'Where Did Our Love Go' " ;
    const std::size_t N = sizeof(str) - 1 ;
    std::cout << str << '\n' ;

    std::rotate( str, std::find( str, str+N, '\'' ), str+N ) ;
    std::cout << str << '\n' ;
}


@Cubbi
What I'm trying to lead to is that if the program operates in terms of "first name", "last name", then it should store those objects: first name separately from last name. Then they can be swapped, abbreviated, capitalized, or otherwise formatted for output.



I think that in this case a simple approach would be to use std::istringstream based on each recod. Then std::getline( istream, temp_string, '\'' ) should be applied. And at last to use another std::istringstream based on temp_string that to split the string into words for further analyzing them and swapping if it is required.
Topic archived. No new replies allowed.