gpt4 book ai didi

c++ - 在 C++ 中处理字符串时如何使用 memset?

转载 作者:IT老高 更新时间:2023-10-28 12:46:21 25 4
gpt4 key购买 nike

我来自 Python 背景,最近学习 C++。我正在学习一个名为 memset 的 C/C++ 函数,并按照网站 https://www.geeksforgeeks.org/memset-in-cpp/ 的在线示例进行操作。我遇到了一些编译错误:

/**
* @author : Bhishan Poudel
* @file : a02_memset_geeks.cpp
* @created : Wednesday Jun 05, 2019 11:07:03 EDT
*
* Ref:
*/

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

int main(int argc, char *argv[]){
char str[] = "geeksforgeeks";

//memset(str, "t", sizeof(str));
memset(str, 't', sizeof(str));

cout << str << endl;

return 0;
}

使用单引号't'时出错
这会打印额外的字符。

tttttttttttttt!R@`

使用带双引号的“t”时出错

$ g++ -std=c++11 a02_memset_geeks.cpp 
a02_memset_geeks.cpp:17:5: error: no matching function for call to 'memset'
memset(str, "t", sizeof(str));
^~~~~~
/usr/include/string.h:74:7: note: candidate function not viable: no known
conversion from 'const char [2]' to 'int' for 2nd argument
void *memset(void *, int, size_t);
^
1 error generated.

如何在 C++ 中使用 memset?

进一步研究
memset 的缺点的优秀教程在这里给出: https://web.archive.org/web/20170702122030/https:/augias.org/paercebal/tech_doc/doc.en/cp.memset_is_evil.html

最佳答案

此声明

char str[] = "geeksforgeeks";

声明一个字符数组,该数组包含一个字符串,该字符串是一个字符序列,包括终止零符号'\0' .

你可以想象声明如下等价方式

char str[] = 
{
'g', 'e', 'e', 'k', 's', 'f', 'o', 'r', 'g', 'e', 'e', 'k', 's', '\0'
};

此函数调用memset

memset(str, 't', sizeof(str));

覆盖数组的所有字符,包括终止零。

所以下一条语句

cout << str << endl;

导致未定义的行为,因为它在遇到终止零之前输出字符。

你可以改写

#include <iostream>
#include <cstring>

int main()
{
char str[] = "geeksforgeeks";

std::memset( str, 't', sizeof( str ) - 1 );

std::cout << str << '\n';
}

或者如下方式

#include <iostream>
#include <cstring>

int main()
{
char str[] = "geeksforgeeks";

std::memset( str, 't', std::strlen( str ) );

std::cout << str << '\n';
}

这就是保持数组中的终止零不变。

如果你想覆盖数组的所有字符,包括终止零,那么你应该替换这个语句

std::cout << str << '\n';

对于这个声明

std::cout.write( str, sizeof( str ) ) << '\n';

如下面的程序所示,因为数组现在不包含字符串了。

#include <iostream>
#include <cstring>

int main()
{
char str[] = "geeksforgeeks";

std::memset( str, 't', sizeof( str ) );

std::cout.write( str, sizeof( str ) ) << '\n';
}

至于这个电话

memset(str, "t", sizeof(str));

那么第二个参数的类型(即类型 const char *)不对应于类型为 int 的第二个函数参数的类型.见函数声明

void * memset ( void * ptr, int value, size_t num );

因此编译器会发出错误消息。

除了字符数组(即使在 C++ 中也经常使用),您还可以使用标准类 std::string (或 std::basic_string )模拟字符串。

在这种情况下,不需要使用标准 C 函数 memset 来用单个字符填充字符串。最简单的方法如下

#include <iostream>
#include <string>

int main()
{
std::string s( "geeksforgeeks" );

s.assign( s.length(), 't' );

std::cout << s << '\n';
}

另一种方法是使用标准算法std::fillstd::fill_n在标题中声明 <algorithm> .例如

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
std::string s( "geeksforgeeks" );

std::fill( std::begin( s ), std::end( s ), 't' );

std::cout << s << '\n';
}

#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>

int main()
{
std::string s( "geeksforgeeks" );

std::fill_n( std::begin( s ), s.length(), 't' );

std::cout << s << '\n';
}

你甚至可以使用 replace 的方法类(class) std::string以下方式之一

#include <iostream>
#include <string>

int main()
{
std::string s( "geeksforgeeks" );

s.replace( 0, s.length(), s.length(), 't' );

std::cout << s << '\n';
}

或者

#include <iostream>
#include <string>

int main()
{
std::string s( "geeksforgeeks" );

s.replace( std::begin( s ), std::end( s ), s.length(), 't' );

std::cout << s << '\n';
}

关于c++ - 在 C++ 中处理字符串时如何使用 memset?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56463341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com