我将如何继续在函数之间"return"字符串数组?
How would I go on as to "return" string arrays between functions?
嘿,所以我正在试验我所知道的,并意识到当我试图传递一个字符串值与返回它不支持,任何想法?对不起,如果我的代码是菜鸟风格(我只有2个月的经验),我计划在函数之间分割代码,但我似乎不能这样做,因为返回我的字符串数组不能用return来完成:(这是代码:
#include <iostream>
#include <math.h>
#include <sstream>
using namespace std;
int itemlist=0;
int c=0;
int r = 0;
int itemlistdec()
{
cout<<"How many items would you like to input?";
cin>>itemlist;
return itemlist;
}
int main() {
itemlistdec();
string item[4][itemlist];//declares item and that columns equal to itemlist whose content is declared right above
for (int c=0;c<itemlist;c++)
{
for (int r=0;r<3;r++) //DETERMINES WHERE EACH RECORD GOES
{
if (r==0)
{
cout<<"Please enter the name of the item ";
}
if (r==1)
{
cout<<"Please input the buying pricen";
}
if (r==2)
{
cout<<"Please input the selling pricen";
}
cin>>item[r][c];
}
}
int calc[3][itemlist];//declaring calc and itemlist
for (int r = 0;r<itemlist;r++)
{
istringstream(item[1][r])>>calc[0][r]; //TAKES BUYING PRICE INTO INT ARRAY FOR CALCULATION
}
for (int r = 0;r<itemlist;r++)
{
istringstream(item[2][r])>>calc[1][r]; //TAKES SELLING PRICE INTO INT ARRAY FOR CALCULATION
}
for (int fart = 0;fart<itemlist;fart++)
{
calc[2][fart] = calc[1][fart] - calc[0][fart]; //REPEATS CALCULATION FOR PROFIT UNTIL ITEMLIST IS REACHED
}
for (int r = 0;r<itemlist;r++)
{
stringstream ss;
ss<<calc[2][r]; //CONVERTS BOTH PROFIT VALUES INTO STRINGS
item[3][r] = ss.str();
}
cout<<"______________________________________________n"; //DISPLAYS OUTPUT IN TABLE FORM
cout<<"ItemttBuying PricettSelling PricettProfitn";
for (int c=0;c<itemlist;c++)
{
for (int r=0;r<4;r++)
{
cout<<item[r][c]<<"tt";
if (r==1)
{
cout<<"t";
}
if (r==2)
{
cout<<"t";
}
if (r==3)
{
cout<<"n";
}
}
}
return 0;
}
我认为你可以使用vector,它非常强大。像这样:
std::vector<std::vector<std::string> > mySecondVector;
std::vector<std::string> myFirstVector;
myFirstVector.push_back("MyString");
mySecondVector.push_back(myFirstVector);
mySecondVector[i][j]; // to access
对于add,访问一个元素监视http://www.cplusplus.com/reference/vector/vector/
返回一个数组有点傻。你必须把它作为一个指针返回,一旦你这样做,你就失去了所有的大小信息。您可以通过itemlist作为一个全局变量来处理这个问题,但是全局变量会施加它们自己的一组限制。首先,你永远不能有一个以上的数组(除非它们的大小相同),因为多个数组会将它们的长度存储在同一个位置。
首先,您必须翻转数组的方向以获得最右侧索引的恒定大小。坦率地说,由于局部性(关于一个条目的所有数据都在相同的内存区域),所以如果您将条目的一部分加载到缓存中,则可能会加载所有条目。这几乎总是导致程序更快)无论如何,这样做可能更好。然后你可能已经注意到你不能只是返回string[][]
或任何看起来像它没有编译器叫你,所以你必须玩游戏定义自定义的数据类型,你可以返回。
typedef string (*arrayPtr)[4];
现在你可以试试
arrayPtr itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
string item[itemlist][4];
//load the array
return item;
}
itemlist知道数组有多大,但是你得到了一个新的障碍。物品超出你的范围,不再有效。更有趣的是,string item[itemlist][4];
甚至不是合法的c++,因为itemlist
不是一个常数值。它在一些c++编译器中是一种方便,但不是全部。
这个怎么样?数组的动态分配将使它比itemlistdec活得更久,但是现在您必须在使用完数组后手动删除它。
arrayPtr itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
arrayPtr item = new string[itemlist][4];
//load the array
return item;
}
现在我们有了一些有用的东西。我们可以通过
使其更具可读性(同时也更少,因为读者必须跟踪array
是什么才能知道如何使用它)。typedef string (array)[4];
typedef array (*arrayPtr);
arrayPtr itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
arrayPtr item = new array[itemlist];
//load the array
return item;
}
这不能扩展到两个维度上的可变长度,或者如果您绝对必须在内部索引上使用常量。在这种情况下,您需要这个组合:
string ** itemlistdec()
{
cout << "How many items would you like to input?";
cin >> itemlist;
string** item = new string*[4]; // 4 can be any number, but you also have to
// use it in place of 4 in the for loop
for (size_t index = 0; index < 4; index++)
{
item[index] = new string[itemlist];
}
//load the array
return item;
}
可行,但你现在已经承担了一堆内存管理职责。所有分配的内存必须使用delete[]
释放。在string **
的情况下,在删除最左边的数组之前,必须遍历最左边的索引和delete[]
最右边的所有数组。
您可以使用vector<vector<string>>
消除这种情况,但在这种情况下它很难看。很棒的技巧,但不符合整个程序的目标。
vector<vector<string>> itemlistdec()
{
int itemlist;
cout << "How many items would you like to input?";
cin >> itemlist;
vector<vector<string>> item(4, vector<string>(itemlist));
for (int c=0;c<itemlist;c++)
{
cout<<"Please enter the name of the item ";
cin>>item[0][c];
cout<<"Please input the buying pricen";
cin>>item[1][c];
cout<<"Please input the selling pricen";
cin>>item[2][c];
}
return item;
}
注意,我返回的是本地向量,并依靠move语义在返回时移动向量,而不是复制它。还需要注意的是,您不再需要全局itemlist,因为vector知道它有多大。如果你想的话,你甚至可以稍后添加一些东西。还要注意,我去掉了输入的内部for循环。不需要。
这比数组选项更好,但我仍然不喜欢它。Item调用了它自己的类,这样我们就可以利用面向对象编程带来的好处。我们还可以为所有成员变量设置正确的数据类型。这样,我们就可以在用户输入错误的输入时捕获它,并消除计算中使用的额外整数数组。
class Item
{
public:
void read(istream & in)
{
// ignoring possibility of total failure of cin here.
cout<<"Please enter the name of the item ";
in >> name;
cout<<"Please input the buying pricen";
while (!(in >> buyPrice)) // loop until we read an integer from the user.
{
in.clear();
cout<<"Invalid. Please input the buying pricen";
}
cout<<"Please input the selling pricen";
while (!(in >> sellPrice))
{
in.clear();
cout<<"Invalid. Please input the selling pricen";
}
return in;
}
// calc logic method goes here.
// output method goes here.
private:
string name;
int buyPrice; // no screwing around with the calc array. numbers are
//read in as numbers or the input fails
int sellPrice;
};
vector<Item> itemlistdec()
{
int nrItems = 0;
cout << "How many items would you like to input?";
cin >> nrItems;
vector<Item> itemlist(nrItems);
for (Item& item : itemlist)
{
item.read(cin);
}
return itemlist;
}
注意,我并没有检查所有输入的有效性,只是检查是否使用了有效的整数。可能足够了,但是....我不小心关闭了stdin。调试不是一件有趣的事情。无论如何,如果stdin向下,问题会更严重。
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- 在 const 函数中通过引用和指针返回之间的区别
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 填充上编译器生成的复制构造函数之间的不一致
- 析构函数和'delete'之间的区别
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 如何在"push_*()"和"emplace_*()"函数之间进行选择?
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 在 C 和 C++ 中作为函数参数,int **a 和 int a[][] 之间有什么确切的区别
- 定义类模板构造函数的两种方法之间的区别
- 仅具有运算符()的结构和普通函数之间的实际区别
- 可变/非可变模板之间函数类型衰减的不一致性