Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

C++ - Динамический символьный массив

86K
09 октября 2014 года
parkito
3 / / 19.08.2014
Здравствуйте, помогите пожалуйста разобраться со следующим вопросом.
Мне нужно чтобы все символы из фала или введенные пользователем поместились в массив. Я думаю, что для этого нужно использовать динамический массив. Но каким образом придумать не могу. Как - то нужно сосчитать количество символов --> выделить память --> инициализировать массив. В голову приходит
Код:
#include<iostream>
#include<cstdlib>
 
int main()
{
    char *arr;
    int size;
    setlocale(LC_ALL, "Russian");
    std::cout<<"Введите размер массива :"<<std::endl;
    std::cin>>size;
    arr = new char[size];
    std::cout<<"Заполните массив :"<<std::endl;
    for (int i = 0; i < size; i++)
        std::cin>>arr[i];
    std::cout<<std::endl;
    for (int i = 0; i < size; i++)
        std::cout<<" "<<arr[i];
    delete [] arr;
}[/CPP]

Но количество элементов может быть сверх большим или малым.
[code]
#include<iostream>
#include<cstdlib>
 
int main()
{
    char *arr;
    int size;
    setlocale(LC_ALL, "Russian");
    std::cout<<"Введите размер массива :"<<std::endl;
    std::cin>>size;
    arr = new char[size];
    std::cout<<"Заполните массив :"<<std::endl;
    for (int i = 0; i < size; i++)
        std::cin>>arr[i];
    std::cout<<std::endl;
    for (int i = 0; i < size; i++)
        std::cout<<" "<<arr[i];
    delete [] arr;
}
Но количество элементов может быть сверх большим или малым.
  • Ну и в чем проблемы? от myCrack, 10 октября 2014 года
86K
10 октября 2014 года
parkito
3 / / 19.08.2014
Не понимаю, как сделать это.
446
10 октября 2014 года
Meander
487 / / 04.09.2011
Перед выделением памяти под массив надо проверить size на попадание в диапазон допустимых значений. Если попадает - Ваш код, иначе - сообщение о некорректности введенного числа символов. Это можно реализовать с помощью условного оператора if () else.
Вот немного о сложных операторах C++
326
10 октября 2014 года
sadovoya
757 / / 19.11.2005
Стандартный std::vector использовать нельзя? Просто вариантов много, вплоть до написания класса. Именно низкоуровневые "сырые" массивы нужно?

Вот чтение файла в вектор:


Код:
#include <cstdio>
#include <vector>

int main() {

    FILE *pf=fopen("1.txt","r");

    char ch;
    std::vector<char> vec;
    while(EOF != fscanf (pf, "%c", &ch) ) {
        vec.push_back( ch );
    }

    fclose(pf);

    return 0;
}
Обращаться к элементу можно подобно массивам: например, vec[0] - начальный элемент. А число элементов = vec.size()
392
10 октября 2014 года
cronya
421 / / 03.01.2009
Для файла можно сделать считывание блоков определенного размера
Выполнена с помощью динамической структуры(двусвязного списка), состоящая из узлов
Код:
#include <iostream>

using std::endl;
using std::cout;
using std::system;

class List
{
private:
    char* word;
public:
    List(){}
    ~List(){ delete[] word; }
    void setValue(char* ptr, size_t size){ word = new char[size]; strcpy_s(word, size, ptr); }
    char* getValue(){ return word;}
    List* next, *prev;

}*Head, *Tail;

void Add(char* ptr, size_t size);
void Out();

int main()
{
    FILE* m_file = NULL;
    errno_t err = fopen_s(&m_file, "myText.txt", "r");
    size_t size_block = 2; 
   
    if (err == 0)
    {
        while (!feof(m_file))
        {
            char* line = new char[size_block];
            fgets(line, size_block, m_file);
            if (strlen(line) < size_block)
            {
                cout << line << endl;
                Add(line, size_block);
            }
            delete[] line;         
        }
        Out();
        fclose(m_file);
    }
    else
    {
        cout << "Can't open the file!" << endl;
    }
    cout << endl;
    system("pause");
    return 0;
}

void Add(char* m_Line, size_t size)
{
    List* ptr = NULL, *tmp = NULL;
    if (Head == NULL)
    {
        ptr = new List();
        ptr->setValue(m_Line, size);
        ptr->next = ptr->prev = NULL;
        Head = Tail = ptr;
    }
    else
    {
        tmp = Tail;
        ptr = new List();
        ptr->setValue(m_Line, size);
        tmp->next = ptr;
        ptr->prev = tmp;
        Tail = ptr;
        ptr->next = NULL;
       
    }
}

void Out()
{
    cout << endl << "Your Text: " << endl;
    List* ptr = Head;
    while (ptr != NULL)
    {
        cout << ptr->getValue();
        ptr = ptr->next;
    }
}
файл содержит

 
Код:
Hello World! This is a nice day! Really gyus, nice day!
Have a nice day!
Результат

Код:
H
e
l
l
o

W
o
r
l
d
!

T
h
i
s

i
s

a

n
i
c
e

d
a
y
!

R
e
a
l
l
y

g
y
u
s
,

n
i
c
e

d
a
y
!


H
a
v
e

a

n
i
c
e

d
a
y
!

Your Text:
Hello World! This is a nice day! Really gyus, nice day!
Have a nice day!
Для продолжения нажмите любую клавишу . . .
326
10 октября 2014 года
sadovoya
757 / / 19.11.2005
Можно с потоками и итераторами STL. Этот пример с буферизацией.

Код:
#include <fstream>
#include <iterator>
#include <vector>

int main() {

    std::ifstream ifs("1.txt");
    if (!ifs.is_open())
        return -1000;

    std::istreambuf_iterator<char> i0(ifs), il;
    std::vector<char> vec(i0,il);

    ifs.close();

    return 0;
}
Обработка исключений разумеется нужна, для краткости опустил.
326
11 октября 2014 года
sadovoya
757 / / 19.11.2005
Для случая ввода с клавиатуры:

Код:
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

int main() {
    std::vector<char> v;
    /*
        В этом примере stl-алгоритм copy перемещает символы из стандартного ввода в
    вектор, но, так как вектор предварительно не размещён в памяти, используется
    итератор вставки, чтобы вставить в вектор символы один за другим.
    */

    std::copy(std::istream_iterator<char>(std::cin),
              std::istream_iterator<char>(), //end-of-stream (конец-потока) итератор,
              //который создаётся конструктором без параметров.
              std::inserter(v, v.end()));

    //проверка - вывод в консоль вектора
    std::copy(v.begin(), v.end(), std::ostream_iterator<char>(std::cout));

    return 0;
}

Для окончания ввода надо нажать Ctrl-Z (в Windows). Лучше пользователя об этом предупредить.
Пробелы и т.п. whitespace игнорируются в этом примере. Это можно отключить манипуляторами потока.
Или использовать буфиризир. std::istreambuf_iterator, что вдобавок и эффективней. Т.е. заменить первый copy на такой:

 
Код:
std::copy(std::istreambuf_iterator<char>(std::cin),
              std::istreambuf_iterator<char>(),
              std::inserter(v, v.end()));
А можно и еще проще:

Код:
#include <vector>
#include <iterator>
#include <iostream>

int main() {
     std::istreambuf_iterator<char> i0(std::cin), end_of_stream_It;
     std::vector<char> v(i0, end_of_stream_It);
     //проверка:
     for( std::size_t i = 0; i < v.size(); ++i)
        std::cout << v[i];
     return 0;
}

Признак конца ввода можно сделать и по условленному символу при желании.
326
12 октября 2014 года
sadovoya
757 / / 19.11.2005
Можно заранее определять размер файла. Тут используем обычный массив и блок во весь файл:

Код:
#include <fstream>
#include <iostream>

//с использованием материала: C++ Language Tutorial от cplusplus.com

int main() {
    std::ifstream file ("1.txt", std::ios::in|std::ios::binary|std::ios::ate);
    if (file.is_open()) {
        std::ifstream::pos_type size;
        char * memblock;
        size = file.tellg();
        //нужно добавить обработку ошибок
        memblock = new char [size];
        file.seekg (0, std::ios::beg);
        file.read (memblock, size);
        file.close();
        std::cout << "the complete file content is in memory" << std::endl
                  << "its content: " << std::endl << memblock << std::endl;
        delete[] memblock;
    } else std::cout << "Unable to open file";

    return 0;
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог