@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


Если вдруг поможете еще и с выравниванием текста буду признателен :). Но это не самое главное.
Спасибо за отзывчивость. За ранее извиняюсь за быдлокод, только учусь.
  • Вопрос задан
  • 322 просмотра
Пригласить эксперта
Ответы на вопрос 1
MvcBox
@MvcBox
Software Engineer [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, очередная бессмыслица.

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

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

Похожие вопросы