Argumenty wiersza poleceń - paradoks dnia urodzin

0

Witam wszystkich,

Dostałem do napisania program. W instrukcji programu wyraźnie napisane jest, że wartości mają być wprowadzane jako argumenty programu
A dokładniej

Wartości n, k i p podawane są jako argumenty programu. Każdy argument ma następujący format:
zmienna=wartość
gdzie:
zmienna – nazwa zmiennej: „n”, „k” lub „p”
wartość – liczba całkowita (w przypadku n i k) lub zmiennoprzecinkowa (p),

I w tym momencie pojawiają się moje wątpliwości. Jeśli mój argument będzie wyglądał w ten sposób " n=100 ", to kompilator nigdy nie przypisze zmiennej n wartości 100. Czy jakaś dobra dusza może rozwiązać problem początkującego? Jak w takim przypadku implementowania argumentów poradzić sobie z problemem?

0

Nie jestem pewien, czy o to Ci chodzi, ale jeśli napiszesz funkcje main w taki sposób:

int main(int argc, char *argv[])
{

}

otrzymujesz dojście do argumentów podanych podczas wywołania programu. argc to ilość argumentów, a argv to wskaźnik na pierwszy argument( w tym przypadku typu char).

0

Dokładnie o to mi chodzi tylko mój problem polega na tym, że jak po wprowadzeniu argumentu n=100
przypisać *argv[1] wartość 100 zamiast tego całego łańcucha znaków? Czy jest to wykonalne?

0

Oczywiście że jest.
Tutaj ostatni przykład jest ze znakiem - a ty napisz zamiast tego = : https://arch.kacperkolodziej.pl/artykuly/programowanie/214-cpp-wczytywanie-parametrow-programu-z-linii-polecen.html :)

0

Jak sobie program wywołujesz o tak:

program.exe n=100 k=200 p=300

to argc wyniesie 4 (bo ścieżka do pliku .exe to pierwszy argument, natomiast "n=100" to drugi, itd.)
natomiast
argv[0] = "sciezka/program.exe"
argv[1] = "n=100"
argv[2] = "k=200"
argv[3] = "p=300"

Jako, że argv to tablica c-stringów to musisz sobie sparsować argumenty, tak aby do zmiennych w programie wpisać odpowiednie wartości.

Zrobić to można na przykład tak (-std=c99):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void parse_argument(int *output, const char *arg, int argc, char *argv[])
{
	int arg_length = strlen(arg);
	for(int i = 1 /* pomijamy pierwszy argument */; i < argc; i = i + 1)
	{
		if(memcmp(argv[i], arg, arg_length) == 0) // sprawdzamy czy początek argv[i] jest równe arg
		{
			if(argv[i][arg_length] == '=') // sprawdzamy czy po nazwie argumentu jest =
			{
				*output = atoi(argv[i] + arg_length + 1);
			}
		}
	}
}

int main(int argc, char *argv[])
{
	int n = 0;
	int k = 0;
	int p = 0;

	parse_argument(&n, "n", argc, argv);
	parse_argument(&k, "k", argc, argv);
	parse_argument(&p, "p", argc, argv);

	printf("%i %i %i\n", n, k, p);
}

Sprecyzuj czy chodzi ci o C czy o C++ bo w C++ można do tego dojść w trochę bardziej jasny sposób.

0

Chodzi mi o język c++ właśnie coś w stylu kodu który zaprezentowałeś

0
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

bool is_prefixed(const string &a, const string &b)
{
	if (a.size() > b.size()) {
		return a.substr(0,b.size()) == b;
	} else {
		return b.substr(0,a.size()) == a;
	}
}

template < typename TYPE >
void parse_argument(TYPE *const output, const string &arg, const int argc, char *const argv[])
{
	for(int i = 1 /* pomijamy pierwszy argument */; i < argc; ++i)
	{
		if(is_prefixed(argv[i], arg))
		{
			if(argv[i][arg.length()] == '=')
			{
				istringstream ss((argv[i] + arg.length() + 1));
				ss >> *output;
			}
		}
	}
}

int main(int argc, char *argv[])
{
    int n = 0;
    int k = 0;
    float p = 0; // załóżmy, że p jest liczbą zmiennoprzecinkową

    parse_argument(&n, "n", argc, argv);
    parse_argument(&k, "k", argc, argv);
    parse_argument(&p, "p", argc, argv);

    cout << n << " " << k << " " << p << " " << endl;
    return 0;
}

prog.exe n=2 k=1 p=0.5
2 1 0.5

0

A czy ktoś mógłby mi opisać jeszcze działanie tych częsci kodu?

bool is_prefixed(const string &a, const string &b)
{
    if (a.size() > b.size()) {
        return a.substr(0,b.size()) == b;
    } else {
        return b.substr(0,a.size()) == a;
    }
}
 for(int i = 1; i < argc; ++i)
    {
        if(is_prefixed(argv[i], arg))
        {
            if(argv[i][arg.length()] == '=')
            {
                istringstream ss((argv[i] + arg.length() + 1));
                ss >> *output;
            }
        }
    }
0
class ArrgParse
{
public:
     ArrgParse(int argc, char *argv[])
     {
          for (int i=1; i<argc ;++i)
          {
               ParseArgument(argv[i]);
          } 
     }

     void ParseArgument(const std::string &arg)
     {
          std::istringstream data { arg };
          std::string key, value;
          if (std::getline(data, key, '='))
          {
                std::getline(data, value);
                values[key] = value;
          }
     }

     auto GetValue(const std::string &key) const -> std::string
     {
          auto it = values.find(key);
          if (if != values.end())
          {
              return it->second;
          }
          return {};
     }
private:
    std::map<std::string, std::string> values;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1