6

I'm trying to convert a byte array to a string in C but I can't quite figure it out.

I have an example of what works for me in C++ but I need to convert it to C.

The C++ code is below:

#include <iostream>
#include <string>

typedef unsigned char BYTE;

int main(int argc, char *argv[])
{
  BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
  std::string s(reinterpret_cast<char*>(byteArray), sizeof(byteArray));
  std::cout << s << std::endl;

  return EXIT_SUCCESS;
}

Can anyone point me in the right direction?

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76
Dan
  • 2,304
  • 6
  • 42
  • 69
  • 4
    String *is* a byte array with terminating `'\0'` character. So yeah, you will need it's size to accommodate it too. – Eugene Sh. Aug 07 '19 at 17:02
  • Aren't you missing a null-terminator? – R.J. Dunnill Aug 07 '19 at 17:06
  • Why are you making a wonky typedef `BYTE`? This is like imposing the terminology of another language on C where it doesn't belong. In C we call these `unsigned char` or `uint8_t` if you prefer. – tadman Aug 07 '19 at 17:07
  • @R.J.Dunnill, C++ understands a non-null terminated buffer representing a string when you specify the size. – Alexis Wilke Aug 07 '19 at 17:08
  • @KonradRudolph It clearly isn't. – πάντα ῥεῖ Aug 07 '19 at 17:09
  • 3
    @LeeDanielCrocker Please actually **read** the question, not just the code. OP has C++ code; but they want to know how to do the same in C. – Konrad Rudolph Aug 07 '19 at 17:10
  • If the question is about C, then he should include C code. – Lee Daniel Crocker Aug 07 '19 at 17:11
  • 2
    @Konrad OK, sorry for the mess. I misread. – πάντα ῥεῖ Aug 07 '19 at 17:11
  • @KonradRudolph As per C++ and C tag policies, it is fine to use both tags for questions regarding "Compatibility or porting code between C and C++". This tag usage is the community consensus - it should have both tags. https://stackoverflow.com/tags/c%2b%2b/info – Lundin Aug 07 '19 at 17:26
  • 1
    I'll add both tags. Anyone disagreeing kindly take it up on meta [here](https://meta.stackoverflow.com/questions/374306/proposed-update-to-c-and-c-tag-usage-wikis) instead of vandalizing this question with edits. – Lundin Aug 07 '19 at 17:29
  • @LeeDanielCrocker: Requesting how to do something in C code does not require supplying C code as an example. Supplying C++ code to explain or illustrate some part of their question is fine, and it does not mean their question is about C++. – Eric Postpischil Aug 07 '19 at 17:39
  • Fair enough. Though we generally prefer "here's my code, what's wrong" questions to "how do I write..." questions. – Lee Daniel Crocker Aug 07 '19 at 18:27
  • @Lundin I’m not sure why you’re addressing me: I’m fine with both tags (although I don’t find it strictly necessary here). I objected to people removing the C tag. – Konrad Rudolph Aug 07 '19 at 19:09
  • @LeeDanielCrocker: We who? Stack Overflow is a site for general programming questions and answers. “What is wrong with this code?” is a subset of suitable questions. As far as “we” are concerned, it is at best a distraction from the main purpose and ought to be a minor subset. Most code with a bug does not exemplify general principles that would be useful for others to look up and learn from (and many of those that might just duplicate some previously explained issue, just in a different form is not conducive to searching). “How do I do X?” questions are more suitable for the main purpose. – Eric Postpischil Aug 07 '19 at 20:31

3 Answers3

18

Strings in C are byte arrays which are zero-terminated. So all you need to do is copy the array into a new buffer with sufficient space for a trailing zero byte:

#include <string.h>
#include <stdio.h>

typedef unsigned char BYTE;

int main() {
    BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
    char str[(sizeof byteArray) + 1];
    memcpy(str, byteArray, sizeof byteArray);
    str[sizeof byteArray] = 0; // Null termination.
    printf("%s\n", str);
}
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • @πάνταῥεῖ every changes my tags for the OP. The first line states the code IS in C++ but I want it in C. This works a treat and will accept when able – Dan Aug 07 '19 at 17:09
  • 7
    @tadman That’s an unfair accusation. The tags say C, the title says C, the body of the question says C. We (me included!) are just all jumping at the sight of C++ code and ignore mentions of C in tags and title like Pavlovian dogs (because we’ve been conditioned to expect mis-tagging between the two languages) but the question makes it clear why the C++ code is included, and how it’s relevant and legitimate. – Konrad Rudolph Aug 07 '19 at 17:15
  • @KonradRudolph There is C++ code present which is a red herring, and that's really not called for. I'm of the opinion that if there's C++ code in the question, it is, *by definition*, a C++ question and should be tagged as such. If you want C and C only, don't even go there, just use C and deal. – tadman Aug 07 '19 at 17:16
2

C strings are null terminated, so the size of the string will be the size of the array plus one, for the null terminator. Then you could use memcpy() to copy the string, like this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char BYTE;

int main(void)
{
  BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };

  // +1 for the NULL terminator
  char str[sizeof(byteArray) + 1];
  // Copy contents
  memcpy(str, byteArray, sizeof(byteArray));
  // Append NULL terminator
  str[sizeof(byteArray)] = '\0';

  printf("%s\n", str);    
  return EXIT_SUCCESS;
}

Output:

Hello

Run it online

gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

Here is a demonstrative program that shows how it can be done.

#include <stdio.h>
#include <string.h>

typedef unsigned char BYTE;

int main(void) 
{
    BYTE byteArray[5] = { 0x48, 0x65, 0x6C, 0x6C, 0x6F };
    char s[sizeof( byteArray ) + sizeof( ( char )'\0' )] = { '\0' };

    memcpy( s, byteArray, sizeof( byteArray ) );

    puts( s );

    return 0;
}

The program output is

Hello

Pay attention to that the character array is zero initialized. Otherwise after the call of memcpy you have to append the terminating zero "manually".

s[sizeof( s ) - 1] = '\0';

or

s[sizeof( byteArray )] = '\0';

The last variant should be used when the size of the character array much greater than the size of byteArray.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335