Zmiana kodu innym programem

0

Hej, czy można napisać w C++ program który zmieni mi wszystkie słowa cout >>, cout >> format() na println()?
Samo println() działa dopiero od gcc 14 i gcc 14.1, na llvm to nie wiem czy już dodali ten standard.
Można już pisać nowoczesne programy w C++26 z println() czy lepiej siedzieć na cout >> format()?

#include <format>
#include <iostream>

using namespace std;

void showBalance(double balance);
double deposit();
double withdraw(double balance);

int main() {
  // banking practice program
  double balance = 0;
  int choice = 0;

  do {
    cout << "******************\n";
    cout << "Enter your choice:\n";
    cout << "******************\n";
    cout << "1. Show Balance\n";
    cout << "2. Deposit Money\n";
    cout << "3. Withdraw Money\n";
    cout << "4. Exit\n";
    cin >> choice;

    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    switch (choice) {
    case 1:
      showBalance(balance);
      break;
    case 2:
      balance += deposit();
      showBalance(balance);
      break;
    case 3:
      balance -= withdraw(balance);
      showBalance(balance);
      break;
    case 4:
      cout << "Thanks for visiting!\n";
      break;
    default:
      cout << "Invalid choice\n";
    }
  } while (choice != 4);
}

void showBalance(double balance) {
  cout << format("Your balance is: ${:.2f}\n", balance);
}

double deposit() {
  double amount = 0;

  cout << "Enter amount to be deposited: ";
  cin >> amount;

  if (amount > 0) {
    return amount;
  } else {
    cout << "That's not a valid amount:\n";
    return 0;
  }
}

double withdraw(double balance) {
  double amount = 0;

  cout << "Enter amount to be withdrawn: ";
  cin >> amount;

  if (amount > balance) {
    cout << "insufficient funds\n";
    return 0;
  } else if (amount < 0) {
    cout << "That's not a valid amount\n";
    return 0;
  } else {
    return amount;
  }
}
#include <print>
#include <iostream>

using namespace std;

void showBalance(double balance);
double deposit();
double withdraw(double balance);

int main() {
  // banking practice program
  double balance = 0;
  int choice = 0;

  do {
    println("******************");
    println("Enter your choice:");
    println("******************");
    println("1. Show Balance\n");
    println("2. Deposit Money\n");
    println("3. Withdraw Money\n");
    println("4. Exit\n");
    cin >> choice;

    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

    switch (choice) {
    case 1:
      showBalance(balance);
      break;
    case 2:
      balance += deposit();
      showBalance(balance);
      break;
    case 3:
      balance -= withdraw(balance);
      showBalance(balance);
      break;
    case 4:
      println("Thanks for visiting!\n");
      break;
    default:
      println("Invalid choice\n");
    }
  } while (choice != 4);
}

void showBalance(double balance) {
  println("Your balance is: ${:.2f}\n", balance);
}

double deposit() {
  double amount = 0;

  println("Enter amount to be deposited: ");
  cin >> amount;

  if (amount > 0) {
    return amount;
  } else {
    println("That's not a valid amount:\n");
    return 0;
  }
}

double withdraw(double balance) {
  double amount = 0;

  println("Enter amount to be withdrawn: ");
  cin >> amount;

  if (amount > balance) {
    println("insufficient funds\n");
    return 0;
  } else if (amount < 0) {
    println("That's not a valid amount\n");
    return 0;
  } else {
    return amount;
  }
}
2

O ile dobrze rozumiem pytanie, to chodzi o zamianę składni w kodzie - da się, ale raczej chcesz do tego użyć zewn. narzędzi takich jak ambr, kiedys byl comby, ale z tego co pamietam obecnie juz nie dziala.
Jesli korzystasz z edytora ktore wspiera makra, to tez powinno byc znacznie prosciej (w vimie moglbys sobie wrzucic wszystko do qflist i odpalic albo substitute dla kazdego elementu, albo makro).
W zaleznosci od skali programu to tez raczej nie powinien byc problem, zeby zrobic to manualnie.

Jesli chodzi o uzywanie print w kodzie, to osobiscie i tak poki co uzywam fmtlib do tego wszedzie w projektach i w pracy, zamiast <format>.

A odpowiednik print/println i tak mozesz sobie napisac juz teraz :)

template <typename Args>
auto print(std::format_string<Args...> fmt_string, Args&&... args) {
  std::puts(std::format(fmt_string, std::forward<Args>(args)...).data());
}

edit: literówka, brak pack expansion w kodzie

0

@Iroh ale dlaczego mam korzystać z fmtlib i pisać odpowiednik print, jak gcc-14 już obsługuje print i println? W jakim celu mam robić naokoło takie dodatkowe obejścia?
Napisałem ponad 100 konsolowych programów w którym jest cout i coutt << format(), ale widzę że na yt i github ludzie już stosują w swoich programach to println.
Więc chciałem napisać program w C++ lub znaleźć gotowca w sieci który pozmienia mi to cout na println.

0

Można już pisać nowoczesne programy w C++26 z println() czy lepiej siedzieć na cout >> format()?

Nie ma znaczenia, używaj co masz pod ręką. cout to narzędzie którego przestaje się używać bezpośrednio wraz z rozpoczęciem pierwszej pracy. Ewentualnie do jakiejś prostej narzędziówki jak się nie chce gotowców do logowanie wrapuje się to w coś prostego w stylu kodu poniżej, gdzie potem możesz sobie cout zmienić na cokolwiek w jednym miejscu, także nie myśl nad tym zbyt długo.

#include <type_traits>
#include <sstream>
#include <iostream>

class SimpleLog
{
public:
  ~SimpleLog()
  {
    std::cout << m_ss.str() << std::endl;
  }

  template
  <
    typename T,
    typename = typename std::enable_if<std::is_integral<T>::value || std::is_floating_point<T>::value>::type
  > 
  SimpleLog& operator<<(T val)
  {
    m_ss << val;
    return *this;
  }

  SimpleLog& operator<<(const std::string &str)
  {
    m_ss << str;
    return *this;
  }

  SimpleLog& operator<<(const std::stringstream &ss)
  {
    m_ss << ss.str();
    return *this;
  }

  SimpleLog& operator<<(const char *c_str)
  {
    m_ss << c_str;
    return *this;
  }

  std::ostream& stream() const
  {
    return std::cout;
  }

private:
  std::stringstream m_ss;
};

#define log (SimpleLog{})

/////////////////////////////////

int main()
{
  log << "Hello World!";
  log << "goodbye";

  return 0;
}

1

zamiast zastanawiać się czy można już używać std::print itp to po prostu użyj biblioteki fmt.
To już działa wszędzie od dawna i to jest źródło na który wzorują się autorzy standardu.

https://github.com/fmtlib/fmt
https://fmt.dev/11.0/

To, że w tej chwili możesz używać wersji gcc, która wspiera tę funkcjonalność, nie znaczy, że. w przyszłej pracy będziesz w tej sytuacji.
Jest wiele powodów, dla których projekt może być zmuszony używać wcześniejszej wersji kompilatora, albo nędziesz miał nowszy kompilator, ale z powodu wsparcia starszych platform nie będzie wolno używać danej funkcjonalności.

Przykładowo w moim obecnym projekcie, na MacOS używamy teraz clang-15, ale jako, że wspieramy MacOS 10.14 to cześć biblioteki standardowej jest wyłączona z użytku (kompilator sama tego pilnuje): std::filesystem.
Na Linux jesteśmy zmuszeni używać clang-10, bo jakaś zależność, z której korzystamy wymaga standardowej biblioteki obsługiwanej przez clang-10.

0
plansz_el napisał(a):

@Iroh ale dlaczego mam korzystać z fmtlib i pisać odpowiednik print, jak gcc-14 już obsługuje print i println? W jakim celu mam robić naokoło takie dodatkowe obejścia?
Napisałem ponad 100 konsolowych programów w którym jest cout i coutt << format(), ale widzę że na yt i github ludzie już stosują w swoich programach to println.
Więc chciałem napisać program w C++ lub znaleźć gotowca w sieci który pozmienia mi to cout na println.

źle zrozumiałeś kolegę.
biblioteka fmt ma wszystkie funkcjonalności a nawet więcej (np kolory).

ten hack z puts jest tylko jak nie chcesz zużywać fmt , ale masz już C++20 i mozna opakować użycie std::foramt

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.