我正在学习C ++,我需要创建结构Airplane
并使用它。
我的结构 Airplane.h
#include "stdafx.h"
using namespace std;
struct Airplane {
string destination;
int number;
string type;
};
这是我的代码
#include "stdafx.h"
#include "Airplane.h"
string SetDestination(int n);
string SetType(int n);
void PrintAirplaneList(Airplane * &airplaneList, int n, string title);
void SortByDestination (Airplane *&airplaneList, int n);
void FindAirplanesAndPrint(Airplane *&airplaneList, int n, string type);
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
srand((unsigned)time(NULL));
int n;
cout << "Input n = ";
cin >> n;
Airplane * airplaneList = new Airplane[n];
for (int i = 0; i < n; ++i)
{
airplaneList[i].destination = SetDestination(rand()%5);
airplaneList[i].number = rand()%9001 + 1000;
airplaneList[i].type = SetType(rand()%3);
}
PrintAirplaneList(airplaneList, n, "List:");
SortByDestination (airplaneList, n);
PrintAirplaneList(airplaneList, n, "Sorted list (by destination):");
string type;
cout << "Input type: ";
getline(cin, type);
FindAirplanesAndPrint(airplaneList, n, type);
delete [] airplaneList;
system("PAUSE");
return 0;
}
string SetDestination (int n)
{
string destination;
switch(n){
case 0: destination = "Tokio"; break;
case 1: destination = "Amsterdam"; break;
case 2: destination = "Moscow"; break;
case 3: destination = "Philadelphia"; break;
case 4: destination = "San Diego"; break;
default: destination = "Unknown city"; break;
}
return destination;
}
string SetType (int n)
{
string type;
switch(n){
case 0: type = "passenger"; break;
case 1: type = "cargo"; break;
case 2: type = "post"; break;
default: type = "unknown type"; break;
}
return type;
}
void PrintAirplaneList(Airplane *&airplaneList, int n, string title)
{
cout << "\n";
cout << title << "\n\n";
for (int i = 0; i < n; ++i)
{
cout << "Destination: " << airplaneList[i].destination << "\n";
cout << "Number: " << airplaneList[i].number << "\n";
cout << "Type: " << airplaneList[i].type << "\n\n";
}
}
void SortByDestination (Airplane *&airplaneList, int n)
{
for (int i = 0; i < n - 1; ++i)
{
for (int j = 0; j < n -1; ++j)
{
if(airplaneList[j + 1].destination > airplaneList[j].destination) continue;
Airplane tempAirplane = airplaneList[j];
airplaneList[j] = airplaneList[j + 1];
airplaneList[j + 1] = tempAirplane;
}
}
}
void FindAirplanesAndPrint(Airplane *&airplaneList, int n, string type) {
cout << "Type - " << type << "\n";
int count = 0;
for (int i = 0; i < n; ++i)
{
if (airplaneList[i].type == type)
{
cout << "Destination: " << airplaneList[i].destination << "\n";
cout << "Number: " << airplaneList[i].number << "\n";
++count;
}
}
if (count == 0)
{
cout << "Not found\n";
}
}
我有两个问题 1.我无法在
中输入类型string type;
cout << "Input type: ";
getline(cin, type);
FindAirplanesAndPrint(airplaneList, n, type);
我的函数FindAirplanesAndPrint
开始工作,没有任何类型的值。如何让我的程序获得价值?
2.如何在函数中获得动态数组的大小?因为似乎每个函数中数组n
的传递大小是错误的。
答案 0 :(得分:4)
“如何在函数中获取动态数组的大小?因为看起来每个函数中数组n
的传递大小是错误的。”
然而,这是使用动态分配的C风格数组的唯一方法。
如果要避免显式发送大小,则传递一些包装此原始内存缓冲区的对象,并提供其他检索大小的方法。这里最合理的解决方案是使用std::vector<Airplane>
。
答案 1 :(得分:3)
1)忽略不相关的,这基本上就是你得到的:
cin >> n;
getline(cin, type);
operator>>
在输入缓冲区中留下一个换行符,这是getline
看到的第一个字符。由于'\n'
是默认行分隔符,因此您将获得一个空行。要解决此问题,请在致电cin.ignore()
以放弃getline
之前致电'\n'
。
2)如果您希望坚持使用原始指针,将尺寸作为参数传递是您唯一的选择。切换到std::vector
,您可以随时查询size()
方法。
答案 2 :(得分:1)
输入类型的问题是输入缓冲区在输入n后包含换行符。在使用函数getline之前,应该使用成员函数ignore来清除缓冲区。
至于你的第二个问题,那么你应该自己跟踪一个动态分配的数组的大小。或者,您可以将数组的最后一个元素设置为NULL,并将其用作标记。
答案 3 :(得分:0)
您可能会创建一个包含0个项目的动态数组,创建一个int计数器,使用getline作为语句进行while循环,而(getline(cin,string_var)!= SomeText)/ * SomeText =某种文本,用户向您显示不会再有输入* /了,您要在for中执行的操作应在一段时间内完成,而在while结束时将计数器增加一,即i ++。关于对数组的访问,如果您的动态数组有0个项目,则SomeDynamicArray [1] .something = SomeValue只会在数组中添加第二个项目,并且该项目的“某物”将等于SomeValue。
type *ArrayPointer = new type[0];
string StringVar;
int i = 0;
while (getline(cin, StringVar) != "Text that show there are not going to be any more inputs") {
/*code*/
i++;
}
idk是否适用于您的情况,但是如果需要,请尝试。同样,至少每个人都在谈论向量,至少我知道,向量速度较慢且花费更多的内存,因为它们使大小增加了一倍,而不是每次需要时都增加。希望能对您有所帮助。
答案 4 :(得分:0)
使用动态数组时,我使用的一种方法是将数组作为对该函数的引用。这将帮助您保留数组的大小信息。
例如:
string list1[3] = {
"item1",
"item2",
"item3"
};
string list2[2] = {
"item1",
"item2"
};
template<typename T, size_t N>
void PrintItems(T(&items)[N]) {
for (int i = 0; i < N; i++) {
cout << items[i] << endl;
}
}
int main() {
PrintItems(list1);
PrintItems(list2);
}
在前面的示例中,N存储该数组的正确大小信息。更多信息here
答案 5 :(得分:0)
你不能通过在 C++ 中找出动态分配数组的大小。
这实际上并不完全正确。广泛支持特定类型的大小检索 - 具有析构函数的对象数组的大小。
对于任何考虑使用它的人 - 我必须警告您,据我所知,任何标准或编译器供应商都无法以任何方式保证这一点。它可能会在任何时间点发生变化,除了业余爱好项目外,不应依赖它。
可破坏对象数组的大小存储在对象本身之前,可以通过基本指针转换访问:((size_t*)mem)[-1]
。
考虑一下 - 当您调用 delete []
时,您并没有传递数组的大小,因此 C++ 必须 以某种方式存储确切的大小以知道要调用多少个对象析构函数,以一种可以从指针本身轻松有效地访问的方式。但是 - 不能保证它必须是元素数 - 它也可以是字节数或结束指针,可能混合了一些标志位。也就是说,一旦他们决定了约定,它可能会破坏某种向后兼容性以便以后更改。
对于那些有兴趣对此进行测试的人,这是代码:https://ideone.com/Z0Sta1
#include <stdio.h>
struct bytes10
{
~bytes10() { printf("dtor %p", this); }
char _[10]; // to test whether the size or the count is returned
};
int main()
{
size_t size1 = ((size_t*)new int[10])[-1]; // doesn't work (pointer on some platforms, allocation size-based number on others)
printf("%zu (0x%zx)\n", size1, size1);
printf("%zu\n", ((size_t*)new bytes10[5])[-1]);
printf("%zu\n", ((size_t*)new bytes10[6])[-1]);
printf("%zu\n", ((size_t*)new bytes10[7])[-1]);
printf("%zu\n", ((size_t*)new bytes10[65536])[-1]);
return 0;
}
可能的输出(第一个值可能不同):
49 (0x31)
5
6
7
65536
附言在我看来,C++ 委员会应该考虑标准化对所有 new[]
分配的数组大小的访问,或者提供一种新类型的类似于 new
的运算符,它能够保证大小前缀。这有能力允许将 new[]
用于较低级别的代码(例如更简单的单指针不可变字符串)。