czy Community 2022 ma obsługę standardowo konwersi(konwertowania) danych z char->int , int->char , float->char , char->float ? jeśli tak to można jakieś przykłady prosić ...
EDIT:sprawdziłem atoi oraz atof i błędne pokazuje wartości, sypie się..
konwersja, konwertowanie danych
- Rejestracja: dni
- Ostatnio: dni
- Postów: 678
- Rejestracja: dni
- Ostatnio: dni
- Postów: 28
Community 2022 jest chyba zgodny z w miarę nowymi standardami. To standard 'ma obsługę' a nie IDE (no chyba że jakieś rozszerzenia).
No ale do rzeczy. Myślę że lepiej byłoby gdybyś sam pokazał przykłady gdzie nie działa ale mniejsza.
Są funkcje z:
<cstdlib(atoi,atof,strtof)<string>(stoi,stof,to_string)<charconv>(from_chars,to_chars)<cstdio>(sprintf)<format>
Przykład od GPT :
#include <iostream>
#include <string>
#include <cstring>
#include <charconv>
#include <cstdlib>
#include <cstdio>
#include <format>
int main() {
// ----- char* (C-string) -> int -----
const char* str_num = "12345";
int num1 = atoi(str_num); // C-style
int num2 = std::stoi(std::string(str_num)); // C++ string + stoi
int num3 = 0;
std::from_chars(str_num, str_num + std::strlen(str_num), num3); // from_chars
std::cout << "char* -> int:\n";
std::cout << "atoi: " << num1 << "\n";
std::cout << "stoi: " << num2 << "\n";
std::cout << "from_chars: " << num3 << "\n\n";
// ----- int -> char* / std::string -----
int val = 6789;
char buffer1[20];
sprintf(buffer1, "%d", val); // C-style
std::string str_val = std::to_string(val); // C++ style
char buffer2[20];
auto [ptr, ec] = std::to_chars(buffer2, buffer2 + sizeof(buffer2), val); // C++17 with std::to_chars
*ptr = '\0'; // null-terminate manually
std::cout << "int -> char* / string:\n";
std::cout << "sprintf: " << buffer1 << "\n";
std::cout << "to_string: " << str_val << "\n";
std::cout << "to_chars: " << buffer2 << "\n";
std::cout << "format: " << std::format("{}", val) << "\n\n";
// ----- char* -> float -----
const char* str_float = "3.14159";
float f1 = atof(str_float); // C-style
float f2 = std::stof(std::string(str_float)); // C++ string + stof
float f3 = 0.0f;
std::from_chars(str_float, str_float + std::strlen(str_float), f3); // from_chars (float) – may have limited support
char* endptr;
float f4 = strtof(str_float, &endptr); // strtof
std::cout << "char* -> float:\n";
std::cout << "atof: " << f1 << "\n";
std::cout << "stof: " << f2 << "\n";
std::cout << "from_chars: " << f3 << " (may be zero if not supported)\n";
std::cout << "strtof: " << f4 << "\n\n";
// ----- float -> char* / string -----
float pi = 3.14159f;
char buffer3[32];
sprintf(buffer3, "%.5f", pi); // C-style formatting
std::string str_pi = std::to_string(pi); // C++ style
char buffer4[32];
auto [ptr2, ec2] = std::to_chars(buffer4, buffer4 + sizeof(buffer4), pi); // C++17 with std::to_chars
*ptr2 = '\0'; // null-terminate
std::cout << "float -> char* / string:\n";
std::cout << "sprintf: " << buffer3 << "\n";
std::cout << "to_string: " << str_pi << "\n";
std::cout << "to_chars: " << buffer4 << "\n";
std::cout << "format: " << std::format("{}", pi) << "\n";
return 0;
}
EDIT: Dodałem <format>
- Rejestracja: dni
- Ostatnio: dni
- Postów: 678
cout << atof((char*)"3.14159658") << endl;
wynik:3.1416 - obcina koniec
float pi = 3.14159658f;
char buffer3[32];
sprintf(buffer3, "%f", pi); // C-style formatting
wynik:: 3.141597 - też obcina, z tego co widać to zaokrągla to mi się nie podoba
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1107
wilkwielki napisał(a):
cout << atof((char*)"3.14159658") << endl;wynik:3.1416 - obcina koniec
Podglądałeś w debugerze co rzeczywiście zwraca atof np przypisując do tymczasowej zmiennej typu double? Bo mam wrażenie, że to tylko kwestia wyświetlania. Powinieneś zainteresować się tym https://en.cppreference.com/w/cpp/io/manip/setprecision Jak ustawisz odpowiednio precyzję, to powinien wyświetlać tyle ile chcesz.
Jeśli chodzi o drugą rzecz, spróbuj tak:
sprintf(buffer3, "%.20f", pi); // C-style formatting
Pisane z pamięci bez sprawdzenia, ale powinno też zadziałać ;)
- Rejestracja: dni
- Ostatnio: dni
- Postów: 28
Problemy są dwa.
Jeden to setprecision co do którego Mr.YaHooo mnie ubiegł bo za bardzo grzebie się z pisaniem odpowiedzi.
Drugi to wybór typu danych. Typ float jest za mały aby pomieścić tę liczbę. Zmiana na double rozwiązuje ten problem.
Poniżej przykład:
- dodałem
setprecision - zmieniłem
to_stringnaformat - zmieniłem
floatnadouble(zmieniając odpowiednio funkcje)
#include <iostream>
#include <string>
#include <cstring>
#include <charconv>
#include <cstdlib>
#include <cstdio>
#include <format>
#include <iomanip>
int main() {
// ----- char* -> double -----
const char* str_double = "3.14159265358979";
double f1 = atof(str_double);
double f2 = std::stod(std::string(str_double));
double f3;
std::from_chars(str_double, str_double + std::strlen(str_double), f3);
char* endptr;
double f4 = strtod(str_double, &endptr);
std::cout << std::fixed << std::setprecision(14);
std::cout << "char* -> double:\n";
std::cout << "atof: " << f1 << "\n";
std::cout << "stod: " << f2 << "\n";
std::cout << "from_chars: " << f3 << " (may be zero if not supported)\n";
std::cout << "strtod: " << f4 << "\n\n";
// ----- double -> char* / string -----
double pi = 3.14159265358979;
char buffer3[32];
sprintf(buffer3, "%.14f", pi);
std::string str_pi = std::format("{}", pi);
char buffer4[32];
auto [ptr2, ec2] = std::to_chars(buffer4, buffer4 + sizeof(buffer4), pi);
*ptr2 = '\0';
std::cout << "double -> char* / string:\n";
std::cout << "sprintf: " << buffer3 << "\n";
std::cout << "format: " << str_pi << "\n";
std::cout << "to_chars: " << buffer4 << "\n";
return 0;
}
- Rejestracja: dni
- Ostatnio: dni
- Postów: 678
zrobiłem tak:
double pi = 3.14159265358979;
char buffer3[32];
std::setprecision(32);
sprintf(buffer3, "%.20f", pi);
cout << pi << endl;
wynik: 3.14159
- Rejestracja: dni
- Ostatnio: dni
- Postów: 1107
Ale setprecision nie tak się używa. Oba moje sposoby działają poprawnie https://ideone.com/c4PF5y
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
// your code goes here
double pi = 3.14159265358979;
cout << std::setprecision(32) << pi << endl;
char buffer3[32];
sprintf(buffer3, "%.20f", pi);
cout << buffer3;
return 0;
}
- Rejestracja: dni
- Ostatnio: dni
- Postów: 678
rzeczywiście działa, ok to dzięki w razie problemów sprawdzę ostatnie posty, dzięki
- Rejestracja: dni
- Ostatnio: dni
- Postów: 2184
sprintfw C++ nie jest przestarzała w sensie technicznym (ciągle jest w standardzie C i C++), ale uznaje się ją za niebezpieczną – bo łatwo o błąd typu buffer overflow (przekroczenie bufora, jeśli źle policzysz rozmiar).W nowoczesnym C++ masz kilka lepszych opcji:
1.
snprintfBezpieczniejsza wersja
sprintf, bo podajesz maksymalny rozmiar bufora:char buf[100]; snprintf(buf, sizeof(buf), "Wynik: %d", 42);2.
std::ostringstreamCzęść standardu C++ (bezpieczna, ale trochę „ciężka” i mniej wygodna):
#include <sstream> #include <string> std::ostringstream oss; oss << "Wynik: " << 42; std::string str = oss.str();3.
std::format(C++20)Nowoczesne i bardzo wygodne:
#include <format> #include <string> std::string s = std::format("Wynik: {}", 42);4.
fmt(biblioteka open-source, na której opiera sięstd::format)Jeśli Twój kompilator nie wspiera jeszcze
std::format, możesz użyć {fmt}:#include <fmt/core.h> #include <string> std::string s = fmt::format("Wynik: {}", 42);
Podsumowanie:
sprintfnadal działa, ale lepiej go unikać w nowych projektach.- Jeśli chcesz pisać nowocześnie: używaj
std::format(C++20) albo{fmt}.- Jeśli musisz w stylu C:
snprintf.Chcesz, żebym zrobił tabelkę porównawczą (
sprintfvssnprintfvsostringstreamvsstd::format)?
ja osobiście preferuję fmt
- Rejestracja: dni
- Ostatnio: dni
- Postów: 678
jeśli tak to zrób tą tabelkę porównawczą
- Rejestracja: dni
- Ostatnio: dni
wilkwielki napisał(a):
czy Community 2022 ma obsługę standardowo konwersi(konwertowania) danych z char->int , int->char , float->char , char->float ? jeśli tak to można jakieś przykłady prosić ...
EDIT:sprawdziłem atoi oraz atof i błędne pokazuje wartości, sypie się..
brokenelevator napisał(a):
Community 2022 jest chyba zgodny z w miarę nowymi standardami.
Najwyraźniej mylicie IDE z kompilatorem.
Microsoft Visual Studio Community 2022 - odnosi się do IDE (Integrated Development Environment). Wraz z tym narzędziem jest instalowany kompilator MSVC.
Wersja Microsoft Visual Studio różnią się zestawem narzędzi jakie są dostarczane z/do tego IDE. Sam kompilator C/C++ jest ten sam dla wszystkich wersji.