Pergunta

Eu só tenho Delphi 2009 e, anteriormente, ter lido alguns artigos sobre modificações que possam ser necessárias por causa da mudança para cadeias de caracteres Unicode. Principalmente, é mencionado que sizeof (char) não é garantido para ser 1 mais. Mas por que isso seria interessante sobre a manipulação de cadeia?

Por exemplo, se eu usar um AnsiString: = 'Test' e fazer o mesmo com uma String (que é unicode agora), então eu recebo Length () = 4, que é correto para ambos os casos. Sem ter testado isso, eu tenho certeza que todas as outras funções de manipulação de strings se comportam da mesma maneira e decidir internamente se o argumento é uma string unicode ou qualquer outra coisa.

Por que o tamanho real de um char ser de interesse para mim se eu fizer manipulações de string? (É claro que se eu usar cordas como cordas e não para armazenar quaisquer outros dados)

Obrigado por qualquer ajuda! Holger

Foi útil?

Solução

Com Unicode SizeOf (SomeChar) <> Comprimento (SomeChar) . Essencialmente, o comprimento de um string é menor, então a soma do tamanho de sua caractere s. Contanto que você não assuma SizeOf (Char) = 1 ou SizeOf (SomeString [x]) = 1 (já que ambos são false agora) ou tentar intercâmbio byte s com caractere é, então você não deve ter nenhum problema. Qualquer lugar que você está fazendo algo recheio criativo Byte S em Char s ou string s, então você vai precisar usar AnsiString .

(SizeOf (SomeString) ainda é 4 não importa o comprimento, uma vez que é essencialmente um ponteiro com um pouco de magia do compilador.)

Outras dicas

As pessoas muitas vezes converter implicitamente a partir de personagens de bytes no código Delphi antigo, sem realmente pensar sobre isso. Por exemplo, quando se escreve para um riacho. Quando você escreve uma string para um fluxo, você tem que especificar o número de bytes que você escreve, mas muitas vezes as pessoas passam a contagem de caracteres em vez disso. Consulte este post de Chris Bensen para outro exemplo.

Outra forma como as pessoas muitas vezes fazem essa conversão implícita e código antigo é usando um "string" para armazenar dados binários. Neste caso, eles realmente querem bytes, mas o tipo de dados espera caracteres. D2009 tem um melhor tipo para este .

Eu não tentei Delphi 2009, mas estão usando FPC que também é a mudança para Unicode lentamente. Estou 95% certo de que tudo abaixo também vale para o Delphi 2009

Em FPC (quando suporte unicode) será assim que funciona como 'tamanho' levar a página de códigos em consideração. Assim, ele irá retornar o comprimento da corda como um 'humano' iria vê-lo. Se houver - por exemplo - dois caracteres chineses, que ambos tomam dois bytes de memória em unicode, comprimento retornará 2, uma vez que existem dois caracteres na cadeia. Mas a corda vai levar 4 bytes de memória. (+ A memória para a contagem de referência ea principal # 0, mas isso de lado)

O que você não pode fazer mais é esta:

var p : pchar;
begin
  p := s[1];
  for i := 0 to length(string)-1 do
    begin
    write(p);
    inc(p);
    end;      
end;

Como esse código vai - no exemplo dois chinese-caráter - escrevem os errados dois caracteres. Ou seja, os dois bytes que fazem parte do primeiro caractere 'real'.

Em suma: Comprimento () não retorna a quantidade de bytes alocados para a cadeia mais, mas a quantidade de caracteres. (Antes da mudança para Unicode, esses dois valores eram iguais um ao outro)

O tamanho real de um personagem não deve importar, a menos que você está fazendo a manipulação no nível de byte.

(É claro que se eu usar cordas como cordas e não para armazenar quaisquer outros dados)

Esse é o ponto-chave, você não usar cordas para outros fins, mas algumas pessoas fazem. Eles usam cordas como matrizes, para que eles (e que inclusive eu) precisa verificar todos esses usos para garantir que nada está quebrado ...

Não vamos esquecer que há momentos em que essa conversão não é realmente desejado. Diga para armazenar um GUID em um registro por exemplo. O guid só pode conter caracteres hexadecimais mais os - e suportes ... tornando-os levar até o dobro do espaço pode fazer um grande impacto sobre o código existente. Claro que a solução mais simples é mudá-los para AnsiString, e lidar com os avisos do compilador se você fizer qualquer manipulação de cadeia neles.

Pode ser um problema se você fizer chamadas API do Windows. Ou se você tiver o código legado que faz inc ou dezembro de str [0] para alterar seu comprimento.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top