-3

How read and print the first character of this array? (Not the whole string, only first character).

char data[]= "£A";
printf("%c", data[0]);  

Here, I have tried printf("%c", data[2]);

Output: A

But printf("%c", data[0]); or printf("%c", data[1]); does not print anything (blank output).

Al Sajid
  • 1
  • 1
  • Non-general way: `printf("%c%c", data[0], data[1]);` – MikeCAT Jan 03 '21 at 01:22
  • 3
    Most likely, your source file is saved with UTF-8 encoding, where `£` requires two bytes to encode. So `data` is actually four bytes large: `data[0]` and `data[1]` together encode `£`, `data[2]` encodes `A`, and `data[3]` is `\0`, the terminating NUL character. Generally, not every Unicode character can be printed with `%c` specifier; only the first 256 can. – Igor Tandetnik Jan 03 '21 at 01:23
  • To add to what @IgorTandetnik said. Here's an example of the size of your _one_ letter could have: https://godbolt.org/z/7dxv9a – Ted Lyngmo Jan 03 '21 at 01:45
  • @TedLyngmo The size printed is the size of the character plus the size of terminating null-character. – MikeCAT Jan 03 '21 at 01:47
  • @MikeCAT I guess you looked at my example before I adjusted just that :-) – Ted Lyngmo Jan 03 '21 at 01:48
  • 1
    @TedLyngmo Subtracting `std::size("")` may be better. – MikeCAT Jan 03 '21 at 01:49
  • @MikeCAT I'm a bit tired right now, but that should be `1` on all standard conforming platforms. Oh, ok, to not use magic numbers? Correct - I agree. – Ted Lyngmo Jan 03 '21 at 01:50

1 Answers1

0

Code

#include <cstring>
#include <string>
#include <stdexcept>
#include <iostream>

typedef std::string String;

size_t GetTotalUTF8Chars(const String &data)
{
    size_t ret = 0;
    for (char value : data)
    {
        if ((value & 0xc0) != 0x80)
        {
            ++ret;
        }
    }
    return ret;
}

String GetUTF8Char(String data, size_t pos)
{
    if(pos >= GetTotalUTF8Chars(data))
    {
        throw std::length_error(u8"Invalid UTF8 character position");
    }
    String result;
    String::const_iterator it = data.begin();
    String::const_iterator beginIterator(it);
    size_t utf8pos = 0;
    if ((data[0] & 0xc0) != 0x80)
    {
        it++;
    }
    while (it != data.end())
    {
        char value = *it;
        if ((value & 0xc0) != 0x80)
        {
            if (pos == utf8pos)
            {
                return String(beginIterator, it);
            }
            beginIterator = it;
            utf8pos += 1;
        }
        it++;
    }
    return String(beginIterator, it);   
}

int main()
{
    char cstr[] = u8"HelloWorld£A";
    String str = String(cstr);

    std::cout<<"█ With C String"<<std::endl;
    for (size_t i = 0; i < GetTotalUTF8Chars(cstr); i++)
    {
        std::cout << i <<".- " << GetUTF8Char(cstr, i) << std::endl;
    }

    std::cout<<"█ With C++ String"<<std::endl;
    for (size_t i = 0; i < GetTotalUTF8Chars(str); i++)
    {
        std::cout << i <<".- " << GetUTF8Char(str, i) << std::endl;
    }

  str = u8"£A";
    printf(u8"Position0 = %s / Position1 = %s\n", GetUTF8Char(str,0).c_str(), GetUTF8Char(str, 1).c_str());

  try{
    std::cout << GetUTF8Char(str, 15) << std::endl; 
  }
  catch(std::exception &ex)
  {
    std::cout<< "Exception message:" <<ex.what()<<std::endl;
  }

    return EXIT_SUCCESS;
}

Output

█ With C String
0.- H
1.- e
2.- l
3.- l
4.- o
5.- 
6.- 
7.- W
8.- o
9.- r
10.- l
11.- d
12.- 
13.- £
14.- A
█ With C++ String
0.- H
1.- e
2.- l
3.- l
4.- o
5.- 
6.- 
7.- W
8.- o
9.- r
10.- l
11.- d
12.- 
13.- £
14.- A
Position0 = £ / Position1 = A
Exception message:Invalid UTF8 character position

Your example

str = u8"£A";
printf(u8"%s\n", GetUTF8Char(str,0).c_str());
printf(u8"%s\n", GetUTF8Char(str,1).c_str());
printf(u8"%s %s\n", GetUTF8Char(str,0).c_str(), GetUTF8Char(str, 1).c_str());

Output

£
A
£ A

You can try this code on Get UTF8 Char(https://repl.it/@JomaCorpFX/Get-UTF8-char#main.cpp)

Joma
  • 3,520
  • 1
  • 29
  • 32