My c++ program is this:
#include <iostream>
#include <cstdlib>
#include <dos.h>
using namespace std;
void arr(int pts,string *splt_msg){
for(int x=-1;x<pts-1;x++){
string input;
cout<<"Enter part "<<x<<endl;
cin>>input;
(*splt_msg)[x]=input;
}
}
void print_arr(string *splt_msg,int del,int parts){
for(int x=-1;x<parts-1;x++){
cout<<(*splt_msg)[x];
delay(del);
}
}
int main(){
cout<<"Parts in message: ";
int parts;
cin>>parts;
cout<<"Delay between parts(ms): ";
int del;
cin>>del;
parts--;
string splt_msg[parts];
string (*Parr)[parts]=&splt_msg;
arr(parts,Parr);
print_arr(Parr,del,parts);
return 0;
}
Here is the error code(on windows and mingw):
c:\Users\User\Desktop\c++>g++ -o program test1.cpp
In file included from test1.cpp:3:0:
c:\mingw\include\dos.h:54:2: warning: #warning "<dos.h> is obsolete; consider using <direct.h> instead." [-Wcpp]
^~~~~~~
test1.cpp: In function 'void arr(int, std::__cxx11::string*)':
test1.cpp:18:14: error: 'delay' was not declared in this scope
delay(del);
^
test1.cpp: In function 'int main()':
test1.cpp:32:17: error: cannot convert 'std::__cxx11::string (*)[parts] {aka std::__cxx11::basic_string<char> (*)[parts]}' to 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' for argument '2' to 'void arr(int, std::__cxx11::string*)'
arr(parts,Parr);
^
test1.cpp:33:27: error: cannot convert 'std::__cxx11::string (*)[parts] {aka std::__cxx11::basic_string<char> (*)[parts]}' to 'std::__cxx11::string* {aka std::__cxx11::basic_string<char>*}' for argument '1' to 'void print_arr(std::__cxx11::string*, int, int)'
print_arr(Parr,del,parts);
^
Does someone know what i have done wrong and the solution?
Thanks for the help, I'm just trying to write a simple program to test some concepts out like passing pointers into functions but it doesn't seem to be working.
This code is more C style then C++. You are doing difficult error prone things. Try using vectors and such
string splt_msg[parts];
should not even evaluate, as parts is not a constant expression.
Try using things like std::vector. and passing by reference. E.g.:
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
template<typename T>
T Read() noexcept {
T output{};
std::cin >> output;
return output;
}
void arr(std::vector<std::string>& splt_msg) {
for (auto& msg : splt_msg) {
std::cout << "Enter part \n";
std::cin >> msg;
}
}
void print_arr(std::vector<std::string> const& splt_msg, int delay) {
for (auto& msg : splt_msg) {
std::cout << msg;
Sleep(delay);
}
}
int main() {
std::cout << "Parts in message: ";
auto parts = Read<int>();
std::cout << "Delay between parts(ms): ";
auto delay = Read<int>();
std::vector<std::string> splt_msg(parts);
arr(splt_msg);
print_arr(splt_msg, delay);
}
edit: or even better: use an object
#include <iostream>
#include <string>
#include <vector>
#include <Windows.h>
template<typename T>
T Read() noexcept {
T output{};
std::cin >> output;
return output;
}
class SplitMessage {
private:
std::vector<std::string> splitMessage;
public:
SplitMessage(size_t length) noexcept : splitMessage(length) {}
void GetData() noexcept;
void PrintData(int delay) const noexcept;
};
void SplitMessage::GetData() noexcept {
for (auto& msg : splitMessage) {
std::cout << "Enter part \n";
std::cin >> msg;
}
}
void SplitMessage::PrintData(int delay) const noexcept {
for (auto& msg : splitMessage) {
std::cout << msg;
Sleep(delay);
}
}
int main() {
std::cout << "Parts in message: ";
auto parts = Read<int>();
std::cout << "Delay between parts(ms): ";
auto delay = Read<int>();
SplitMessage splt_msg(parts);
splt_msg.GetData();
splt_msg.PrintData(delay);
}
Both functions require a std::string* (a pointer to a string) as first parameter, but both times you pass std::string*[] (an array of pointers to a string) as first paramater. The solution depends on what you want to achieve, but I guess, you want to call the function for one element of the array with an indexer: print_arr(Parr[0],del,parts);
Some other notes:
for(int x=-1;x<parts-1;x++){cout<<(*splt_msg)[x];...} will access the -1st character of a string, which is UB, but probably just crashes. Should be for(int x=0;x<parts;x++)
string splt_msg[parts]; is no valid C++, since parts is not constant at compile time.
Related
I learned a helper function that can convert strings to integers:
int string_to_int(string s)
{
istringstream instr(s);
int n;
instr>>n;
return n;
}
It's mentioned that the argument s cannot be c-str string, why is this the case?
But you can pass a C style string.
The reason for that is because the std::string constructor can implicitly accept a CharT* (Char type, which is char in this case) as a parameter. Thus, something like the following would work:
#include <iostream>
#include <sstream>
using namespace std;
int string_to_int(string s)
{
istringstream instr(s);
int n;
instr>>n;
return n;
}
int main()
{
const char* test = "12345";
std::cout << string_to_int(test) << "\n"; // Outputs 12345
std::cout << string_to_int("122") << "\n"; // Outputs 122
}
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
std::wstring inputfield;
void function(uint32_t val)
{
std::wstring keystring;
keystring = std::to_wstring(val);
inputfield = inputfield + keystring;
std::wstringstream s;
s << L"(" << inputfield << L") ";
std::wstring str = s.str();
std::wcout << str << "\n";
return;
}
int main()
{
uint32_t x ;
while(cin>>x)
{
function(x);
cout<< *(&x)<< endl;
}
return 0;
}
I am trying string format to get output like (000)-000-000 or USA phonenumber format, But I am not able to achieve that, Please help, Thanks
If you want to change string 000000000 or simillar (and you do, even if input is a number, simply convert it with std::to_string) then just add a few characters in proper places.
std::string format_number(std::string str) {
if(str.size() != 9) {
throw std::logic_error{"Phone number is not 9-characters long"};
}
str.insert(str.begin(), '(');
str.insert(str.begin() + 4, ')');
str.insert(str.begin() + 5, '-');
str.insert(str.begin() + 9, '-');
return str;
}
You can allocate input phone numbers and then pass structures like this;
struct numbers {
int A;
int B;
int C;
} // then get (A)-B-C
#include <iostream>
#include <thread>
#include <string>
//---- The following function will be invoked by the thread library
void thread_proc(std::string msg)
{
std::cout << "ThreadProc msg:" << msg;
}
int main()
{
// creates a new thread and execute thread_proc on it.
std::thread t(thread_proc, "Hello World\n");
// Waiting for the thread_proc to complete its execution
// before exiting from the program
t.join();
}
How to resolve this error
$ g++ Dummy.cpp -o Dummy -std=c++1z -pthread
Dummy.cpp: In function 'int main()':
Dummy.cpp:12:10: error: 'thread' is not a member of 'std'
12 | std::thread t(thread_proc, "Hello World\n");
| ^~~~~~
Dummy.cpp:3:1: note: 'std::thread' is defined in header '<thread>'; did you forget to '#include <thread>'?
2 | #include <thread>
+++ |+#include <thread>
3 | #include <string>
Dummy.cpp:15:5: error: 't' was not declared in this scope; did you mean 'tm'?
15 | t.join();
| ^
| tm
I have a problem with String Insertion because, I can not add a char, just a const char. How can i easily convert it?
The compiler just accept like this:
b.insert(i,"a");
But i want like this:
b.insert(i,b[ii]);
Full Code:
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string a,b;
int aa=0;
cin >> a;
b=a;
for(int i=0;i<a.length()+1;i++)
{
for(int ii=0;ii<a.length();ii++)
{
b.insert(i,a[ii]);
if (b == string(b.rbegin(), b.rend()))
{
cout << b << endl;aa=1;
break;
}
b.erase (b.begin()+i);
}
if(aa=1)break;
}
if(aa==0)
cout << "NA" << endl;
return 0;
}
See the documentation for std::string::insert. The version that takes a single char also needs a count argument.
b.insert(i,1,b[ii]);
You should use the following overload of std::string::insert:
basic_string& insert( size_type index, size_type count, CharT ch );
See http://en.cppreference.com/w/cpp/string/basic_string/insert
I have this class:
template<typename T> class Parser
{
public:
Parser() : count(0) {}
virtual void parse(const string&);
void get_token(void);
private:
T result;
char token;
string expression;
int count;
};
now had the class not been generic, had the result been say, a double, I would have used this method to detect numbers.
while((strchr("1234567890.",token))
{
/* add token to a "temp" string */
/* etc. etc. */
}
result = atof(temp.c_str());
But since result is generic, I can't use any method like atof and atoi etc.
What do I do?
Boost has this functionality built-in:
#include <boost/lexical_cast.hpp>
void Parser<T>::get_token() {
std::string token = ...;
result = boost::lexical_cast<T>(token);
}
Add exception handling as required.
Or, perhaps you don't want to use Boost for some reason:
void Parser<T>::get_token() {
std::string token = ...;
std::stringstream ss;
ss << token;
ss >> result;
}
Check the error state of ss as required.
More expansive answers may be found on this related question, though it discusses only int specifically.
Another generic template based Numeric To String converter. It takes ints and doubles.
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
template <class T>
inline std::string Numeric_To_String (const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
int main(int argc, char *argv[])
{
int i = 9;
double d = 1.2345;
string s;
cout <<"Generic Numeric_To_String( anyDatatype ) \n\n";
s = Numeric_To_String( i );
cout <<"int i to string : "<< s <<" "<< endl;
s = Numeric_To_String( d );
cout <<"double d to string : "<< s <<" "<< endl;
cout <<" \n";
return 0;
}
If you only have a hand full of types you want to parse, you can use template specialization:
template<>
void Parser<int>::parse(const string&)
{
result = atoi(string.c_str());
}
template<>
void Parser<float>::parse(const string&)
{
result = atof(string.c_str());
}
...
But this only works if you implement every convertion you need, of course.
With C++17 you can use the templated std::from_chars.
https://en.cppreference.com/w/cpp/utility/from_chars
#include <charconv>
#include <iostream>
template <typename Number>
auto stringTo(std::string_view str)
{
Number number;
std::from_chars(str.data(), str.data() + str.size(), number);
return number;
}
int main()
{
const auto str = std::string("42");
std::cout << stringTo<long>(str) << '\n';
std::cout << stringTo<double>(str) << '\n';
}
Check the return value of std::from_chars to detect errors.
const auto result = std::from_chars(...);
if (result.ec == std::errc::invalid_argument || result.ec == std::errc::result_out_of_range)
{
std::cout << "string to number error" << '\n';
}
More info and examples: https://www.bfilipek.com/2018/12/fromchars.html
GCC and clang don't yet support the floating point version of std::from_chars (August 2019).
Header file
#include <iostream>
#include <cstring>
const unsigned MaxLength = 11;
class Phone {
public:
Phone(const char *phone) {
setPhone(phone);
}
void setPhone(const char Phone[ ]);
const char* getPhone();
private:
char phone[MaxLength+1];
};
Cpp file
#include "Phone.h"
#include <iostream>
#include <ctype.h>
#include <cstring>
using namespace std;
bool checkNum(char num[]);
void Phone::setPhone(const char Phone[ ]) {
strncpy(phone, Phone, MaxLength);
phone[MaxLength] = '\0';
}
const char* Phone::getPhone() {
return phone;
}
int main() {
Phone i1("12345678901");
cout << i1.getPhone() << endl;
if (checkNum(i1.getPhone))
cout << "Correct" << endl;
else
cout << "Invalid Wrong" << endl;
}
bool checkNum(char num[]) {
bool flag = true;
if (isdigit(num[0]) == 0)
flag = false;
return flag;
}
When I tried to compile, I get this error:
error C3867: 'Phone::getPhone':
function call missing argument list;
use '&Phone::getPhone' to create a
pointer to member
I'm getting an error on this line "if (checkNum(i1.getPhone))". I created a Phone object and what I am trying to do is use the function checkNum to see if the first index of the array is a number. Am I referencing the object wrong? Should I use indirect selection operator instead? Any idea what I am doing wrong?
Thanks
You are missing a pair of parentheses after getPhone in if (checkNum(i1.getPhone)); it should be if (checkNum(i1.getPhone())).
The line:
if (checkNum(i1.getPhone))
should be
if (checkNum(i1.getPhone()))