0

我有一个加密文件的程序,但在末尾添加了扩展名“.safe”。所以最终结果类似于“file.txt.safe”

当我去解密文件时,用户再次输入文件名:“file.txt.safe”,它保存为一个字符。现在我想删除“.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());
4

2 回答 2

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 );
于 2012-06-04T18:17:14.490 回答
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”时,它不再被视为文本文件。
  • 这会导致安全问题,因为当隐藏真实类型元数据时,虚假类型元数据可能会被误认为是真实类型元数据。
  • 和更多...
于 2012-06-04T19:45:46.203 回答