У меня проблемы с получением 3 строк от пользователя с помощью cin.getline () и использованием массива указателей для их хранения - PullRequest
0 голосов
/ 25 февраля 2019

Я получаю исключение на моем cin.getline.Я новичок в C ++, извините, если код действительно плохой.

Функция GetInput должна выполнять следующие действия: Эта функция принимает три строки введенного пользователем текста и сохраняет введенные строки в виде трех отдельных строк.Используйте массив указателей для хранения строк.Функция должна попросить пользователя ввести три строки данных.Функция будет хранить информацию в массиве указателей.(Cin.getline ()).Должен быть размещен внутри GetInput и должен иметь точно правильный размер для каждой строки.

int main() {
    char* str[2];
    GetInput(str); 

}

void GetInput(char* ptr[]) {
    for (int i = 0; i < 3; i++) {
        cout << "Enter a string: ";
        cin.getline(ptr[i], strlen(ptr[i]), '\n');
    }
}

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

К сожалению, назначение требует указателей, так как это было бы легко использовать std::vector<std::string>.Если вам нужно использовать указатели, используйте умные указатели, такие как std::unique_ptr.Они будут delete/delete[] необработанным указателем, которым они владеют, когда они будут уничтожены (выйдут за пределы области видимости) и тем самым помогут предотвратить утечки памяти.Таким образом, используя массивы и указатели, это можно сделать одним из способов.

#include <iostream>
#include <array>    // std::array
#include <cstring>  // std::memcpy
#include <memory>   // std::unique_ptr

constexpr size_t max_line_length = 256;

// convenience alias
using CStrPtr = std::unique_ptr<char[]>;

void GetInput(std::array<CStrPtr, 3>& ptrs) {
    char buf[max_line_length]; // temporary buffer when reading a line

    // loop through the 3 pointers in the array
    for(CStrPtr& cptr : ptrs) {
        std::cout << "Enter a string: ";
        std::cin.getline(buf, max_line_length);
        size_t len = std::strlen(buf) + 1; // +1 to make place for the string terminator, '\0'
        // create a new pointer to a char[] with space for the string
        // and assign it to the pointer in the array
        cptr = std::make_unique<char[]>(len);
        // copy the string in buf into the space the raw pointer held by cptr now points to
        std::memcpy(cptr.get(), buf, len);
    }
}

int main() {
    std::array<CStrPtr, 3> strs;
    GetInput(strs);
    for(const CStrPtr& cptr : strs) {
        std::cout << cptr.get() << "\n";
    }
}

Если вам не разрешено использовать стандартные интеллектуальные указатели, вы можете создать свой собственный интеллектуальный указатель или простую строкуучебный класс.Вот версия выше, но с простым классом строки:

#include <iostream>
#include <array>     // std::array
#include <cstring>   // std::strlen
#include <algorithm> // std::copy

constexpr size_t max_line_length = 256;

class cstring {
    char* m_mem; // the precious pointer
public:
    cstring() : // default constructor
        m_mem(new char[1]) // make place for the string terminator
    {
        m_mem[0] = '\0'; // the string terminator
    }
    cstring(char const* buf) : // converting constructor
        m_mem{}
    {
        // allocate memory
        size_t len = std::strlen(buf) + 1;
        m_mem = new char[len];
        // and copy buf to m_mem
        std::copy(buf, buf+len, m_mem);
    }
    cstring(const cstring& o) : // copy ctor
        cstring(o.m_mem) // delegate to converting ctor
    {}
    cstring(cstring&& o) : // move ctor
        // copy the pointer from o and set o:s pointer to nullptr
        m_mem(std::exchange(o.m_mem, nullptr))
    {}
    cstring& operator=(const cstring& o) { // copy assignment
        *this = cstring(o); // using copy ctor + move assignment
        return *this;
    }
    cstring& operator=(cstring&& o) { // move assignment
        // swap pointers: let o destroy our old pointer for us
        std::swap(m_mem, o.m_mem);
        return *this;
    }
    ~cstring() { delete[] m_mem; } // destructor

    // user-defined conversions
    operator char const* () const { return m_mem; }
    operator char* () { return m_mem; }
};

void GetInput(std::array<cstring, 3>& ptrs) {
    char buf[max_line_length]; // temporary buffer when reading a line

    // loop through the 3 pointers in the array
    for(cstring& cptr : ptrs) {
        std::cout << "Enter a string: ";
        std::cin.getline(buf, max_line_length);
        // create a new cstring and assign it to the cstring in the array
        cptr = cstring(buf);
    }
}

int main() {
    std::array<cstring, 3> strs;
    GetInput(strs);
    for(const cstring& cptr : strs) {
        // cptr will here use the user-defined conversion to "char const*"
        // for which there's a standard operator<< defined
        std::cout << cptr << "\n";
    }
}
0 голосов
/ 25 февраля 2019
#include <iostream>
#include <string>

using namespace std;

void getLine(string ptr[]) {
    for (int index = 0; index < 3; ++index) {
        string line;
        getline(cin, line);
        ptr[index] = line;
    }
}

int main() {
    string ptr[3];
    getLine(ptr);

    for (int index = 0; index < 3; ++index) {
        cout << ptr[index] << endl;
    }
}

В вашем коде было несколько ошибок.Во-первых, вы не выделили достаточно места для вашего массива.Ваша длина должна быть длиной массива, а не индексом последнего элемента.Так что, если это 3 строки, это [3].

Далее, я бы не использовал char *, но вместо этого использовал бы строковый класс.См. Мой код.

В-третьих, ваши strlen вещи - ну, у вас есть массив указателей на случайные места в памяти, или, возможно, массив нулевых указателей.В любом случае, это неправильно.

Вы МОЖЕТЕ сделать что-то вроде этого:

char myStrings[3][1000];

А затем в своей getline используйте 1000 в качестве максимальной длины (возможно, 999 - я неиспользуйте getline в той форме, которую вы сделали).Это позволило бы выделить 3 символьных массива по 1000 байт каждый.

Но обычная вещь strlen просто не сработает, потому что вы не начинаете с каких-либо строк, из которых стрельба.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...