【问题标题】:_tcsncpy_s() write over old content?_tcsncpy_s() 覆盖旧内容?
【发布时间】:2012-05-30 09:31:42
【问题描述】:

在字符串上多次使用 _tcsncpy_s() 是否会覆盖旧内容?还是它创建新内容然后指向新内容?举个简单的例子,如果我有:

    LPTSTR myString = new TCHAR[MAX_PATH];
    LPTSTR copiedString1 = "Hello";
    LPTSTR copiedString2 = "Rock";
    _tcsncpy_s(myString,MAX_PATH,copiedString1,5); //1
    //delete [] myString; //3
    //LPTSTR myString = new TCHAR[MAX_PATH]; //3
    _tcsncpy_s(myString,MAX_PATH,copiedString2,4); //2

我在 1 处理解:我们有 myString --> 'H' 'e' 'l' 'l' 'o'

但是在第 2 点:'R' 'o' 'c' 'k' 是否被复制到 'H' 'e' 'l' 'l' 上,而 'o' 仍然存在?还是它现在指向内存中的一个新区域?我需要像 3 那样删除并重新创建 myString 吗?如果我先复制了String2,然后复制了String1,该怎么办?会发生什么不同的事情吗?还有什么可能有用的吗?

感谢您的宝贵时间,祝您有愉快的一天。

【问题讨论】:

  • 为什么_tcsncpy_s要分配新内存??您正在向它传递一个指向它应该写入的内存位置的指针,它只是写入该位置...如果您将相同的位置传递两次,它会两次写入相同的位置...这里没有魔术发生.

标签: c++ strcpy


【解决方案1】:

但是在第 2 点: 'R' 'o' 'c' 'k' 是否被复制到 'H' 'e' 'l' 'l' 上, 而'o'仍然存在?

是的。阅读documentation

这些函数尝试将 strSource 的前 D 个字符复制到 strDest,其中 D 是 count 和 strSource 长度中的较小者。如果这些 D 字符将适合 strDest(其大小以 numberOfElements 给出)并且仍然为空终止符留出空间,则复制这些字符并附加终止空;否则,将 strDest[0] 设置为空字符并调用无效参数处理程序,如参数验证中所述。

现在,关于您的其他问题:

或者它现在指向内存中的一个新区域?

不,mystring 仍然指向同一个数组。

我 需要像 3 那样删除并重新创建 myString 吗?

也许吧。取决于你想做什么。如果您想要两个字符串的副本,那么是的,您将需要两个字符数组(静态或动态)。

如果我有 先复制String2,再复制String1?

在这种情况下,你会得到Rock 作为你的字符串。

有什么不同 发生了什么?

操作后mystring 中存在不同的字符串,所以是的。

还有什么可能有用的吗?

你想连接这两个字符串吗?如果是这样,请使用连接函数,例如strcat。另外,请注意以下划线开头的函数是非标准的、供应商特定的函数,因此不可能完全移植。尝试使用标准定义的函数(如strncpystrcatstrncat等)。

MS 世界中以_t 为前缀的函数通常是宏,它们根据您的项目设置切换到相应函数的适当 ASCII/Unicode 版本(即 UNICODE/_UNICODE 预处理器宏是否已经定义与否)。

最后,字符串复制和连接的变体与n 之间从源读取最多n 个字符。这种设计允许程序员编写安全代码(因此prevent buffer overflows)。

哦,在我们忘记之前,如果您使用的是 C++,您应该忘记所有关于 C 风格的字符串操作,并简单地切换到更简洁、更易于使用的 std::string(或 std::wstring 视情况而定)可能是)。字符串复制通过简单的赋值发生(即= 就足够了)并且连接同样是惯用的(即+= 就足够了)。更多请查看the documentation

【讨论】:

  • 非常感谢。你的答案很完美
  • @JHowzer:我强烈建议您重新阅读最后一段,看看您是否可以转到suitabstd::string——这就是在C++中的做法。
猜你喜欢
  • 2011-04-20
  • 2018-03-30
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多