将用户输入数据存储在结构的动态数组中/显示所述数据。 C++
Storing user input data in a dynamic array of structures/ displaying said data. C++
所以对于我的项目,我必须...
- 使用以下格式创建结构:struct PERSON{string name;年龄;浮动 gpa;};
- 要求用户输入他们想要输入的记录数。
- 创建一个 PERSON 类型的动态数组 p 以能够保存第 2 部分中的所有记录
- 在第 2 部分中将数据读入数组 p
- 显示数组p
但是,每当我 运行 我的程序开始输入我的数据时,它不会让我输入多于一组的数据,输出似乎没有什么意义。
这是我的代码:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
struct PERSON
{
string name;
int age;
float gpa;
};
PERSON *p;
int main()
{
int count;
cout << "Please enter the number of records you wish to enter: ";
cin >> count;
p = new (nothrow) PERSON[count];
if (p == nullptr)
cout << "Error: memory could not be allocated";
for (int i = 0; i < count; i++)
{
cout << "Enter name, age, and gpa: ";
getline(cin, p[i].name);
cin >> p[i].age;
cin >> p[i].gpa;
cout << endl;
}cout << endl;
cout << "This is the content of array p: " << endl;
cout << right << setw(8) << "NAME" << setw(7) << "AGE" << setw(7) << "GPA" << endl;
cout << "--------------------------" << endl;
for (int i = 0; i < count; i++)
{
cout << p[i].name << " " << p[i].age << " " << p[i].gpa << endl;
}
return 0;
}
现在,当我将数据从文件复制到结构的动态数组时,这种格式似乎工作得很好,但我现在似乎无法让它工作,因为我正在处理用户输入。
以下是试用 运行 程序的结果:
Please enter the number of records you wish to enter: 3
Enter name, age, and gpa: Robert 21 2.1 // This is the info I tested
Enter name, age, and gpa:
Enter name, age, and gpa:
This is the content of array p:
NAME AGE GPA
--------------------------
-842150451 -4.31602e+008 //?
-842150451 -4.31602e+008 //?
-842150451 -4.31602e+008 //?
Press any key to continue . . .
我现在可能已经检查了代码两打,并且一直在寻找答案很长一段时间。任何 advice/analysis/comments 将不胜感激。
所以@AndyG 建议我将 getline(cin, p[i].name) 更改为 cin >> p[i].name ,这似乎解决了问题。谢谢!
不好意思给大家添麻烦了
std::getline() 函数是 "misbehaving" 与您的意图相关,因为(我认为)在流输入中留下了一个换行符排队。
您可以使用以下命令丢弃此类字符 cin.sync().
为什么会这样?因为 operator>> 不读取空格,但是 std::getline() 读取,所以当 cin >> 计数; 语句被执行并按下回车,新行字符(来自按下回车)留在流输入队列中,由 std::getline()[=30 自动读取=] 执行时。
还有其他函数可以完成此操作,也许更有消息的人可以告诉我们哪个是最佳选择。
这是一个固定版本:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
struct Person
{
string name;
int age;
float gpa;
};
int main()
{
cout << "Please enter the number of records you wish to enter: ";
int count;
cin >> count;
Person* p = new Person[ count ];
for ( int i = 0; i < count; i++ )
{
cin.sync(); // added this to discard unused characters from input queue
cout << "Enter name: ";
getline( cin, p[ i ].name );
cout << "Enter age: ";
cin >> p[ i ].age;
cout << "Enter gpa: ";
cin >> p[ i ].gpa;
cout << endl;
}cout << endl;
cout << "This is the content of array p: " << endl;
cout << right << setw( 8 ) << "NAME" << setw( 7 ) << "AGE" << setw( 7 ) << "GPA" << endl;
cout << "--------------------------" << endl;
for ( int i = 0; i < count; i++ )
{
cout << p[ i ].name << " " << p[ i ].age << " " << p[ i ].gpa << endl;
}
return 0;
}
备注:
您不需要检查 Person* p 是否为 nullptr,因为如果 new 运算符无法分配足够的内存,它将抛出 std::bad_alloc 异常。如果确实需要,请考虑将该内存分配包装在 try catch 块中。
问题
您的 getline(cin, p[i].name)
实际上是在同一行获取您的所有输入,您后面的 cin
语句将不匹配。
std::getline
应该保留用于将整行放入字符缓冲区或 std::string
,也就是说,它并不总是适合读取字符串的工具。
解决方案
相反,您只需将 getline(cin, p[i].name)
替换为 cin >> p[i].name
。
其他小改动
删除 nullptr
检查:
if (p == nullptr)
cout << "Error: memory could not be allocated";
因为在 C++ 中,如果 new
运算符分配失败,您将抛出异常。就像提到的 一样,您可以将其包装在 try catch 块中,尽管我个人只是将其完全删除。
#include <new>
// ...
Person* p = null;
try
{
p = new Person[count];
} catch(std::bad_alloc& ex)
{
cerr << "Unable to allocate memory for Person! Error msg: " << ex.what() << "\n";
return 1;
}
最后,别忘了delete[]
你分配给p
的内存:
// ...
delete[] p;
return 0;
} //end of int main()
即使您的 OS 肯定会为您清理内存,您仍然应该确保手动清理它。至少要好好练习。或者,您可以改用 std::array
或 std::vector
,这仍然会为您提供随机访问,就像您已经拥有的 PERSON
的 c 样式数组一样。
所以对于我的项目,我必须...
- 使用以下格式创建结构:struct PERSON{string name;年龄;浮动 gpa;};
- 要求用户输入他们想要输入的记录数。
- 创建一个 PERSON 类型的动态数组 p 以能够保存第 2 部分中的所有记录
- 在第 2 部分中将数据读入数组 p
- 显示数组p
但是,每当我 运行 我的程序开始输入我的数据时,它不会让我输入多于一组的数据,输出似乎没有什么意义。
这是我的代码:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
struct PERSON
{
string name;
int age;
float gpa;
};
PERSON *p;
int main()
{
int count;
cout << "Please enter the number of records you wish to enter: ";
cin >> count;
p = new (nothrow) PERSON[count];
if (p == nullptr)
cout << "Error: memory could not be allocated";
for (int i = 0; i < count; i++)
{
cout << "Enter name, age, and gpa: ";
getline(cin, p[i].name);
cin >> p[i].age;
cin >> p[i].gpa;
cout << endl;
}cout << endl;
cout << "This is the content of array p: " << endl;
cout << right << setw(8) << "NAME" << setw(7) << "AGE" << setw(7) << "GPA" << endl;
cout << "--------------------------" << endl;
for (int i = 0; i < count; i++)
{
cout << p[i].name << " " << p[i].age << " " << p[i].gpa << endl;
}
return 0;
}
现在,当我将数据从文件复制到结构的动态数组时,这种格式似乎工作得很好,但我现在似乎无法让它工作,因为我正在处理用户输入。
以下是试用 运行 程序的结果:
Please enter the number of records you wish to enter: 3
Enter name, age, and gpa: Robert 21 2.1 // This is the info I tested
Enter name, age, and gpa:
Enter name, age, and gpa:
This is the content of array p:
NAME AGE GPA
--------------------------
-842150451 -4.31602e+008 //?
-842150451 -4.31602e+008 //?
-842150451 -4.31602e+008 //?
Press any key to continue . . .
我现在可能已经检查了代码两打,并且一直在寻找答案很长一段时间。任何 advice/analysis/comments 将不胜感激。
所以@AndyG 建议我将 getline(cin, p[i].name) 更改为 cin >> p[i].name ,这似乎解决了问题。谢谢!
不好意思给大家添麻烦了
std::getline() 函数是 "misbehaving" 与您的意图相关,因为(我认为)在流输入中留下了一个换行符排队。
您可以使用以下命令丢弃此类字符 cin.sync().
为什么会这样?因为 operator>> 不读取空格,但是 std::getline() 读取,所以当 cin >> 计数; 语句被执行并按下回车,新行字符(来自按下回车)留在流输入队列中,由 std::getline()[=30 自动读取=] 执行时。
还有其他函数可以完成此操作,也许更有消息的人可以告诉我们哪个是最佳选择。
这是一个固定版本:
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
struct Person
{
string name;
int age;
float gpa;
};
int main()
{
cout << "Please enter the number of records you wish to enter: ";
int count;
cin >> count;
Person* p = new Person[ count ];
for ( int i = 0; i < count; i++ )
{
cin.sync(); // added this to discard unused characters from input queue
cout << "Enter name: ";
getline( cin, p[ i ].name );
cout << "Enter age: ";
cin >> p[ i ].age;
cout << "Enter gpa: ";
cin >> p[ i ].gpa;
cout << endl;
}cout << endl;
cout << "This is the content of array p: " << endl;
cout << right << setw( 8 ) << "NAME" << setw( 7 ) << "AGE" << setw( 7 ) << "GPA" << endl;
cout << "--------------------------" << endl;
for ( int i = 0; i < count; i++ )
{
cout << p[ i ].name << " " << p[ i ].age << " " << p[ i ].gpa << endl;
}
return 0;
}
备注: 您不需要检查 Person* p 是否为 nullptr,因为如果 new 运算符无法分配足够的内存,它将抛出 std::bad_alloc 异常。如果确实需要,请考虑将该内存分配包装在 try catch 块中。
问题
您的 getline(cin, p[i].name)
实际上是在同一行获取您的所有输入,您后面的 cin
语句将不匹配。
std::getline
应该保留用于将整行放入字符缓冲区或 std::string
,也就是说,它并不总是适合读取字符串的工具。
解决方案
相反,您只需将 getline(cin, p[i].name)
替换为 cin >> p[i].name
。
其他小改动
删除 nullptr
检查:
if (p == nullptr)
cout << "Error: memory could not be allocated";
因为在 C++ 中,如果 new
运算符分配失败,您将抛出异常。就像提到的
#include <new>
// ...
Person* p = null;
try
{
p = new Person[count];
} catch(std::bad_alloc& ex)
{
cerr << "Unable to allocate memory for Person! Error msg: " << ex.what() << "\n";
return 1;
}
最后,别忘了delete[]
你分配给p
的内存:
// ...
delete[] p;
return 0;
} //end of int main()
即使您的 OS 肯定会为您清理内存,您仍然应该确保手动清理它。至少要好好练习。或者,您可以改用 std::array
或 std::vector
,这仍然会为您提供随机访问,就像您已经拥有的 PERSON
的 c 样式数组一样。