how to sort a string in C++ using sort function - string

Why I'm getting error in this code
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string s1= "deepak";
cout << s1 << endl;
string s2= sort(s1.begin(), s1.end());
cout << s2 << endl;
return 0;
}
ERROR :
enter image description here
main.cpp:10:20: error: conversion from 'void' to non-scalar type 'std::string'
{aka 'std""__cxx11::basic_string,char>'} requested

The sort function sorts elements in a range, but it does not return the sorted string. You can sort s1 in-place:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
string s1= "deepak";
cout << s1 << endl;
sort(s1.begin(), s1.end());
cout << s1 << endl;
return 0;
}
if you want to return a sorted string:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string sortString(string s) {
string sortedString = s;
sort(sortedString.begin(), sortedString.end());
return sortedString;
}
int main()
{
string s1= "deepak";
cout << s1 << endl;
string sortedS1 = sortString(s1);
cout << sortedS1 << endl;
return 0;
}

Related

Why cout<<"Hello world" + 10; prints d in the output [duplicate]

The code successfully compiles it but I can't understand why, for certain values of number, the program crashes and for other values it doesn't. Could someone explain the behavior of adding a long int with a char* that the compiler uses?
#include <iostream>
int main()
{
long int number=255;
std::cout<< "Value 1 : " << std::flush << ("" + number) << std::flush << std::endl;
number=15155;
std::cout<< "Value 2 : " << std::flush << ("" + number) << std::flush << std::endl;
return 0;
}
Test results:
Value 1 : >
Value 2 : Segmentation fault
Note: I'm not looking for a solution on how to add a string with a number.
In C++, "" is a const char[1] array, which decays into a const char* pointer to the first element of the array (in this case, the string literal's '\0' nul terminator).
Adding an integer to a pointer performs pointer arithmetic, which will advance the memory address in the pointer by the specified number of elements of the type the pointer is declared as (in this case, char).
So, in your example, ... << ("" + number) << ... is equivalent to ... << &""[number] << ..., or more generically:
const char *ptr = &""[0];
ptr = reinterpret_cast<const char*>(
reinterpret_cast<const uintptr_t>(ptr)
+ (number * sizeof(char))
);
... << ptr << ...
Which means you are going out of bounds of the array when number is any value other than 0, thus your code has undefined behavior and anything could happen when operator<< tries to dereference the invalid pointer you give it.
Unlike in many scripting languages, ("" + number) is not the correct way to convert an integer to a string in C++. You need to use an explicit conversion function instead, such as std::to_string(), eg:
#include <iostream>
#include <string>
int main()
{
long int number = 255;
std::cout << "Value 1 : " << std::flush << std::to_string(number) << std::flush << std::endl;
number = 15155;
std::cout << "Value 2 : " << std::flush << std::to_string(number) << std::flush << std::endl;
return 0;
}
Or, you can simply let std::ostream::operator<< handle that conversion for you, eg:
#include <iostream>
int main()
{
long int number = 255;
std::cout<< "Value 1 : " << std::flush << number << std::flush << std::endl;
number = 15155;
std::cout<< "Value 2 : " << std::flush << number << std::flush << std::endl;
return 0;
}
Pointer arithmetic is the culprit.
A const char* is accepted by operator<<, but will not point to a valid memory address in your example.
If you switch on -Wall, you will see a compiler warning about that:
main.cpp: In function 'int main()':
main.cpp:6:59: warning: array subscript 255 is outside array bounds of 'const char [1]' [-Warray-bounds]
6 | std::cout<< "Value 1 : " << std::flush << ("" + number) << std::flush << std::endl;
| ^
main.cpp:8:59: warning: array subscript 15155 is outside array bounds of 'const char [1]' [-Warray-bounds]
8 | std::cout<< "Value 2 : " << std::flush << ("" + number) << std::flush << std::endl;
| ^
Value 1 : q
Live Demo

How to fix C++ argument of type"const char*" is incompatible with parameter of type"char*"

I'm using vs2019 and I have a problem the compiler give me an error however I cant solving that
please help me.
the error is : argument of type"const char*" is incompatible with parameter of type"char*"
Blockquote
*** #include <iostream>
#include<cstring>
using namespace std;
class part
{
public:
char partname[30];
int partnumber;
double cost;
void setpart(char pname[], int pn, double c)
{
strcpy_s(partname, pname);
partnumber = pn;
cost = c;
}
void showpart()const
{
cout << "\npartname : " << partname;
cout << "\npartnumber : " << partnumber;
cout << "\ncost($) : " << cost;
}
};
int main()
{
part part1, part2;
part1.setpart("handle bolt", 467, 4500);
part2.setpart("start lever", 549, 2300);
cout << "\nFirst part : "; part1.showpart();
cout << "\nSecond part : "; part2.showpart();
}***
The strings you are giving to setpart are const strings ( const char *) . But set part take a char * as parameter. Since pname will not be modified in your example you can replace void setpart(char pname[], int pn, double c) by void setpart(const char pname[], int pn, double c)

Banking System Program

I've slowly been building up my banking system and need help. First though a quick run through. 1. choose an existing account or new one. 2. after that it will display the options of withdraw, deposit or close account (close account is the least of my worries as of right now). I've been using two different text documents as well. One is "Accounts" where it will scan or add accounts the other is "Money" where it should keep track of money in each account. The question is how can I assign the money to each account?
I've head of struct arrays, however it is confusing me. If that is the best course of action I'm going to need a mini walkthrough by making comments on the coding for me to better understand it.
#include <iostream>
#include <fstream>
#include <iomanip>//used to move text
#include <string>
using namespace std;
int display(char& anwser);
void N_account(char& anwser, string& name);
int Exist(string& name_search, char& anwser, string name_from_file, char&
anwser2, string& money_deposit);
void deposit(string& money_deposit, char& anwser, char& anwser2, int& money_D);
void withdraw(string& withdraw_money, char& anwser, char& anwser2, int& money_D, string& total_money, int& money_W);
int main()
{
int start_money, money_D, money_W;
string name, name_search, name_from_file, money_deposit, withdraw_money, total_money;
char anwser, anwser2;
display(anwser);
if (anwser == '1')
{
N_account(anwser, name);
}
if (anwser == '2')
{
Exist(name_search, anwser, name_from_file, anwser2, money_deposit);
}
if (anwser2 == '1')
{
deposit(money_deposit, anwser, anwser2, money_D);
}
if (anwser2 == '2')
{
withdraw(withdraw_money, anwser, anwser2, money_D, total_money, money_W);
}
}
int display(char& anwser)
{
cout << setw(65) << "=================" << endl;
cout << setw(65) << "Banking Managment" << endl;
cout << setw(65) << "=================" << endl;
cout << setw(60) << "1.New account" << endl;
cout << setw(65) << "2.Existing account" << endl;
cin >> anwser;
return 0;
}
void N_account(char& anwser, string& name)
{
ofstream outfile;
outfile.open("Accounts.txt", std::ofstream::out | std::ofstream::app);
cout << "Enter in first and last name for new account:";
cin.ignore();
getline(cin, name);
outfile << name;
outfile << endl;
cout << "Account added" << endl;
outfile.close();
}
int Exist(string & name_search, char& anwser, string name_from_file, char& anwser2, string & money_deposit)
{
ifstream infile;
infile.open("Accounts.txt");
cout << "Enter in your account:";
cin.ignore();
getline(cin, name_search);
while (getline(infile, name_from_file))
{
if (name_from_file == name_search)
{
cout << "Account found: " << name_search << endl;
cout << "Choose what you would like to do" << endl;
cout << setw(56) << "1.Deposit" << endl;
cout << setw(57) << "2.Withdraw" << endl;
cout << setw(62) << "3.Close account" << endl;
cin >> anwser2;
return 0;
}
}
infile.close();
}
void deposit(string & money_deposit, char& anwser, char& anwser2, int& money_D)
{
ofstream O_file;
O_file.open("Money.txt", std::ofstream::out | std::ofstream::app);
cout << "Enter in how much you would like to deposit: ";
cin.ignore();
getline(cin, money_deposit);
money_D = stoi(money_deposit);//converts string into integer so that I may use basic operators such as less than or subtraction ect.
if (money_D < 0)
{
cout << "Error!" << endl;
system("pause");
exit(1);
}
O_file << money_deposit;
O_file << endl;
O_file.close();
}
void withdraw(string & withdraw_money, char& anwser, char& anwser2, int& money_D, string & total_money, int& money_W)
{
ofstream O_file;
O_file.open("Money.txt", std::ofstream::out | std::ofstream::app);
cout << "Enter in how much you would like to withdraw:";
cin.ignore();
getline(cin, withdraw_money);
money_W = stoi(withdraw_money);//converting string to integer
total_money = money_W - money_D;
O_file << total_money;
O_file << endl;
O_file.close();
}
When I choose the account named "John Doe" with a balance of $45.00 and wish to withdraw $20.00 I want the money for John Doe to decrease to $25.00 and NOT make a new line in the "Money" text document saying $20.00 like it has been doing.
The existing accounts are:
John Doe
Jane Doe
Travis Scott
William Smith
Patrick Michaels
Courtney Desmond
Their bank accounts are:
45.00
98.00
48.00
56.00
120.00`

reading from a file in visual c++

i am making a project in clr windows form using c++ and im having problem in retrieving the data from the file in a template(vector) when the form is loaded. my form has the button to save the code which calls the save method in the class coded as below. pls suggest what should be the code to retrieve the file, thank you.here record isthe name of the vector.
int men_database::save(int count)
{ ofstream out;
out.open("MALE.txt",ios::out|ios::binary);
if(!out)
return -1;
else
{for(int i=0;i<count;i++)
{out<<'\n'<<record[i].getid();
out<<'\n'<<record[i].getname();
out<<'\n'<<record[i].getsize();
out<<'\n'<<record[i].getcolor();
out<<'\n'<<record[i].getprice();
out<<'\n'<<record[i].getpic();
out<<'\n'<<record[i].getwatch();
}
out.close();
}//else ends
return 1;}
Here is some basic code for reading/writing. Though you might find something better elsewhere. \n is used as delimiter. Each record should have 2 fields (in yours it is 7 fields). Each field must be single-line string. Ps, you get more attention with c++ tag on your question.
int main()
{
{
ofstream f("data.txt");
f << "id1" << endl;
f << "name1" << endl;
f << endl;
f << "id2" << endl;
f << "name2" << endl;
f << endl;
}
{
ifstream f("data.txt");
string id;
string name;
while (f)
{
f >> id;
f >> name;
if (!f) break;
cout << "id: " << id << endl;
cout << "name: " << name << endl;
cout << endl;
}
}
return 0;
}

cin unintentionally skipping user input

I am trying to write a loop that validates user input, and then repeats if the input is bad. The input must be either a binary number (as a string) or a decimal number (as an int). I have seperate functions to validate this input, but they are not causing any trouble.
The problem arises when I select 1 or 2, and then willingly enter an invalid binary or decimal number. At this point, the do-while loop repeats successfully. The program prints another request for user input to cout, But when it comes time for the user to enter input, the program thinks that there is input in the console before I even enter anything. I believe this is a problem with whitespace/control characters in the buffer, but I am not sure how to fix it. I have tried using std::cin >> std::ws to clear any straggling white space, but no luck.
#include <iostream>
#include <string>
#include <limits>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
using std::cout;
using std::cin;
using std::endl;
using std::numeric_limits;
using std::max;
using std::streamsize;
using std::string;
//int toDecimal;
//true is is binary
bool validateBinary(const string &binaryNumber){
for(int i = 0; i < binaryNumber.length(); i++){
if((binaryNumber[i] != 1) && (binaryNumber[i] != 0)){
return false;
}
}
return true;
}
//true if is decimal
bool validateDecimal(){
return cin;
}
int main() {
int conversionType = 0; //we initialize conversionType to a default value of 0 to ensure the copiler it will always have a value
bool isBinary = false;
bool isDecimal = false;
string binaryNumberInput;
int decimalNumberInput;
do {
if(conversionType == 0){
cout << "Enter 1 to convert binary to decimal," << endl;
cout << "2 to convert decimal to binary, " << endl;
cout << "or 3 to exit the program: ";
std::cin >> std::ws; //to clear any whitespace fron cin
cin >> conversionType; //upon a second iteration, this value is read in before a user input is given
}
if(!cin || (conversionType != 1 && conversionType != 2)){
cout << "Incorrect input." << endl;
cin.clear(); //clear the fail bit
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //used to ignore not-numeric input
}
cout << "You have selected option " << conversionType << "." << endl;
if(conversionType == 1){
cout << "Please enter a binary number: ";
cin >> binaryNumberInput;
isBinary = validateBinary(binaryNumberInput);
if(!isBinary){
cout << "The numbered you entered is not a binary number!" << endl;
conversionType = 0;
}
}
if(conversionType == 2){
cout << "Please enter a decimal number: ";
cin >> decimalNumberInput;
isDecimal = validateDecimal(); //true if succeeded, meaning is a number
if(!isDecimal){
cout << "The numbered you entered is not a decimal number!" << endl;
conversionType = 0;
}
}
}
while((conversionType != 1 && conversionType != 2) || (isBinary == isDecimal));
return 0;
}
Rather than debug your current program you might want to consider using the standard library to simply things
#include <iostream>
#include <string>
#include <bitset>
#include <climits>
#include <limits>
template<typename T>
void get(T& value)
{
while (!(std::cin >> value)) {
std::cout << "Invalid input\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
int main()
{
std::cout << "Enter 1 to convert binary to decimal,\n" <<
"2 to convert decimal to binary\n";
int option;
if (std::cin >> option) {
switch (option) {
case 1: {
std::bitset<CHAR_BIT * sizeof(unsigned long long)> bits;
get(bits);
std::cout << bits.to_ullong() << '\n';
break;
}
case 2: {
unsigned long long i;
get(i);
std::cout << std::bitset<CHAR_BIT * sizeof i>(i) << '\n';
break;
}
}
}
}
If you want this to loop you should be able to add it back in again easily enough.

Resources