Le funzioni GetPrivateProfileXXX di Windows (utilizzate per lavorare con i file INI) hanno alcune strane regole su come gestire le lunghezze del buffer.GetPrivateProfileString - Buffer length
documentazione afferma di GetPrivateProfileString:
Se [..] il buffer di destinazione fornito è troppo piccolo per contenere la stringa di richiesta, la stringa viene troncata e seguita da un carattere null, e il valore di ritorno è pari a nSize meno uno.
I leggere questo e ho capito che questo comportamento rende impossibile distinguere tra due scenari in-codice:
- Quando la lunghezza della stringa valore è esattamente uguale a nSize - 1.
- Quando il valore nSize (cioè il buffer) è troppo piccolo.
ho pensato di sperimentare:
Ho questo in un file INI:
[Bar]
foo=123456
e ho chiamato GetPrivateProfileString con questi argomenti come un 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 }
Un programma che chiama questo codice non avrebbe modo di sapere con certezza se il valore della chiave effettiva è effettivamente di 5 caratteri di lunghezza, o anche di 6, come negli ultimi due casi es risultato è uguale a nSize - 1.
L'unica soluzione è controllare ogni risultato == nSize - 1 e richiamare la funzione con un buffer più grande, ma questo non sarebbe necessario nei casi in cui il buffer è esattamente il misura giusta.
Non c'è un modo migliore?
Si suppone che sia un codice C o C++? –