strcpy… strncpy 및 null이 종료되는 strcpy_mine으로 대체하고 싶습니다.

StackOverflow https://stackoverflow.com/questions/951119

  •  11-09-2019
  •  | 
  •  

문제

단서는 제목에 있지만 기본적으로 800개 이상의 strcpy 인스턴스가 있는 일부 코드를 상속했습니다.새 함수를 작성한 다음 strcpy를 strcpy_mine으로 바꾸고 싶습니다.

그래서 나는 strcpy_mine이 어떤 매개변수 목록을 갖게 될지 알아내려고 노력 중입니다.

나는 시도했다:

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;
}

하지만 크기는 항상 4입니다. pCopyMe는 포인터입니다.

내가하고 싶지 않은 것은 교체입니다

strcpy (buf, pCopyMe);

~와 함께

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

어떤 아이디어가 있나요?(strcpy_l을 사용할 수 없습니다)

건배

도움이 되었습니까?

해결책

호출 사이트의 모양에 따라 대부분의 경우는 간단한 템플릿으로 처리할 수 있습니다.

#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;
}

Microsoft Visual Studio 2005 이상을 사용하는 경우 다음을 참조하세요. 보안 템플릿 오버로드 Microsoft 구현을 위해.

다른 팁

sizeof () 유형의 크기를 반환합니다 -이 경우 const char* const 32 비트 기계에서 4 개가됩니다.

나는 당신이 원한다고 생각합니다 strlen(). 그러나 그것은 strncpy 함수를 사용하는 올바른 방법이 아닙니다. 당신은 크기가 필요합니다 산출 strncpy에 대한 버퍼.

이 문제를 해결하려면 각 통화 사이트에서 코드를 검사하고 출력 버퍼의 크기를 작성하고 인수로 전달해야합니다. strcpy_mine. strcpy (또는 strcpy_mine)의 콜 사이트가 출력 버퍼의 크기를 모르는 경우 버퍼를 할당하는 위치를 코드에서 뒤로 검색하고 크기를 strcpy 사이트로 전달해야합니다. .

기본적으로 당신은 동일한 논증을 취하고 처음에 strncpy를 생성 한 문제를 피하기를 희망하는 strcpy를 대체 할 수 없습니다 (그리고 그 이상의 대체품). strncpy와 동일한 인수를 취하는 함수를 만들 수 있지만 결과가 null -terminated를 보장 할 수 있습니다. OpenBsd의 strlcpy () 기능. 그러나 첫 번째 단계는 출력 버퍼 크기에 대한 지식을 전달하기 위해 호출 사이트를 변경하는 것입니다.

약간 주변 장치는 아마도, 아무도 언급하지 않았고 제목에 과시되지 않았기 때문에 : 당신은 (법적으로) strcpy_mine().

이름이 시작하는 함수의 "네임 스페이스" str 표준 라이브러리 용으로 예약되어 있습니다. 예를 들어, 이 질문에 대한 대답.

strcpy_mine에 대해 strncpy와 동일한 매개 변수 목록을 사용할 수 있지만 항상 null이 결과를 종료하도록 작성하십시오. 하기가 그리 어렵지 않아야합니다.

그러나 한 가지 과제는 strcpy ()를 호출하는 기존 코드 중 일부가 버퍼의 크기를 알지 못할 수도 있다는 것입니다.

또한 여러 편집을 피하기 위해 매크로를 사용할 수 있습니다. 또는 일부 스크립트를 통해 편집을 자동화합니다.

위에서 언급 한 것처럼 대상 버퍼의 크기를 매개 변수로 전달해야합니다.

이것은 일종의 주제이지만, 나는 당신이 사용한 후에 그것을 지적하고 싶습니다. strncpy(), 당신은 인덱스가있는 버퍼의 마지막 문자를 null로 설정해야합니다. 1 적은 길이보다 (버퍼의 길이가 아님) :

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

또는 또는 사용할 수 있습니다 strncat() 빈 문자열에서 길이가 1 인 길이를 전달하면 문자열을 무효화 할 수 있습니다.

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

Douglas Leeder가 맞습니다. 모든 인스턴스에서 양호하고 제정신 버퍼 길이를 통과시키는 그 런트 작업을 기꺼이하지 않는 한 strcpy를 교체하는 데 유용한 제한이 있습니다. 그것은 많은 일입니다!

좋은 소식은 그만한 가치가 있다는 것입니다! 몇 년 전, 나는 늦고 버그가 많고 신뢰할 수없는 여러 C ++ 프로젝트를 시작했습니다. strcpy와 strlen을 선언하고 프로젝트에서 2-3 일을 내려 Custom Strncpy/strnlen으로 대체 하여이 모든 프로젝트에서 우리는 갑자기 몇 시간 대신 며칠 동안 실행할 수있었습니다. 우리는 또한 화면 디스플레이 및 로그 파일에서 잘린 문자열이 많이 나오는 것을 보았습니다. 그로 인해 우리에게는 잘린 문제, 이전에는 충돌하는 문제를 추적하는 데 필요한 단서를 제공했습니다.

이 작업을 원하지 않으면 NULL의 포인터 매개 변수를 모두 확인하고 문자열 사본의 최대 크기를 제한하여 훨씬 작은 이점을 얻을 수 있습니다. 경계에 도달하는 모든 시간을 기록합니다. 문자열이 제대로 종료되지 않으면 strlen이 행복하게 충돌하므로 두 개의 매개 변수를 수행하지 마십시오.

요즘에는 새로운 프로젝트가 좋은 문자열 객체를 사용하지만 그렇지 않은 레거시 코드가 많이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top