使用 Char 数组作为多种用途的通用变量

Using a Char Array as a general variable for multiple uses

本文关键字:变量 Char 数组 使用      更新时间:2023-10-16

需要帮助,了解如何将 1 个字符数组用于多个用户输入,将用户输入数据传递给类 setMethod(),然后释放或重用相同的字符数组变量用于下一个用户输入语句,冲洗并重复。 我知道对于指针,您可以删除与它们关联的内存地址以释放空间,所以我认为这将是我最好的选择?

// 9Application01.cpp
// Zachary James Mcclurg
#include "pch.h"
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
const int NAME_SIZE = 20;
const int STREET_SIZE = 30;
const int CITY_SIZE = 20;
const int STATE_CODE_SIZE = 3;
const int MAXINPUT = 80;
class Customer
{
private:
long customerNumber;
char custName[NAME_SIZE];
char streetAddress_1[STREET_SIZE];

public:
bool setNum(long num);
bool setName(char namesize[]);
bool setAddress1(char address1[]);

long getNum() const;
char* getName();
char* getAdd1();
};

bool Customer::setNum(long num)
{
if (num > 99999 || num < 0) {
cout << "Invalid input. Re-enter ";
return false;
}
customerNumber = num;
return true;
}
bool Customer::setName(char namesize[MAXINPUT])
{
if (strlen(namesize) >= NAME_SIZE) {
cout << "Invalid input. Re-enter ";
return false;
}
strcpy_s(custName, namesize);
return true;
}
bool Customer::setAddress1(char address1[MAXINPUT])
{
if (strlen(address1) >= NAME_SIZE) {
cout << "Invalid input. Re-enter ";
return false;
}
strcpy_s(streetAddress_1, address1);
return true;
}

// Getter Methods 
long Customer::getNum() const
{
return customerNumber;
}
char* Customer::getName()
{
return custName;
}
char* Customer::getAdd1()
{
return streetAddress_1;
}

int main()
{
Customer custom;
char dataLine[MAXINPUT];
long numLine;

cout << "Name: ";
cin.getline(dataLine, MAXINPUT);
custom.setName(dataLine);
cout << "Customer ID: ";
cin >> numLine;
custom.setNum(numLine);
cout << "Primary Address: ";
cin.getline(dataLine, MAXINPUT);
custom.setAddress1(dataLine);

cout << "Your Name is: " << custom.getName() << endl;
cout << "Your Customer ID is: " << custom.getNum() << endl;
cout << "Your Primary Address is: " << custom.getAdd1() << endl;
}

同一字符数组可用于多次读取。只要不是动态分配的,就不需要清理:

#include <iostream>
int main()
{
char cstr[50];
while(std::cin.getline(cstr, 50))
{
std::cout << "I read "" << cstr << """ << std::endl;
}
return 0;
}

如果数组是动态分配的(如果字符串大到足以导致堆栈溢出,则应该是动态分配的),则必须在完成后delete[]它:

#include <iostream>
int main()
{
auto cstr = new char[50];
while(std::cin.getline(cstr, 50))
{
std::cout << "I read "" << cstr << """ << std::endl;
}
delete[] cstr;
return 0;
}

但是这段代码很危险。您可能会忘记清理,或者中间某处的异常可能会导致内存泄漏。您应该考虑std::string以获得最大的异常安全性,并且它也更易于使用。std::string通常持有一个指向堆上动态分配的内存的指针,并且一旦字符串超出范围,它还负责清理它。这意味着您不必担心管理内存/堆栈溢出等。下面是一个示例:

#include <iostream>
#include <string>
int main()
{
auto line = std::string(); // guaranteed to make no copies with C++17
while(std::getline(std::cin, line))
{
std::cout << "I read "" << line << """ << std::endl;
}
// No need to clean up manually!
return 0;
}

只要有意义,就重用变量。有时你会发现,为了给你的变量提供漂亮的可读名称,值得扔掉几个字节,而不是在其标识符不再有意义的情况下使用相同的名称。可读代码值得其黄金的 KLOC。

如果您不能浪费内存,可以使用引用为现有变量分配新名称,但更喜欢下一个选项。

如果您希望变量在完成操作后消失,则首选较窄范围内的自动变量,而不是动态分配。

例:

int main()
{
int result;
{
char huge[102400]; // big 100k char array we don't want any longer than necessary
// use huge array in computation of result
} // huge array exits scope and is freed.
// do stuff with result;
}

由于huge是一个 Automatic 变量,因此无论范围如何退出,它一旦退出其作用域就会被销毁。这很难通过动态分配来保证。数以百万计的程序员编写的数以百万计的程序表明,拥有绕过delete的执行路径非常容易。huge的唯一缺点是您必须在编写程序时密切关注可用的自动存储量。

如果堆栈空间是一个问题,则动态分配,但要确保分配由作为 Automatic 变量的容器对象(库容器或智能指针)管理。