#include <iostream>
using namespace std;
struct Packet {
int a;
char b[17];
int c;
};
// char* dest has form char dest[n], src has length <= n and is null-terminated
// After the function, dest should satisfy:
// - If strlen(src)==n, dest is not null terminated
// - If strlen(src) < n, dest[n-1] = dest[strlen(src)] = '\0'
static void strncpy_faster(char* dest, const char* src, size_t n) {
size_t i;
for (i = 0; i < n; i++) {
dest[i] = src[i];
if (src[i] == '\0')
break;
}
//while (i < n) {dest[i] = '\0'; i++;} // C standard strncpy do this
if (i < n)
dest[n - 1] = '\0';
}
string charArrayToString(const char* a, size_t n) {
size_t len = 0;
while (len < n && a[len]!='\0') len++;
return std::string(a, a+len);
}
int main()
{
string s = "12341234123412345";
Packet packet;
strncpy_faster(packet.b, s.c_str(), 17);
cout << charArrayToString(packet.b, sizeof(packet.b)) << "\n";
s = "12345";
strncpy_faster(packet.b, s.c_str(), 17);
cout << charArrayToString(packet.b, sizeof(packet.b));
return 0;
}
I'm dealing with struct that have fixed-size char arrays. Let's say I really, really want to keep struct size small (or I need to send them over network), so std::string is not used in my struct (it cost 32 bytes, while I have multiple small char arrays with size 4-20). I have 2 problems with strncpy:
strncpy2 char array with same length will emit warning about "potentially not having null-terminated character", which is intended, but I don't need that warning.strncpypad ALL leftover characters (fromdest[strlen(src) -> n-1]) with'\0'. This is a waste of processing in my program.
So, my strncpy_faster only assign up to 2 positions to '\0': the last element of the array, and the position of strlen(src). Since std::string() requires a null-terminated char array (NTCA), I use charArrayToString() to convert non-NTCA to string.
Is this version of strncpy safe? Are there any C/C++ functions that requires strncpy to fill all leftover bytes with '\0', or do they only need a null terminator? I don't know why the standard requires strncpy to zero-out remaining bytes.
Yes.
It's as safe as
strncpyis. So.... not safe.No function require it.
Notes from Linux man-pages
man strcpy:Consider using (and/or implementing)
strlcpy. Remember about first rule of optimization.