Pergunta

a pista está no título, mas basicamente eu tenha herdado algum código que tem mais de 800 casos de strcpy. Eu quero escrever uma nova função e, em seguida, para substituir strcpy com strcpy_mine.

Então, eu estou tentando descobrir o que lista de parâmetros strcpy_mine terá.

Eu tentei:

void strcpy_mine( char* pTarget, const char* const pCopyMe )
{
  const unsigned int lenAlwaysFour = sizeof(pCopyMe ); //:(
  strncpy( pTarget, pCopyMe, lenAlwaysFour );

  //add extra terminator in case of overrun
  pTarget[lenAlwaysFour] = 0;
}

mas o sizeof é sempre 4 pCopyMe é um ponteiro

o que eu não quero fazer é substituir

strcpy (buf, pCopyMe);

com

strncpy (buf, pCopyMe, sizeof(pCopyMe)); buf[sizeof(pCopyMe)] = 0;

todas as idéias? (Strcpy_l não está disponível)

aplausos

Foi útil?

Solução

Dependendo de como as chamadas de locais parecem, muitas vezes maioria dos casos pode ser tratado por um modelo simples:

#include <string.h>

template <int bufferSize>
void strcpy_mine( char (&pTarget)[bufferSize], const char* const pCopyMe )
{
  strncpy( pTarget, pCopyMe, bufferSize-1 );

  //add extra terminator in case of overrun
  pTarget[bufferSize-1] = 0;
}

int main()
{
  char buf[128];
  strcpy_mine(buf,"Testing");
  return 0;
}

Se você estiver usando o Microsoft Visual Studio 2005 ou mais recente, consulte seguros Template sobrecargas para a implementação da Microsoft.

Outras dicas

sizeof () retorna o tamanho do tipo de -. Neste caso const char* const que será de 4 em máquinas de 32 bits

Eu acho que você pensa que você quer strlen(). Mas essa não é a maneira correta de usar as funções strncpy. Você precisa do tamanho do saída tampão para strncpy.

Para corrigir isso, você precisa examinar o código em cada local chamada, e trabalhar para fora o tamanho do buffer de saída, e passar isso como um argumento para strcpy_mine. Se a chamada local para strcpy (ou strcpy_mine) não sabe o tamanho do buffer de saída, você precisa procurar para trás no código para o local que aloca o buffer, e passar o tamanho todo o caminho para o site strcpy .

Basicamente, você não pode escrever uma gota no substituto para o strcpy que leva os mesmos argumentos e esperança para evitar os problemas que produziram strncpy em primeiro lugar (e melhores substituições além disso). Você pode criar uma função que recebe os mesmos argumentos que strncpy, mas garante que o resultado é terminada em nulo - olhar para a implementação de strlcpy do OpenBSD () função . Mas o primeiro passo tem que ser para alterar os locais chamam de repassar conhecimento do tamanho do buffer de saída.

Um pouco periférica talvez, mas desde que ninguém mencionou isso e é ostentado no título:. Você não pode (legalmente) escrever uma função global chamado strcpy_mine()

O "namespace" de funções cujos nomes começam com str é reservado para a biblioteca padrão. Veja, por exemplo, a resposta aceita a esta pergunta .

Você pode usar a mesma lista de parâmetros como strncpy para o seu strcpy_mine, mas escrevê-lo para que ele termina sempre nulo o resultado. não deve ser muito difícil de fazer.

Um desafio, no entanto, é que alguns dos seu código existente que as chamadas strcpy () não pode saber o tamanho do buffer, qualquer um.

Também você pode usar macroses para evitar várias edições. Ou automatizar a edição através de algum script.

Você definitivamente precisa passar no tamanho do buffer de destino como um parâmetro, como outras pessoas têm dito acima.

Esta é uma espécie de off-topic, mas eu só quero salientar que, após usar strncpy(), você precisa definir como nulo o último caractere do buffer, que tem índice de 1 menos do que o comprimento (não o comprimento do buffer):

strncpy (buf, pCopyMe, buflen); buf[buflen - 1] = '\0';

Ou, alternativamente, você pode usar strncat() em uma cadeia vazia, passando um comprimento que é 1 a menos, e vai garantir a nulo encerrar sua string:

buf[0] = '\0'; strncat (buf, pCopyMe, buflen - 1);

Douglas Leeder tem direito. Há um limite para a utilidade de substituir strcpy a menos que você está disposto a fazer o trabalho pesado de passar em um bom, tamanho do buffer sã em cada instância. Isso é um monte de trabalho!

A boa notícia é, vale a pena! Voltar alguns anos atrás, eu entrei em vários projetos C ++ que estavam atrasados, carrinho, e não confiável. Ao declarar strcpy e strlen proibido, e tendo 2-3 dias fora do projeto para substituí-los com strncpy custom / strnlen, em todos esses projetos que de repente poderia correr durante dias em vez de horas. Também vi um monte de cordas truncado sair por monitores de tela e arquivos de log. Que nos deu as pistas necessárias para rastrear os problemas de truncamento, anteriormente bater questões.

Se você não quiser fazer isso, você pode obter um benefício muito menor, simplesmente verificando ambos os parâmetros de ponteiro para NULL, e limitar o tamanho máximo de uma cópia corda e registrando todas as vezes que o limite é atingido. não faça um strlen de qualquer parâmetro, como strlen terá todo o prazer bater em você se a cadeia não é propriamente um terminador nulo.

Hoje em dia, novos projetos usar bons objetos string, mas há um monte de código legado lá fora, que não funciona.

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