funkcje GetPrivateProfileXXX Windows' (używane do pracy z plikami INI) mają jakieś dziwne zasady dotyczące postępowania z długości bufora.GetPrivateProfileString - długość bufora
GetPrivateProfileString za stany dokumentacja:
Jeśli [..] dostarczony bufor docelowy jest zbyt mały, aby pomieścić żądany ciąg, ciąg jest obcinany, a następnie znak null, a zwracana jest wartość równa n Rozmiar minus jeden.
Czytam to i zdałem sobie sprawę, że takie zachowanie sprawia, że niemożliwe do rozróżnienia między dwoma scenariuszami w Kod producenta:
- Kiedy długość wartość ciągu jest dokładnie równa nRozmiar - 1.
- Kiedy wartość nSize (tj. bufor) jest zbyt mała.
pomyślałem, że eksperyment:
mam to w pliku INI:
[Bar]
foo=123456
I zadzwoniłem GetPrivateProfileString z tych argumentów jak test:
// Test 1. The buffer is big enough for the string (16 character buffer).
BYTE* buffer1 = (BYTE*)calloc(16, 2); // using 2-byte characters ("Unicode")
DWORD result1 = GetPrivateProfileString(L"Bar", L"foo", NULL, buffer, 16, fileName);
// result1 is 6
// buffer1 is { 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 0, 0, 0, 0, ... , 0, 0 }
// Test 2. The buffer is exactly sufficient to hold the value and the trailing null (7 characters).
BYTE* buffer2 = (BYTE*)calloc(7, 2);
DWORD result2 = GetPrivateProfileString(L"Bar", L"foo", NULL, buffer, 7, fileName);
// result2 is 6. This is equal to 7-1.
// buffer2 is { 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 0, 0 }
// Test 3. The buffer is insufficient to hold the value and the trailing null (6 characters).
BYTE* buffer3 = (BYTE*)calloc(6, 2);
DWORD result3 = GetPrivateProfileString(L"Bar", L"foo", NULL, buffer, 6, fileName);
// result3 is 5. This is equal to 6-1.
// buffer3 is { 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 0, 0 }
Program wywołujący ten kod nie miałby żadnej pewności, czy rzeczywista wartość klucza ma rzeczywiście 5 znaków długości, czy nawet 6, jak w dwóch ostatnich cas es wynik jest równy nSize - 1.
Jedynym rozwiązaniem jest sprawdzenie, kiedy wynik == nRozmiar - 1 i przywołanie funkcji z większym buforem, ale byłoby to niepotrzebne w przypadkach, w których bufor ma dokładnie taką wartość dobry rozmiar.
Nie istnieje lepszy sposób?
Czy to ma być kod C lub C++? –