'C/C++'에 해당되는 글 1건

  1. 2009.09.14 :: snprintf() 문제점???
C/C++ 2009. 9. 14. 15:50
반응형

회사 다니면서 사용하게 된 snprintf()는 사이즈를 체크할 수 있기 때문에
사이즈 커져 생길 수 있는 오류를 미리 예방할 수 있다.
(많은 core는 string을 copy하면서 발생)

그러다 어느날 sprintf()를 쓰면서 한가지 문제가 발생했다.

snprintf(cmd, CMD_LEN-1, "%s/INMSIFD/smb-inmsifd-1.0/get_patch_file.sh", getenv("XN_HOME"));
    if( !(fp = fopen(cmd, "r")) )
    {
        uLogApp(LOG_MAJ, "getFtpSystemPatchFile() << FILE : %s isn't exist!!", cmd);
        return uFalse;
    }
    if(fp) {
        pclose(fp); fp = NULL;
    }

    snprintf(cmd, CMD_LEN-1, "%s %s %s %s %s %s %s", cmd, g_SmbInfo.patchIpAddr, g_SmbInfo.patchId,
            g_SmbInfo.patchPassword, g_SmbInfo.patchBasePath,
            g_SmbInfo.patchDownDir, fileName);

    uLogApp(LOG_DEB0, "getFtpSystemPatchFile() << CMD : (%s) ", cmd);

소스가 조금 지저분하지만..
1. snprintf()를 이용해서 cmd에 특정 값을 저장한다.
2. 다시 snprintf()를 이용해서 cmd에 기존에 저장된 cmd값과 다른 값들을 함께 저장한다.
결과 : 기존 cmd에 있는 값들은 모두 삭제

기존 cmd값이 삭제되기 때문에 원하는 결과가 출력되지 않는다.
이렇게 사용한 것은 sprintf()를 사용하던 버릇때문에 발생한 문제인데
똑같은 사용이라도 sprintf()를 사용하면 발생하지 않는 문제이다.

<해결방법>
1. snprintf() -> sprintf()를 사용 ( 조금 무식한 방법으로, 사이즈 체크가 어렵기 때문에 패스)
2. offset을 이용한 방법 (권장)

다음은 offset을 이용해 해결한 방식이다.


xi32    offset=0;
    offset = snprintf(cmd, CMD_LEN-1, "%s/INMSIFD/smb-inmsifd-1.0/get_patch_config.sh",
            getenv("XN_HOME"));

    if( !(fp = fopen(cmd, "r")) )
    {
        uLogApp(LOG_MAJ, "getFtpSystemPatchCfg() << FILE : %s isn't exist!!", cmd);
        return uFalse;
    }
    if(fp) {
        pclose(fp); fp = NULL;
    }
    uLogApp(LOG_MAJ, "CMD : (%s) ", cmd);
    // get ftp SYSTEM_PATCH_CONFIG.ini
    snprintf(cmd+offset, CMD_LEN-1, " %s %s %s %s %s", g_SmbInfo.patchIpAddr, g_SmbInfo.patchId,
            g_SmbInfo.patchPassword, g_SmbInfo.patchBasePath, g_SmbInfo.patchDownDir);
    uLogApp(LOG_MAJ, "CMD : (%s) ", cmd);

보다시피, offset을 사용하여 기존 cmd에서 남기고자 하는 만큼 off을 이용해서 포인터를 이동해서 복사한다. 문제 해결!!!

하지만 기존 값을 중간에 넣고 싶다면, 이 방법도 사용하지 못할 것....
그럴 때는 다른 변수를 사용해야 겠지???

왜 sprintf()는 가능한데 snprintf()는 안될까??
궁금하다~

반응형
posted by ssuk1010
: