Las funciones GetPrivateProfileXXX de Windows (utilizadas para trabajar con archivos INI) tienen algunas reglas extrañas sobre cómo lidiar con las longitudes de búfer.GetPrivateProfileString - Longitud de búfer
estados de documentación de GetPrivateProfileString:
Si [..] el búfer de destino suministrada es demasiado pequeño para contener la cadena solicitada, la cadena se trunca y seguido por un carácter nulo, y el valor de retorno es igual a nTamaño menos uno.
leí esto y me di cuenta que este comportamiento hace que sea imposible diferenciar entre dos escenarios en-código:
- Cuando la longitud de la cadena de valor es exactamente igual a nTamaño - 1.
- Cuando el valor nSize (es decir, el buffer) es demasiado pequeño.
pensé que había experimentar:
tengo esto en un archivo INI:
[Bar]
foo=123456
Y llamé GetPrivateProfileString con estos argumentos como una prueba:
// 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 programa que invoque este código no tendría forma de saber con certeza si el valor real de la clave es de hecho 5 caracteres de longitud, o incluso 6, como en los últimos dos cas El resultado es igual a nSize - 1.
La única solución es comprobar siempre result == nSize - 1 y recuperar la función con un buffer más grande, pero esto sería innecesario en los casos donde el buffer es exactamente el Talla correcta.
¿No hay una forma mejor?
¿Se supone que es un código C o C++? –