Извлекать входные данные из указателя на массив символов

0

Я пишу служебную программу командной строки, но я не могу найти способ хранения команд и аргументов. пока у меня есть следующее, но я получаю ошибку сегментации:

int main(void)
{
    char *command;
    char *args[MAX_LINE/2 + 1]; 
    int should_run = 1;

    do{
         cout << "cmd> ";
         int counter = 0;
         while(cin >> command) {
             strcpy(args[counter],command);
             counter++;
         }
        cout << args[0] << "\n";
    }  
}
Теги:

3 ответа

4
Лучший ответ

Вы получаете ошибку сегментации, потому что это:

cin >> command

пытается писать в неинициализированную память. Поскольку это C++, вы должны сделать:

std::string command;

вместо:

char * command;

и аналогично для args. Затем вы можете использовать args[counter] = command вместо использования strcpy(). Для дополнительных точек используйте std::vector<std::string> args вместо использования массива и args.push_back(command) вместо команды args[counter] = command.

Например:

#include <iostream>
#include <vector>
#include <string>

int main() {
    std::string command;
    std::vector<std::string> args;

    std::cout << "cmd> ";
    while( std::cin >> command ) {
        args.push_back(command);
    }

    int i = 0;
    for ( auto a : args ) {
        std::cout << "Arg " << i++ << " is " << a << std::endl;
    }

    return 0;
}

Вывод:

paul@local:~/src/cpp/scratch$ ./args
cmd> test this command
Arg 0 is test
Arg 1 is this
Arg 2 is command
paul@local:~/src/cpp/scratch$
2

Распространенным заблуждением является то, что char * будет играть особую роль на C или C++, главным образом мотивированным тем, что это является законным:

char const * foo = "String";

На самом деле char * по-прежнему остается указателем на char, поэтому вам нужно будет выделить память, прежде чем сможете присвоить ему строковый литерал. У вас есть эта проблема дважды в коде:

char * command;
std::cin >> command;

а также

char * arr[N];
std::strcpy(arr[k], command);

В C++ для этого необходимо использовать такие контейнеры, как std::string и std::vector<std::string>. Если вы настаиваете на работе с массивами символов, вы можете определить статическую максимальную длину:

char command[MAX_LENGTH];
char args[N][MAX_LENGTH];

или динамически с использованием new[]

char * command = new char[MAX_LENGTH];
char * args[N];
for(unsigned k = 0; k < N; ++k) args[k] = new char[MAX_LENGTH];

но тогда вы также должны помнить о том, чтобы освободить эту память:

delete[] command;
for(unsigned k = 0; k < N; ++k) delete[] args[k];

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

0

Это утверждение

while(cin >> command)

является недействительным. Прежде всего переменная команда не была инициализирована, а во-вторых, вам нужно выделить память, чтобы поток cin мог размещать там данные. Либо используйте массив символов (статически или динамически распределенный), либо используйте класс std :: string для ввода данных.

Ещё вопросы

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