Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30

Захват аргументов командной строки в динамический массив

15.03.2023, 01:50. Показов 936. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не могу реализовать захват данных, вводимых с ком. строки и запихнуть в массив указателей на класс. Вывода после всего прогона нет. Проверяю значение *text в конструкторе, оно есть. После, уже не выводит ничего. Есть, кто подскажет? Перерыл уже кучу инфы.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<iostream>
#include<cstring>
 
using namespace std;
const int lim = 100;
 
class Str
{
private:
  char *text = NULL;
  int len = 0;
public:
    Str ()
  {
    text = NULL;
    len = 0;
  }
   ~Str ()
  {
    delete text;
  }
 
  Str (char &a, int l)
  {
    delete text;
    len = l;
    ap = 't';
    text = new char[len];
    strcpy (text, &a);
    text[len] = '\0';
    cout << "constr preob" << endl;
    cout << endl << text << a << endl;//вот здесь еще работает (правда, а-выводит только один символ)
 
  }
 
  void getd ()
  {
    cout << text << endl;
  }
 
};              //end of class
 
int
main (int argc, char *argv[])
{
  Str **arr;
  arr = new Str *[20];
 
  for (int r = 1; r <= argc; r++)
    {
      int len = strlen (argv[r]) + 1;
      arr[r - 1] = new Str (*argv[r], len);
    }
  for (int y = 0; y <= argc - 1; y++)
    {
      (arr[y])->getd ();
    }
}
}
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
15.03.2023, 01:50
Ответы с готовыми решениями:

Если количество строк и столбцов массива задаётся с помощью аргументов командной строки, то это динамический массив?
Если количество строк и столбцов массива задаётся с помощью аргументов командной строки (т. е. они не известны заранее), то это...

Напишите программу, которая считывает из аргументов командной строки массив слов
Напишите программу, которая считывает из аргументов командной строки массив слов и сортирует этот массив по двум критериям. Программа...

Проверка наличия параметра в командной строке // Проверка аргументов командной строки на наличие
Всем доброго времени суток. Возникла необходимость сделать небольшую защиту клиента, на проверку наличия параметра в CMD, если он есть...

17
Модератор
 Аватар для long399
2882 / 1836 / 933
Регистрация: 16.10.2013
Сообщений: 5,240
Записей в блоге: 15
15.03.2023, 05:09
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<iostream>
#include<cstring>
 
using namespace std;
const int lim = 100;
 
class Str
{
private:
  char *text = NULL;
  int len = 0;
public:
    Str ()
  {
    text = NULL;
    len = 0;
  }
   ~Str ()
  {
    delete text;
  }
 
  Str (char *a, int l)
  {
    delete text;
    len = l;
    //ap = 't';
    text = new char[len];
    strcpy (text, a);
    text[len] = '\0';
    cout << "constr preob" << endl;
    cout << endl << text << a << endl;//вот здесь еще работает (правда, а-выводит только один символ)
 
  }
 
  void getd ()
  {
    cout << text << endl;
  }
 
};              //end of class
 
int main (int argc, char *argv[])
{
  Str **arr;
  arr = new Str *[20];
 
  for (int r = 1; r <= argc; r++)
    {
      int len = strlen (argv[r]) + 1;
      arr[r - 1] = new Str (argv[r], len);
    }
  for (int y = 0; y <= argc - 1; y++)
    {
      (arr[y])->getd ();
    }
}
0
Модератор
Эксперт С++
 Аватар для zss
13769 / 10962 / 6491
Регистрация: 18.12.2011
Сообщений: 29,238
15.03.2023, 08:28
Нарушено правило трех.
Распространенные ошибки
Нет копиконструктора и operator=
2
Заблокирован
15.03.2023, 11:22
Цитата Сообщение от zss Посмотреть сообщение
Нарушено правило трех.
В том коде нарушен здравый смысл.
1
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
16.03.2023, 00:21  [ТС]
добавил, изучив по ссылке, спасибо! Но я по прежнему в беде... Где-то теряется указатель. В коде прокомментил, где данные еще выдает.
1)
В строке 142 выдает необработ. исключение:
"Необработанное исключение по адресу 0x00007FF7242221F3 в 1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x0000000000000000", ну, мне кажется, это логично, потому что на этапе отладки я не ввожу аргументы в ком. строку, поэтому там 0.
2)
при запуске без отладки выдает:
(процесс 6040) завершил работу с кодом -1073741819. (вот это про указатель как раз я так понял). Путем затемнения кода понял, что проблема в корявой моей инициализации нового элемента. Это штукень в строке 38, которую я запускаю из строки 143. Хотя, может, оно мне выдает это, потому что, опять же, в запуске без отладки я не ввожу переменные.

Хочу всего лишь захватить слова из командной строки, запихнуть их динамически в массив объектов класса через конструктор, чтобы потом с ними можно было играться. Это вводные...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include<iostream>
#include<cstring>
 
using namespace std;
 
class Str
{
private:
    char* text=NULL;
    int len=0;
    string ap = "t";
public:
    Str(){}
    Str(Str&& a)noexcept :text(nullptr), len(0)
    {
        text = a.text; len = a.len;
        a.text = NULL; a.len = 0;
        cout << "конструктор копирования перемещ.";
    }
 
    Str& operator=(Str&& a)noexcept
    { 
        if (this != &a)
        {
            delete text;
            text = a.text; len = a.len;
            a.text = NULL; a.len = 0;
        }
            return *this;
            cout << "оператор присваивания перемещ.";
    }
 
 
    ~Str() { delete text; }
 
    Str(char& a, int l)
    {
            delete text;
            len = l;
            ap = 't';
            text = new char[len]; strcpy(text, &a); text[len] = '\0'; 
            cout << "конструктор инициализации с аргументом строки и длины строки" << endl;
 //           cout <<endl<< text << a<<endl;// выдает значения
    }
 
};//end of class
 
 
int main(int argc, char* argv[])
{
    setlocale(LC_ALL, "Russian");
    int i = 0;
    Str** arr;
    arr = new Str*[4];
 
    for (int r = 1; r <= argc; r++)
    {
        int len = strlen(argv[r]) + 1;
        arr[r-1] = new Str(*argv[r], len);
        arr[r-1]->getd();//здесь тоже выдает значения
    }
   arr[r-1]->getd();//здесь уже выдает значения
 
    for (int y = 0; y < argc; y++) { delete arr[y]; } delete[] arr;
}
0
Заблокирован
16.03.2023, 00:23
Цитата Сообщение от Valdemarych Посмотреть сообщение
Хочу всего лишь захватить слова из командной строки, запихнуть их динамически в массив объектов класса через конструктор, чтобы потом с ними можно было играться. Это вводные...
Что мешает просто передать указатель и количество?
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
16.03.2023, 00:39  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Что мешает просто передать указатель и количество?
обычно мешают руки.

Если я правильно понял:
указатель на строку из аргументария ком. строки.
количество = argc - 1 (так как один из них - адрес)
Передать в конструктор? если да, то здесь пробел у меня.
Если в мой массив, то значение argc на этапе компиляции не является константой. массив просит константу.

Добавлено через 2 минуты
Цитата Сообщение от Valdemarych Посмотреть сообщение
обычно мешают руки.
Если я правильно понял:
указатель на строку из аргументария ком. строки.
количество = argc - 1 (так как один из них - адрес)
Передать в конструктор? если да, то здесь пробел у меня.
Если в мой массив, то значение argc на этапе компиляции не является константой. массив просит константу.
знать бы хоть, куда смотреть, где ознакомиться. ночь длинная...
0
Заблокирован
16.03.2023, 00:40
argc = 1 + количество слов (словоформ разделенных пробелом)
argv[i] - сами эти слова.
i [1, argc)
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
16.03.2023, 00:43  [ТС]
Цитата Сообщение от Valdemarych Посмотреть сообщение
cout << "конструктор инициализации с аргументом строки и длины строки" << endl;
при том, что этот конструктор отрабатывает, кстати (зашил туда cout, чтобы хоть как-то проверить)
0
Заблокирован
16.03.2023, 00:44
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Test{
    vector<string> words;
    Test(char **w, int c){
        for (int i = 0; i < c; ++i)
            words.push_back(w[i]);
    }
    void Print(){
        for (const auto & word : words)
            cout << word << ' ';
    }
};
int main(int argc, char** argv){
    Test test(argv+1, argc-1);
    test.Print();
}
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
16.03.2023, 01:14  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
argc = 1 + количество слов (словоформ разделенных пробелом)
argv[i] - сами эти слова.
i [1, argc)
немного не понял здесь:
argc = 1 + количество слов (словоформ разделенных пробелом) - это понятно
argv[i] - сами эти слова. тоже понятно
i [1, argc) - вот здесь в аргументах два инта получается. Куда это передавать не уверен, и где сама строка.

ща попробую сформулировать. Количество строк и их размер до их ввода неизвестны. А памяти хочу выделить ровняк.
опишу мою приблуду:
Str** arr; // объявляю указатель на указатель (указатель на указатели на строку)
arr = new Str*[argc-1];//выделяю для него память, в размере argc-1 указателей на объект Str (в Arr будут эти указатели храниться, как в массиве указателей) Указатели использую, чтобы выделать динамически память.

for (int r = 1; r <= argc; r++) //цикл наполнения моего массива указателей на Str данными из argv - массива указателей на Char. Цикл, завершается, когда сравняется с количеством строк, т.е. argc (первую пропускаем, как адрес)
{
int len = strlen(argv[r]) + 1; //вычисляем длину каждой строки для передачи в конструктор(без этой цифры не выделить точный размер). "+1" для терминатора оставляем, так как strlen() его не считает за человека
arr[r-1] = new Str(*argv[r], len);//выделяем память под каждый Str указатель нашего массива и заодно создаем объект путем конструктора инициализации (принимает строку и размер и у себя тоже выделяет память под строку).
}
такая вот идея. Потом все получается, и я иду счастливый спать.

Добавлено через 4 минуты
Цитата Сообщение от SmallEvil Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Test{
    vector<string> words;
    Test(char **w, int c){
        for (int i = 0; i < c; ++i)
            words.push_back(w[i]);
    }
    void Print(){
        for (const auto & word : words)
            cout << word << ' ';
    }
};
int main(int argc, char** argv){
    Test test(argv+1, argc-1);
    test.Print();
}
вектор, к сожалению, нельзя. Как и стринг. по условию. Но кстати, себе сохраню, спасибо большое. Эффективная штука.
0
Заблокирован
16.03.2023, 02:02
Цитата Сообщение от Valdemarych Посмотреть сообщение
i [1, argc) - вот здесь в аргументах два инта получается. Куда это передавать не уверен, и где сама строка.
Это называется дипазаон, или интервал.
Означает что i принимает значение из интервала от 1(включительно) до argc (исключительно).
argv[0] - это параметр запуска вашего приложения.

Цитата Сообщение от Valdemarych Посмотреть сообщение
вектор, к сожалению, нельзя. Как и стринг. по условию.
Да легко, ничего не меняется, ничего.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <cstring>
 
using namespace std;
struct Test{
    char** words;
    int count;
    Test(const char* const* w, int c){
        count = 0;
        words = new char*[c];
        for (int i = 0; i < c; ++i, ++count)
            words[i] = strcpy(new char[strlen(w[i])+1], w[i]);
    }
    void Print(){
        for (int i = 0; i < count; ++i)
            cout << words[i] << ' ';
    }
    ~Test(){
        for (int i = 0; i < count; ++i)
            delete [] words[i];
        delete [] words;
    }
    Test(const Test&) = delete;
    Test& operator=(const Test&) = delete;
};
int main(int argc, char** argv){
    Test test(argv, argc);
    test.Print();
}
Добавлено через 1 минуту
Вопрос, зачем все это ?
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
17.03.2023, 01:25  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Вопрос, зачем все это ?
я задачу такую получил.

в целом понятно, как работает.
И еще один момент, подскажите, пожалуйста: Как сделать массив указателей на объекты класса именно в мэин (чтобы потом с ними играться). С той же идеей: захват из командной строки, запуск конструктора и создание объекта класса (выделение памяти и т.д.) и присваивание объекта какому-то указателю в этом массиве.

как раз пытался данный механизм для этого приспособить.

C++
1
2
3
4
5
6
7
8
9
10
    Str** arr;
    arr = new Str*[4];
 
    for (int r = 1; r <= argc; r++)
    {
        int len = strlen(argv[r]) + 1;
        arr[r-1] = new Str(*argv[r], len);
// вот здесь он выдает значения
    }
// здесь уже ничего не выдает.
У меня получается, что после окончания For, сам массив arr[] пустой, как бубен. Я и по ссылке, и по указателю пытался передать в конструктор. Я читал, что указатели на переменные, объявленные локально, после окончания функции бесполезны. Ну ок. Я убрал, к примеру: int len = из тела цикла. Объявил раньше, здесь только инициализирую. Все равно... Возможно, для моего навыка слишком сложная конструкция, но я уже назвался груздем...
0
Заблокирован
17.03.2023, 01:31
Цитата Сообщение от Valdemarych Посмотреть сообщение
подскажите, пожалуйста
Я бы с радостью, но моя не понимать что вы хотите.
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
17.03.2023, 01:33  [ТС]
только что прописал все это дело без цикла:

C++
1
2
3
4
5
6
7
8
9
10
11
    Str** argr;
    argr = new Str* [argc - 1];
 
    len = strlen(argv[1])+1;
    argr[0] = new Str(*argv[1],len);
 
    len = strlen(argv[2]) + 1;
    argr[1] = new Str(*argv[2], len);
 
    len = strlen(argv[3]) + 1;
    argr[2] = new Str(*argv[3], len);
все ок выводит! Но это прям как-то...
0
Заблокирован
17.03.2023, 01:41
Valdemarych, так а что такое Str ?

Цитата Сообщение от Valdemarych Посмотреть сообщение
for (int r = 1; r <= argc; r++)
У вас же выход за границы массива.
r < argc
Цитата Сообщение от Valdemarych Посмотреть сообщение
*argv[r]
Разыменовывать ничего не нужно.
0
0 / 0 / 0
Регистрация: 04.03.2020
Сообщений: 30
17.03.2023, 02:02  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <cstring>
using namespace std;
struct Test{
    char** words;
    int count;
    Test(const char* const* w, int c){
        count = 0;
        words = new char*[c];
        for (int i = 0; i < c; ++i, ++count)
            words[i] = strcpy(new char[strlen(w[i])+1], w[i]);
    }
    void Print(){
        for (int i = 0; i < count; ++i)
            cout << words[i] << ' ';
    }
    ~Test(){
        for (int i = 0; i < count; ++i)
            delete [] words[i];
        delete [] words;
    }
    Test(const Test&) = delete;
    Test& operator=(const Test&) = delete;
};
int main(int argc, char** argv){
    Test test(argv, argc);
    test.Print();
}
вот то же самое. только чтобы в конструктор кидался не массив ком. строки, а по очереди каждый элемент массива из командной строки(строка) для создания в итоге массива указателей на объекты класса. Массив в мэйне. Он хранит указатели на объекты класса. Объекты класса хранят каждый по строчке, захваченной из командной строки. Ниже схему зафигачил.

класс:

Private:
указатель на строку Char
интовая длина строки


Мэйн

Массив указателей на объекты класса, который выше

Добавлено через 21 минуту
Цитата Сообщение от SmallEvil Посмотреть сообщение
for (int r = 1; r <= argc; r++)
Точно!!! оказывается argv=argc+1
У Лафоре, вроде, этого не было в учебнике. Ща посмотрел...

в итоге, с этой поправкой и Вашим терпением всё запилилось...
Ниже код, который заработал, каналья!!

Спасибо, Родной!!!!!!!!!

C++
1
2
3
4
5
6
for (int r = 1; r < argc; r++)
    {   
       len = strlen(argv[r])+1;
        arr[i] = new Str(*argv[r], len);
        arr[i]->getd(); i++;
    }
0
Заблокирован
17.03.2023, 02:15
Лучший ответ Сообщение было отмечено Valdemarych как решение

Решение

Цитата Сообщение от Valdemarych Посмотреть сообщение
Ниже код, который заработал, каналья!!
На здоровье.
Еще один вариант :
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <cstring>
 
struct String{
    size_t size_m;
    char* data_m;
    String() : size_m{0}, data_m{new char[1]{}}{
    }
    String(const char * str)
        : size_m{strlen(str)}, 
          data_m{strcpy(new char[size_m+1], str)}{
    }
    void Print(){
            std::cout << data_m;
    }
    size_t size() const {
        return size_m;
    }
    ~String(){
        Free();
    }
 
    String(const String& other)
        : size_m{other.size_m}, 
          data_m{strcpy(new char[size_m+1], other.data_m)}{
    }
    String& operator=(const String& other){
        if (this != &other){
            char * new_data = strcpy(new char[other.size_m+1], other.data_m);
            Free();
            size_m = other.size_m;            
            data_m = new_data;
        }
        return *this;
    }
    String& operator=(const char* str){
        size_t new_length = strlen(str)+1;
        char * new_data = strcpy(new char[new_length], str);
        Free();
        size_m = new_length;            
        data_m = new_data;
        return *this;
    }
private : 
    void Free(){
        delete [] data_m;
        size_m = 0;
    }
};
int main(int argc, char** argv){
    String * strings = new String[argc];
    for(int i = 0; i < argc; ++i)
        strings[i] = argv[i];
    for(int i = 0; i < argc; ++i){
        strings[i].Print();
        std::cout << std::endl;
    }
    delete [] strings;
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.03.2023, 02:15
Помогаю со студенческими работами здесь

Разбор аргументов командной строки
Здравствуйте, нужно решить задачу но не знаю с его начать в командной строке вводится A.exeпробел/Uпробел/VEnter и программа должна...

Разбор аргументов командной строки
#!/usr/bin/python3.4 # -*- coding: UTF-8 -*- import sys import argparse import os import re def createParser (): ...

Использование аргументов командной строки
Всем доброго дня !!! Подскажите пожалуйста как связать этот код программы с командной строкой ? #include &lt;fstream&gt; ...

Проверка аргументов командной строки
Код вызывающий программу (интерфейс для работы с разными программами): { int caesar = ui.key-&gt;value(); char *_fileWay =...

Вывод аргументов командной строки
Здравствуйте, вот такой пример : package main import ( &quot;fmt&quot; &quot;os&quot; )


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru