C++ C++;关于字符串类实现的考试
我刚刚参加了一次考试,被问到以下问题: 为下面给定的代码编写GenStrLen、InsertChar和StrReverse方法的函数体。你必须考虑以下几点:C++ C++;关于字符串类实现的考试,c++,string,character,C++,String,Character,我刚刚参加了一次考试,被问到以下问题: 为下面给定的代码编写GenStrLen、InsertChar和StrReverse方法的函数体。你必须考虑以下几点: 如何在C中构造字符串++ 字符串不能溢出 插入字符会使其长度增加1 空字符串由StrLen=0表示 我给出的答案是这样的(见下文)。我的一个问题是使用了许多额外的变量,这让我相信我没有尽可能地做到最好,另一个问题是,这不起作用 class Strings { private: char str[80]; int Str
- 如何在C中构造字符串++
- 字符串不能溢出
- 插入字符会使其长度增加1
- 空字符串由StrLen=0表示
我给出的答案是这样的(见下文)。我的一个问题是使用了许多额外的变量,这让我相信我没有尽可能地做到最好,另一个问题是,这不起作用
class Strings {
private:
char str[80];
int StrLen;
int index; // *** Had to add this ***
public:
Strings(){
StrLen=0;
}
int GetStrLen(void){
for (int i=0 ; str[i]!='\0' ; i++)
index++;
return index; // *** Here am getting a weird value, something like 1829584505306 ***
}
void InsertChar(char ch){
str[index] = ch; // *** Not sure if this is correct cuz I was not given int index ***
}
void StrRevrse(void){
GetStrLen();
char revStr[index+1];
for (int i=0 ; str[i]!='\0' ; i++){
for (int r=index ; r>0 ; r--)
revStr[r] = str[i];
}
}
};
如果有人能向我大致解释一下什么是回答这个问题的最佳方式,以及为什么,我将不胜感激。还有,为什么我的教授会关闭每个类函数,比如“};”,我认为它只用于结束类和构造函数 非常感谢你的帮助
int GetStrLen(void){
for (int i=0 ; str[i]!='\0' ; i++)
index++;
return index; // *** Here am getting a weird value, something like 1829584505306 ***
}
您得到一个奇怪的值,因为您从未初始化索引,只是开始递增它。初始化字符数组时,应将其第一个元素设置为0,对于
索引
,也应设置为0。因此,在GetStrLen
中你会得到一个奇怪的长度,因为当你找到你正在寻找的0时,这取决于神
[Update]在C/C++中,如果不显式初始化变量,通常会用随机垃圾(分配给它们的原始内存的内容)填充它们。此规则也有一些例外,但最佳实践是始终显式初始化变量[/Update]
在InsertChar
中,您应该(在检查溢出后)使用StrLen
索引数组(因为注释指定“在字符串“str”的末尾插入字符“ch”),然后设置新的终止0字符并递增StrLen
您的GetStrLen()
函数不起作用,因为str
数组未初始化。它可能不包含任何零元素
您不需要索引
成员。只需使用StrLen
跟踪当前字符串长度
void InsertChar(char ch){
str[index] = ch; // *** Not sure if this is correct cuz I was not given int index ***
}
这应该更像
str[strlen-1]=ch; //overwrite the null with ch
str[strlen]='\0'; //re-add the null
strlen++;
你不需要计算长度。你已经知道了,是斯特伦。此外,原始问题中没有任何内容表明缓冲区应包含以null结尾的字符串
int GetStrLen(void){
return strLen;
}
这里只使用断言,但另一个选项是抛出异常
void InsertChar(char ch){
assert(strLen < 80);
str[strLen++] = ch;
}
void InsertChar(char-ch){
断言(strLen<80);
str[strLen++]=ch;
}
反转字符串只是交换str缓冲区中的元素的问题
void StrRevrse(void){
int n = strLen >> 1;
for (int i = 0; i < n; i++) {
char c = str[i];
str[i] = str[strLen - i];
str[strLen - i] = c;
}
}
void strevrse(void){
int n=strLen>>1;
对于(int i=0;i
首先,琐碎的}代码>问题只是风格问题。当我将函数体放入类声明中时,我也会这样做。在这种情况下,
只是一个空语句,不会改变程序的含义。它可以不在函数的末尾(但不能在类的末尾)
以下是您所写内容的一些主要问题:
您从不初始化str
的内容。不能保证以\0
字节开始
您从不初始化索引
,只在GetStrLen
中设置它。当程序启动时,它的值可能为-19281281。如果有人在调用GetStrLen
之前调用InsertChar
,该怎么办
您从不在InsertChar
中更新index
。如果有人连续两次调用InsertChar
,该怎么办
在StrReverse
中,您创建了一个名为revStr
的反向字符串,但是您从未对它做过任何操作。str
中的字符串保留相同的后缀
让我感到困惑的是,为什么创建了一个名为index
的新变量,大概是为了跟踪字符串中最后一个字符的索引,而此时已经有一个名为StrLen
的变量用于此目的,而您完全忽略了它。最后一个字符的索引是字符串的长度,因此您应该保持字符串的长度为最新,并使用它,例如
int GetStrLen(void){
return StrLen;
}
void InsertChar(char ch){
if (StrLen < 80) {
str[StrLen] = ch;
StrLen = StrLen + 1; // Update the length of the string
} else {
// Do not allow the string to overflow. Normally, you would throw an exception here
// but if you don't know what that is, you instructor was probably just expecting
// you to return without trying to insert the character.
throw std::overflow_error();
}
}
注意它是如何工作的。假设StrLen=10
。然后我们将str
的位置0复制到revStr
的位置9,然后将str
的位置1复制到revStr
的位置9
等,直到我们将str
的位置StrLen-1
复制到revStr
的位置0
但是在revStr
中有一个反向字符串,但仍然缺少将其放回str
的部分,因此完整的方法如下所示
void StrReverse() {
char revStr[80];
for (int i = 0; i < StrLen; ++i) {
revStr[(StrLen - 1) - i] = str[i];
}
for (int i = 0; i < StrLen; ++i) {
str[i] = revStr[i];
}
}
void StrReverse(){
char revStr[80];
对于(int i=0;i
有一些更聪明的方法可以做到这一点,你不必有一个临时字符串revStr
,但是上面的方法功能完善,可以正确地回答这个问题
顺便说一下,在这段代码中根本不需要担心空字节(
\0
s)。事实上你是(或者至少你应该是)使用StrLen
变量跟踪字符串的长度会使end sentinel变得不必要,因为使用StrLen
您已经知道应该忽略str
内容的点。我将使用StrLen
跟踪字符串的长度。由于长度也表示字符串的结尾,因此我们可以使用该长度插入:
int GetStrLen(void) {
return StrLen;
}
int InsertChar(char ch)
{
if (strLen < sizeof(str))
{
str[StrLen] = ch;
++strLen;
}
}
void StrReverse(void) {
for (int n = 0; n < StrLen / 2; ++n)
{
char tmp = str[n];
str[n] = str[StrLen - n - 1];
str[StrLen - n - 1] = tmp;
}
}
int GetStrLen
void StrReverse() {
char revStr[80];
for (int i = 0; i < StrLen; ++i) {
revStr[(StrLen - 1) - i] = str[i];
}
for (int i = 0; i < StrLen; ++i) {
str[i] = revStr[i];
}
}
int GetStrLen(void) {
return StrLen;
}
int InsertChar(char ch)
{
if (strLen < sizeof(str))
{
str[StrLen] = ch;
++strLen;
}
}
void StrReverse(void) {
for (int n = 0; n < StrLen / 2; ++n)
{
char tmp = str[n];
str[n] = str[StrLen - n - 1];
str[StrLen - n - 1] = tmp;
}
}
class Strings {
private:
char str[80];
int StrLen;
public:
// Constructor
Strings() {
StrLen=0;
str[0]=0;
};
// A function for returning the length of the string 'str'
int GetStrLen(void) {
return StrLen;
};
// A function to inser a character 'ch' at the end of the string 'str'
void InsertChar(char ch) {
if(StrLen < 80)
str[StrLen++]=ch;
};
// A function to reverse the content of the string 'str'
void StrReverse(void) {
for(int i=0; i<StrLen / 2; ++i) {
char aux = str[i];
str[i] = str[StrLen - i - 1];
str[StrLen - i - 1] = aux;
}
};
};
#include <iostream>
void swap_chars(char* left, char* right) {
char temp = *left;
*left = *right;
*right = temp;
}
class Strings {
private:
char m_buffer[80];
int m_length;
public:
// Constructor
Strings()
:m_length(0)
{
}
// A function for returning the length of the string 'm_buffer'
int GetLength() const {
return m_length;
}
// A function to inser a character 'ch' at the end of the string 'm_buffer'
void InsertChar(char ch) {
if (m_length < sizeof m_buffer) {
m_buffer[m_length++] = ch;
}
}
// A function to reverse the content of the string 'm_buffer'
void Reverse() {
char* left = &m_buffer[0];
char* right = &m_buffer[m_length - 1];
for (; left < right; ++left, --right) {
swap_chars(left, right);
}
}
void Print() const {
for (int index = 0; index < m_length; ++index) {
std::cout << m_buffer[index];
}
std::cout << std::endl;
}
};
int main(int, char**) {
Strings test_string;
char test[] = "This is a test string!This is a test string!This is a test string!This is a test string!\000";
for (char* c = test; *c; ++c) {
test_string.InsertChar(*c);
}
test_string.Print();
test_string.Reverse();
test_string.Print();
// The output of this program should look like this...
// This is a test string!This is a test string!This is a test string!This is a test
// tset a si sihT!gnirts tset a si sihT!gnirts tset a si sihT!gnirts tset a si sihT
return 0;
}