Что я делаю не так с функцией ввода?

0

Итак, для моего второго класса 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() состоит в том, чтобы каждый элемент массива structs и 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;
}

Эта программа работает, когда я вводил ввод с клавиатуры (который вводит для каждого элемента в structarray на одной строке), но мой профессор дал нам текстовый файл 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

Его текстовый файл, который закручивает мою программу, потому что у нее есть массив символов на совершенно другой строке. Я считаю, что это именно то, как я вводил данные, но я не знаю, как это исправить. Может ли кто-нибудь помочь мне? Когда я использую перенаправление ввода/вывода для использования файла test.txt для ввода моих данных, я получаю его для вывода первой строки (без строки), а затем остальная часть - сумасшедший барахло. Пожалуйста, помогите мне!

Теги:
arrays
struct
input

1 ответ

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 class. Манипулятор std::ws читает все ведущие пробелы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню