因此,对于我的第二个C ++类,我们必须编写一个程序,创建一个包含5个结构和一个类的数组。在struct中是一个int,一个由5个双精度组成的数组,以及一个由81个元素组成的字符数组。当然,其中一个功能是从用户那里获取信息。该函数称为setStructData():
void Prog1Class::setStructData()
{
for(int i=0; i<5; i++)
{
cout<<"input an integer, five doubles, and a character array up to 80 characters."<<endl;
cin>>StructArray[i].m_iVal;
for(int j=0; j<5; j++)
{
cin>>StructArray[i].m_dArray[j];
}
cin.ignore('\n');
cin>>StructArray[i].m_sLine;
cout<<"String entered: "<<StructArray[i].m_sLine<<endl;
}
}
下一个函数getStructData()是将结构数组和cout中的每个元素都带给用户一行上的元素,下一行的下一个元素依此类推,直到数组上的所有5个元素为止显示。这就是我所拥有的:
void Prog1Class::getStructData(int index, Prog1Struct *struct_ptr)
{
struct_ptr=&StructArray[index];
cout<<struct_ptr->m_iVal<<" ";
for(int i=0; i<5; i++)
{
cout<<struct_ptr->m_dArray[i]<<" ";
}
cout<<struct_ptr->m_sLine<<endl;
}
当我通过键盘输入(输入结构阵列中的每个元素在一行上输入)时,此程序有效,但我的教授给了我们一个文本文件test.txt,我们应该使用它看起来像这个(字符数组与其余部分不同):
10 1.2 2.3 3.4 4.5 5.6
Test string 1
20 2.3 3.4 4.5 5.6 6.7
Test string 2
30 3.4 4.5 5.6 6.7 7.8
Test string 3
40 4.5 5.6 6.7 7.8 8.9
Test string 4
50 5.6 6.7 7.8 8.9 9.1
Test string 5
它的文本文件正在搞砸我的程序,因为它在完全不同的行上有字符数组。我相信它只是我输入数据的方式,但我不知道如何修复它。有人能帮助我吗? 当我使用I / O重定向来使用test.txt文件来输入我的数据时,我得到它输出第一行(没有字符串),然后其余的是一堆疯狂的垃圾。请帮助我!d
答案 0 :(得分:1)
首先,您应始终验证您的输入是否成功!也就是说,在读取流仍然处于良好状态后总是检查,例如:
if (!(std::cin >> StructArray[i].m_dArray[j])) {
std::cout << "failed to read double value\n";
}
接下来,当将格式化输入用于字符数组时,总是首先设置宽度!在没有设置宽度的情况下,你可以在你的程序中创建一个可以被黑客入侵的攻击向量(这可能对你的家庭作业无关紧要,但是一旦你创建了专业软件,它就非常重要了):
if (!(std::cin >> std::setw(sizeof(StructArray[i].m_sLine)) >> StructArray[i].m_sLine)) {
std::cout << "failed to read string\n";
}
但请注意,格式化的输入始终在第一个空白字符处停止读取。来自文件的输入似乎包含Test string
形式的字符串,这将导致Test
被读取并且string
被留在流中以供下一个要读取的项目使用。您可以使用getline()
读取所有输入,直到行尾。但是,由于所有格式化的输入操作都倾向于留下空格字符,例如数字之后的换行符,因此在流中您应该读取前导空格。例如,您可以使用
if (!(std::cin >> std::ws).getline(StructArray[i].m_sLine, sizeof(StructArray[i].m_sLine)) {
...
}
就个人而言,我更倾向于使用std::getline(std::cin >> std::ws, str)
,第二个参数类型为std::string
,但似乎您的赋值不允许使用std::string
类。 操纵器 std::ws
读取所有前导空格。