How to transform pointer array to smaller pointer array?

Hello im trying to run this code but i get error:
cannot convert 'char*' to 'char (*)[2]' in initialization|
in line 16

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

int main ()
{
    // create simple char array
    char arr[] = "123 456 789";

    // create char pointer array of sizeof(arr) and assign address of arr.
    char (* pchar)[sizeof(arr)] = (&(arr));

    // create void pointer and assign arr.
    void * pvoid = (&arr);

    // create another char pointer array of 3 bites and assign pvoid transformed to char.
    char (* pchar2)[2] = ((char *)pvoid);

    // print the value pointed by pchar2.
    cout<<(*pchar2)<<endl;

    return 0;
}


Program output should be 123
Thank you for reading.
Last edited on
Maybe you should test it with a vector, its much easier than this.

http://www.cplusplus.com/reference/vector/vector/


In Line 13 you should do it like this:
1
2
3
// create another char pointer array of 3 bites and assign pvoid transformed to char.
char * pchar2[3];
pchar2[0] = (char*) pvoid;


But it wont make the Array smaller!
I'm not trying to make array smaller, but to point to first 3 chars of array instead of all.
1
2
3
4
5
6
7
8
9
#include <iostream>

int main() {
    char arr[] = "123 456 789";
    char(* pchar )[sizeof(arr)] = &arr;
    std::cout << *pchar << '\n';
    char (* pchar2 )[3] = (char(*)[3])pchar;
    std::cout << *pchar2 << '\n';
}


But it won't just print the first 3 characters just because it's type says it's a 3-char array. Just like printing any c-style array, cout will keep printing chars until it hits the '\0' char.
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
#include <iostream>

int main()
{
    // create simple char array
    char arr[] = "123 456 789";

    // create char pointer array of sizeof(arr) and assign address of arr.
    char (*pchar)[sizeof(arr)] = &arr ;

    // create void pointer and assign arr.
    void* pvoid = &arr ;

    // print the value of pvoid.
    std:: cout << pvoid << '\n' ;

    // create another pointer to array of 3 bytes (char) and nitialise with a cast
    char (*pchar2)[3] = static_cast< char(*)[3] >(pvoid);

    // print the value of pchar2 (must be same as pvoid).
    std:: cout << pchar2 << '\n' ;

    // print the array *pchar2 as a c-style string (array to pointer decay)
    // (print sequence of chars till a null char is encountered. must be 123 456 789)
    std:: cout << *pchar2 << '\n' ;

    // print the contents of the array *pchar2. (print the three chars, must be 122)
    for( char c : *pchar2 ) std::cout << c ;
}

http://coliru.stacked-crooked.com/a/ce5eba26713598f8
Thank you for all your replies.
Sorry people i made a mistake. My code lines 12 and 13 was suppose to be like this:
1
2
    // create void pointer and assign address of pchar.
    void * pvoid = &pchar;


Thank you tbp the line 7 of your code looks awesome this is what i was looking for.
And thank you to JLBorges for his code line 18.

Now my code compiles, runs and looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

int main ()
{
    // create simple char array
    char arr[] = "123 456 789";

    // create char pointer array of sizeof(arr) and assign address of arr.
    char (* pchar)[sizeof(arr)] = (&(arr));

    // create void pointer and assign address of pchar.
    void * pvoid = &pchar;

    // create another char pointer array of 3 bites and assign pvoid transformed to char*[3].
    char (* pchar2)[3] = ((char(*)[3])pvoid);

    // print the value pointed by pchar2.
    cout<<(*pchar2)<<endl;

    return 0;
}


No matter if i use JLBorges code: static_cast< char(*)[3] >(pvoid);
or tbp code: (char(*)[3])pchar;

I still have problem instead of output 123 i get:
 
∞■m


Any ideas?
First do you know the difference between an array of char and a C-string?

// create simple char array
char arr[] = "123 456 789";

char sub[5] = {0};
memcpy(sub,arr,3);
cout << sub;
memcpy(sub,&arr[4], 3)
cout << sub;
//if you mess up the pre-assigned zeros in sub, the end of strings will get mangled doing this sort of thing. I did not mangle them, but you need to understand this.

you can't really cut 123 and 456 out of arr suitable for a cout statement without copying it to another string. You can loop and print 1 char at a time, if you want, but not with a string-level cout you have to use a char level cout loop.

there are other ways to get a substring out of it, but all will involve a copy to allocate a zero end of string marker.

char (* pchar)[sizeof(arr)] = (&(arr)); //this looks totally wrong to me.
either do this
char* pchar = arr; //a reference pointer to arr.
or do this
char (* pchar)= new char[strlen(arr)+1] ; //a new memory location of the same size as arr
Last edited on
I was thinking they are the same thing.
A array of char.
no. a c-string has a zero terminal character, an array of char may not.
an array of char might be integers, raw bytes, or a bytes that happen to be 'text'. An array of char might be a c-string. but a c-string specifically has the zero termination.
I still have problem instead of output 123 i get:
The problem is line 13. It is a pointer to the pointer. So remove the & and it will work, but does not magically remove any characters.

I would strongly discourage people creating such a casting feast though.

Thank you for all your answers. I can just use:
arr[3]=0;
Before i use std::cout<<(*pchar);

Here is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

int main ()
{
    // create simple char array
    char arr[] = "123 456 789";

    // create char pointer array of sizeof(arr) and assign address of arr.
    char (* pchar)[sizeof(arr)] = (&(arr));

    // create void pointer and assign address of pchar.
    void * pvoid = pchar;

    // create another char pointer array of 3 bites and assign pvoid transformed to char.
    char (* pchar2)[2] = ((char(*)[2])pvoid);

    // add null just after 123.
    arr[3]=0;
    // print the value pointed by pchar2.
    std::cout<<(*pchar2);

    return 0;
}
Note, of course that your solution will only work with C-strings. It will not work with arrays of other types.

You have not "shortened the array". You've just put a null character in the 4th element, so that when the char array is interpreted as a C-string, it will be interpreted as having a length of 3 characters.

Really, you've changed nothing but the way the array is output to the terminal. The actual array is still as long as it ever was.

That may, of course, be all you wanted all along.
I'm impressed by the code obfuscation achieved in this thread. Great work. :P
heh. Back when I would set zero and unset it to get a quick substring to print, it works fine.
just set arr[3] back to ' ' if you want to restore your original data after the print. Nothing wrong with this, but if you want to do a hands-on c-string program, be prepared to deal with your bugs and the inherit problems of direct manipulation / low level code. Its really easy to mess up, and really hard to fix it, once the programs get bigger. String type is the way to go in c++, and if doing C code, you want to be very precise and careful with it.
Last edited on
Tkank you for all your help. I will mark this as solved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <string_view>

int main()
{
     // create simple char array
    const char arr[] = "012345678901234";
    std::cout << arr << '\n' ;

    // create a view of the first eight characters of the array
    std::string_view view( arr, 8 ) ;
    std::cout << view << '\n' ; // 01234567

    // remove the first three characters from the view
    view.remove_prefix(3) ;
    std::cout << view << '\n' ; // 34567

    while( !view.empty() )
    {
        view.remove_suffix(1) ; // remove the last character from the view
        std::cout << view << '\n' ; // and print it
    }
}

http://coliru.stacked-crooked.com/a/b2fbb5c8ae186ab9
Topic archived. No new replies allowed.