@pynew_user

Как правильно получить из параметра argv[] строку «название файла»? Как вывести в консоль определенное количество строк?

Мой код, в основном он компилируется и нужные функции реализовывает.

#include <iostream> //библиотека для вывода текста в консоль
#include <fstream> // библиотека для работы с файлами
#include <string> // библиотека для работы со строками
#include <vector> // библиотека для работы с массивом строковых данных
#include <iomanip> // библиотека для выравнивания текста 
#include <climits> // библиотека для проверки максимального значения типа int
#include <stdlib.h> // библиотека для досрочного выхода из прогаммы (exit)
using namespace std; // стандартное пространство имен для упрощения написания типов данных



int main(int argc, char* argv[]) // инициализация функции main и передача в нее аргументов из командной строки
{
    setlocale(LC_CTYPE, "rus"); // поддрежка Русского алфавита
    vector <string> params {

         "Наименования", "Площадь здания", "Этажность здания", // массив заголовочной строки таблицы
         "Год сооружения", "Оценочная стоимость млн.руб"
    };
     vector <array <string, 5> > air {
	   { "Домодедово", "1223", "10", "1980", "201"}, // двумерный массив, хранящий таблицу данных
	   { "Шереметьево", "570", "12", "1965", "312"},
	   { "Внуково", "823", "11", "1988", "179"},
	}; 
    if (argc > 1 && (string(argv[1]) == "-c" || string(argv[1]) == "-mass" || string(argv[1]) == "-r" || string(argv[1]) == "-h" || string(argv[1]) == "--help")){ 
        // проверка больше ли передано параметров в консоль, тк по стандарту первый параметр всегда подается - путь к файлу. Так же является второй параметр одной из ниже приведенных команд
        if (string(argv[1]) == "--help" || string(argv[1]) == "-h"){ // проверка, передан ли параметр -help и ее содержание
                cout << "--help либо -h" << " " << "- запуск программы в режиме получения справки. После вывода справочной информации программа завершает работу." << endl;
                cout << '\n';
                cout << "-с [N] [file_name]" << " " << "- запуск программы в режиме создания электронной таблицы записей, N – количество записей, file_name – имя текстового файла, в котором будет сохранен массив (таблица) записей." << endl;
                cout << '\n';
                cout << "-mass" << " " << "- просмотр массива данных, хранящихся в программе." << endl;
                cout << '\n';
                cout << "-r [N] [file_name] - запуск программы в режиме чтения содержимого текстового файла file.txt, на экран должны быть выведены не более N записей. " << endl;
                cout << '\n';

            }
        else if (string(argv[1]) == "-mass"){ // проверка, передан ли параметр -mass и вывод в консоль массива air 
            for (const auto & el: params){
                cout << setiosflags( ios::left ) << setw(35) << el;
            }
            cout << '\n'; 
            cout << '\n';

            for (const auto &x : air){   
                cout << setiosflags( ios::left);
                for (const auto &y : x)
                    cout << setw(30) << y ; 
                    cout << '\n';
            }
            cout << '\n';
            }
        else if (string(argv[1]) == "-c") { // проверка, передан ли параметр -c 
            
            if (argc != 4) // тк параметру -с должны сопутствовать [N] и [file_name] проверяем колличество параметров
            {
               cout << "Параметру -с  должны сопутствовать параметры [N] - количество записей и [file_name] - имя файла для записи.";
               cout << '\n';
            }
            else{ 
                char * endp;
                long i = strtol(argv[2],&endp,10); 
                
                
                if (*endp || i < 0 || i > INT_MAX){ // проверка правильности написания [N]
                    cout << "Параметру -с  должны сопутствовать параметры [N] - количество записей и [file_name] - имя файла для записи.";
                    cout << '\n';
                }
                else {
                    int argv[2];
                    string argv[3];

                    ofstream fout (argv[3].c_str() , ios::app); // передача праметра [file_name] в объект класса ofstream для открытия файла в режиме записи
                    if (!fout.is_open()){ //проверка корректно ли название файла
                        cout << "Некорректное имя файла.\n"; 
                    }

                    else{    
                   
                    // запись в файл массива air        
                    for (int i = 0; i < argv[2]; i++){
                
                    for (int j = 0; j < air[i].size(); j++){

                        fout << setiosflags( ios::left ) << setw(25) << air[i][j] ;
                    }  
                    fout << '\n';
                  
                
                    }
                    fout.close();
                    }
                }
            }
        }
        else if (string(argv[1]) == "-r") { // проверка, передан ли параметр -r
            
            if (argc != 4) // проверяем колличество параметров
            {
               cout << "Параметру -r  должны сопутствовать параметры [N] - количество записей и [file_name] - имя файла для записи.";
               cout << '\n';
            }
            else{ 
                
                char * endp;
                long i = strtol(argv[2],&endp,10);
                
                if (*endp || i < 0 || i > INT_MAX){ // проверка правильности написания [N]
                    cout << "Параметру -r  должны сопутствовать параметры [N] - количество записей и [file_name] - имя файла для записи.";
                    cout << '\n';
                }    

                else{
                    string argv[3];
                    int line_number;
                    string str;
                    

                    ifstream fin (argv[3].c_str(), ios::app); // передача праметра [file_name] в объект класса ifstream для открытия файла в режиме чтения
                  
                    if (!fin.is_open()){ //проверка корректно ли название файла
                        cout << "Некорректное имя файла.\n";
                        exit(0); 
                    }
                    

                    else{
                        while(getline(fin, str))
                        {
                            line_number++;
                        }
                        if (line_number!=0){ // проверка есть ли записи в файле

                            int argv[2];
                            int N = 0;

                            for (const auto & el: params) // вывод шапки массива для удобного ориентирования 
                            {
                                cout << setiosflags( ios::left ) << setw(35) << el;
                            }
                            cout << '\n';
                            cout << '\n';

                            
                            /*for (int i = 0; i < N; i++){
                                
                                getline(fin, str);
                                cout << str << endl;
                        }*/
                            string line;
                            while (N < argv[2]){ // вывод указанного числа из параметра [N]

                                
                                getline(fin, line);
                                cout << str << endl;
                                N++;
                            }

                            fin.close();
                        }
                        else{
                            cout << "Указанный файл пуст.\n";
                        }
                    }
                }
            }    
        }
    }
    
    else {
        cout << "Вы не передали аргументов программы. Введите команду --help или -h для получения справки.";
        cout << '\n';
    }
    return 0;
}


1)Требуется считать из параметра argv[3] название файла в который будет записываться / из которого будет выводится текст. Пытался реализовать с помощью ifstream fin (argv[3].c_str(), ios::app);, но безуспешно - выдает ошибку. Находил в интернете разные примеры, где параметр именно так и использовали, возможно напутал в типах данных, не силен в C++.
Если напрямую указывать файл ifstream fin ("file.txt"); все работает, и вывод и ввод.
2) В данном блоке пытаюсь с помощью параметра argv[2] ограничить вывод строк в консоль из файла, но тоже не работает. Требуется вывести именно столько строк, сколько указано в argv[2]. Так же пытался через for (int i = 0; i < N; i++). Прошу помочь в этом.
string line;
                            while (N < argv[2]){ // вывод указанного числа из параметра [N]

                                getline(fin, line);
                                cout << str << endl;
                                N++;
                            }


Программа должна работать на Linux. Код писал и компилировал в Linux Mint. Использую компилятор g++.
Использовал файл file.txt. При записи в файле лежит текст:
Домодедово     1223                     10                       1980                     201                      
Шереметьево   570                      12                       1965                     312                      
Внуково           823                      11                       1988                     179


Если вдруг поможете еще и с выравниванием текста буду признателен :). Но это не самое главное.
Спасибо за отзывчивость. За ранее извиняюсь за быдлокод, только учусь.
  • Вопрос задан
  • 232 просмотра
Пригласить эксперта
Ответы на вопрос 1
MvcBox
@MvcBox
Software Developer [C/C++/JS(for Node.js)/etc]
int argv[2];
string argv[3];

ofstream fout (argv[3].c_str() , ios::app);

1) Оно даже не скомпилится, как минимум словите conflicting declaration
2) Классическая ошибка - затенение переменных. Вы хотели скастовать это в string, но в итоге написали полный бред. Даже если бы не было conflicting declaration, у вас там еще out of range: argv[3].c_str()

while (N < argv[2]) { // вывод указанного числа из параметра [N]

Вы сравниваете адрес с N, очередная бессмыслица.

Дальше искать ошибки не стал, так как не имеет смысла. Все надо переделывать.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы