更改数组的最后5个字符

时间:2012-06-04 18:12:52

标签: c++

我有一个加密文件的程序,但最后添加扩展名“.safe”。所以最终结果就像“file.txt.safe”

当我去解密文件时,用户再次输入文件名:“file.txt.safe”,它被保存到char中。现在我想删除“.safe”并将文件重命名为其原始名称。

我尝试过以下操作,但似乎没有任何事情发生,也没有错误。

Decrypt (myFile); //decrypts myFile

char * tmp = myFile;
char * newFile;
newFile = strstr (tmp,".safe");  //search tmp for ".safe"
strncpy (newFile,"",5);   //replace .safe with ""

rename (myFile, newFile);

我确定我错过了一些明显的东西,但如果这种方法不起作用,我正在寻找任何简单的方法。

编辑添加: (由主持人从海报对K-ballo的回复中复制)

谢谢大家。我采用了std :: string方法,发现它可以工作:

Decrypt(myFile); 
string str = myFile; 
size_t pos = str.find(".safe"); 
str.replace(pos,5,""); 
rename(myFile, str.c_str());

2 个答案:

答案 0 :(得分:4)

对于您想要做的事情,只需将strncpy行改为此即可:

*newFile = '\0';

如果文件名包含早期 .safe (例如 file.safest.txt.safe ),或者如果它不包含子字符串,则仍会出现问题 .safe 。你最好从数组的末尾搜索,并确保找到一些东西。

这似乎是一种更好的方法(尽管在 C ++ 中,最好只使用std::string):

char* filename = ...;
size_t filename_length = strlen( filename );
int safe_ext_pos = filename_length - 5; // 5 == length of ".safe"
if( safe_ext_pos > 0 && strcmp( ".safe", filename + safe_ext_pos ) == 0 )
    filename[ safe_ext_pos ] = '\0';

这是代码的std::string版本:

std::string filename = ...;
int safe_ext_pos = filename.length() - 5; // 5 == length of ".safe"
if( safe_ext_pos > 0 && filename.compare( safe_ext_pos, 5, ".safe" ) == 0 )
    filename.erase( safe_ext_pos );

答案 1 :(得分:0)

你应该小心:

my.safe.file.txt.safe

不是只搜索'.safe'并删除它或截断第一个文件名,你应该确保它实际上在字符串的末尾:

std::string myfile = ...
Decrypt(myFile);

const std::string extension_to_remove = ".safe";
if (decryption is successful &&
    myfile.size() >= extension_to_remove.size() &&
    myfile.substr(myfile.size()-5) == extension_to_remove)
{
  std::string newFile = myfile.substr(0, myfile.size()-5);
  rename(myFile, newFile);
}

还有关于文件扩展名的说明。对于软件来说,使用文件名中的特殊格式识别文件类型确实是一种非常糟糕的做法。*人类可以使用特殊的命名约定来组织文件,但软件基本上应该忽略它,除非是为了制作它人类很容易使用他们想要的惯例。

因此,解密文件的代码不应该执行此任务。相反,您的解密代码应该使用文件进行解密,并使用文件来包含输出。然后,用于计算加密文件名称的输出文件名的代码应存在于其他位置,例如用户界面中用户告诉您输出文件名。您的代码将删除“.safe”(如果存在)并提供修改后的名称作为默认输出文件名,以供用户确认。

void perform_decryption(std::string const &encrypted, std::string const &decrypted) {
    Decrypt(encrypted);
    if (decryption is successful && encrypted!=decrypted)
        rename(encrypted, decrypted);
}

std::string default_decrypted_name(std::string const &filename) {
    const std::string extension_to_remove = ".safe";
    if (filename.size() >= extension_to_remove.size() &&
        filename.substr(filename.size()-extension_to_remove.size()) == extension_to_remove)
    {
      return filename.substr(0, filename.size()-extension_to_remove.size());
    }
    return filename + ".decrypted";
}

*以下是针对文件扩展名的一些原因:

  • 文件扩展名不是唯一的,在某些情况下会导致无法正确识别文件类型的冲突。 (他们甚至无法达到预期目的的事实真的应该足够......)
  • 它降低了用于组织的文件名的可用性。当'myfile.txt'重命名为'myfile.txt.old'时,它不再被视为文本文件。
  • 这会导致安全问题,因为在隐藏真实类型元数据时,伪类型元数据可能会被误认为真实类型元数据。
  • <子> and more...