I want to make proggram wchich will be generete numbers in binary base from o to n, and i want thme all have the same numbers of chars.
That's the code:
#include <iostream>
#include <bitset>
#include <string>
#include <vector>
#include <cmath>
#include <stdio.h>
using namespace std;
vector<string> temp;
int BinaryNumbers(int number)
{
const int HowManyChars= ceil(log(number));
for(int i = 0; i<number; i++)
{
bitset<HowManyChars> binary(i);
temp.push_back(binary.to_string());
}
}
int main(){
BinaryNumbers(3);
for(int i=0; i<temp.size();i++)
{
cout<<temp[i]<<endl;
}
return 0;
}
My problem is that I can't set bitset<> number(HowManyChars)"[Error] 'HowManyChars' cannot appear in a constant-expression"
A possible solution is to use the maximum sized bitset to create the string. Then only return the last count characters from the string.
In C++17 there is a new function to_chars.
One of the functions (1), takes the base in the last parameter.
// use numeric_limits to find out the maximum number of digits a number can have
constexpr auto reserve_chars = std::numeric_limits< int >::digits10 + 1; // +1 for '\0' at end;
std::array< char, reserve_chars > buffer;
int required_size = 9; // this value is configurable
assert( required_size < reserve_chars ); // a check to verify the required size will fit in the buffer
// C++17 Structured bindings return value. convert value "42" to base 2.
auto [ ptr, err ] = std::to_chars( buffer.data(), buffer.data() + required_size, 42 , 2);
// check there is no error
if ( err == std::errc() )
{
*ptr = '\0'; // add null character to end
std::ostringstream str; // use ostringstream to create a string pre-filled with "0".
str << std::setfill('0') << std::setw(required_size) << buffer.data();
std::cout << str.str() << '\n';
}
Related
I am a beginner and I just need a bit of help on why I getline is showing an error:
this is what I have so far
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>
using namespace std;
const double TAX_RATE = 0.0825;
const int MAX_ITEMS = 1000;
const int MAX_TRANSACTIONS = 100;
int main(int argc, char const *argv[]){
string fname = "";
int itemCnt = 0, start = 0, end = 0;
int ids[MAX_ITEMS], qtys[MAX_ITEMS];
double costs[MAX_ITEMS], subtotals[MAX_TRANSACTIONS],
taxes[MAX_TRANSACTIONS], totals[MAX_TRANSACTIONS];
string names[MAX_ITEMS], paymentTypes[MAX_ITEMS], payments[MAX_ITEMS];
ifstream iFile;
if ( argc != 2 ) {
cout<<"usage: "<< argv[0]<< " <file name>" <<endl;
return 0;
} else {
iFile.open(argv[1]);
}
if (!iFile) {
cout<<"Error: Invalid file name"<<endl;
cin.clear();
}
while (!iFile.eof())
{
getline(iFile,str); //this isn't working
int commaLoc = str.find(',');
ids[itemCnt]= str.substr(0,commaLoc);
str = str.substr(commaLoc +1, str.length());
//string to int I'm not sure how to do I know its something with stoi() but not sure how to format it
}
return 0;
}
I am able to get the file to open but I'm not sure why getline isn't working it keeps saying something like
no instance of overload function
My csv file looks like:
1,Laptop,799.99,1,cash,1100
I need it to read the first number and because Its a string i don't know how to save it as an int
Multiple errors. First there is nothing called 'str' in your program. I will guess its just a string used as a temp buffer
do not do this (!File.eof) it doesnt do what you think.
while (iFile)
{
string str; <<<<<==== added
getline(iFile,str); //this isn't working <<<===is now
int commaLoc = str.find(',');
Next this line doesnt work because ids are ints and substring returns a string.
// ids[itemCnt]= str.substr(0,commaLoc);
ids[itemCnt]= stoi(str.substr(0,commaLoc)); <<<<==== fixed
str = str.substr(commaLoc +1, str.length());
}
I strongly recommend you use std::vector instead of c-style fixed size arrays. Takes 5 minutes to learn how to use them and they have huge benefits. If you must use fixed size arrays use std::array instead of c-style
You can read a string and try to convert it to a number in different ways. For example, since C++17, you can use from_chars. One of its overloads:
Receives a pair of begin and end char pointers, and an int variable,
tries to parse an int number, and
and returns the parsed number, together with a pointer to the first character that wasn't part of the match.
int i{};
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), i);
if (ec == std::errc{}) { /* do something with i */} else { /* error */ }
[Demo]
Full code (using a istrinstream instead of a ifstream):
#include <charconv> // from_chars
#include <iomanip>
#include <iostream>
#include <sstream> // istringstream
#include <system_error> // errc
constinit const int MAX_ITEMS = 10;
int main() {
std::istringstream iss{
"1,Laptop,799.99,1,cash,1100\n"
"2,PC,688.88,2,card,1101\n"
"blah,Keyboard,39.00,3,cash,1102"
};
size_t itemCnt{};
int ids[MAX_ITEMS]{};
std::string str{};
while (std::getline(iss, str)) {
// Parse counter
int i{};
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), i);
if (ec == std::errc{}) {
ids[itemCnt] = i;
// Remaining string
std::string remaining_string{ str.substr(ptr - str.data() + 1) };
std::cout << ids[itemCnt] << ", " << remaining_string << "\n";
}
else {
std::cout << "Error: invalid counter.\n";
}
++itemCnt;
}
}
// Outputs:
//
// 1, Laptop,799.99,1,cash,1100
// 2, PC,688.88,2,card,1101
// Error: invalid counter.
so I want to do the simplest thing in c++ , reverse a string (store the new string) and than print it
my code is :
char a[size] , reverse[size];
strcpy(a,"dlow olleh " );
for (int i = 0 ; i <= strlen(a); i++) {
reverse[i]= a[strlen(a)-i];
}
cout << reverse ;
I must note that when
cout << reverse[i] ;
is inside the for loop every thing wotks fine , but when I wwant to print it as a string it just don't , I cant under stand what ive missed
cout << reverse[i] ;
what am i doing wrong?
You are using arrays of char and functions of the C Standard Library to manipulate strings in C++.
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string foo{ "Hello, World!" };
std::string bar{ foo };
std::reverse(bar.begin(), bar.end());
std::cout << '\"' << foo << "\" ==> \"" << bar << "\"\n";
}
If – for some reason beyond my comprehension – you *have to* do it by foot, do it in an idiomatic way and provide an interface that takes a pair of iterators:
#include <algorithm>
void str_reverse(char *begin, char *end)
{
while (begin < end)
std::swap(*begin++, *--end);
}
// ...
#include <cstring>
// ...
char foo[]{ "Hello, World!" };
str_reverse(foo, foo + std::strlen(foo));
If you can't use <algorithm> for whatever reason implement your own swap():
template<typename T>
void swap(T &a, T &b)
{
T tmp{ a };
a = b;
b = tmp;
}
In this loop
for (int i = 0 ; i <= strlen(a); i++){
reverse[i]= a[strlen(a)-i];
you are accessing characters beyond the actual characters of the strings.
For example when i is equal to 0 you are coping the terminating zero character from the string a into the first position of the string reverse.
reverse[0]= a[strlen(a)-0];
the code can be written simpler without for example reduntant calls of the function strlen.
char a[size], reverse[size];
strcpy( a, "dlrow olleh" );
size_t i = 0;
for ( size_t n = strlen( a ); i < n; i++ )
{
reverse[i] = a[n - i - 1];
}
reverse[i] = '\0';
std::cout << reverse << '\n';
Pay attention to that there is the standard algorithm std::reverse_copy that does the same task.
Below there is a demonstrative program.
#include <iostream>
#include <algorithm>
#include <cstring>
int main()
{
const size_t SIZE = 20;
char a[SIZE], reverse[SIZE];
std::strcpy( a, "dlrow olleh" );
std::cout << a <<'\n';
auto it = std::reverse_copy( a, a + strlen( a ), reverse );
*it = '\0';
std::cout << reverse <<'\n';
return 0;
}
The program output is
dlrow olleh
hello world
The first you copy when reversing the string is in fact the null terminator so when you are printing it to console it will not show up since the null terminator is the first in the array so you want to do this instead
int size = 12;
char a[12], reverse[12];
strcpy(a, "dlow olleh ");
for (int i = 0; i < strlen(a); i++) {
reverse[i] = a[strlen(a) - (i+1)];
}
reverse[strlen(a)] = '\0';
cout << reverse;
I'm new to programming so I'm sorry if my question is hard to understand.
I have a string modelAnswer as such
string modelAnswer = "ABABACDA";
So it's supposed to be the answers to a quiz and I'm trying to make it so that if user's input is
string studentAnswer = "ABADBDBB"; for example the program will show that I have gotten 3 points as the first three letters of the studentAnswer string matches the modelAnswer.
You can use standard algorithm std::inner_product as for example
#include <iostream>
#include <string>
#include <numeric>
#include <functional>
int main()
{
std::string modelAnswer( "ABABACDA" );
std::string studentAnswer( "ABADBDBB" );
auto n = std::inner_product( modelAnswer.begin(), modelAnswer.end(),
studentAnswer.begin(), size_t( 0 ),
std::plus<size_t>(), std::equal_to<char>() );
std::cout << n << std::endl;
return 0;
}
The program output is
3
It is assumed that the strings have the same length. Otherwise you should use the less string as the first pair of arguments.
For example
#include <iostream>
#include <string>
#include <numeric>
#include <algorithm>
#include <functional>
#include <iterator>
int main()
{
std::string modelAnswer( "ABABACDA" );
std::string studentAnswer( "ABADBDBB" );
auto n = std::inner_product( modelAnswer.begin(),
std::next( modelAnswer.begin(), std::min( modelAnswer.size(), studentAnswer.size() ) ),
studentAnswer.begin(), size_t( 0 ),
std::plus<size_t>(), std::equal_to<char>() );
std::cout << n << std::endl;
return 0;
}
If you are using standard strings, with the proper includes (Mainly #include <string>), you can write a simple for loop to iterate over each character, comparing them.
std::string answer = "ABABACDA";
std::string stringToCompare = "ABADBDBB";
int score = 0;
for (unsigned int i = 0; (i < answer.size()) && (i < stringToCompare.size()); ++i)
{
if (answer[i] == stringToCompare[i])
{
++score;
}
}
printf("Compare string gets a score of %d.\n", score);
The above code works for me, printing the following result:
Compare string gets a score of 3.
Using a stringstream, you can push one character at a time into temporary variables and test for equivalence in a loop.
#include <iostream>
#include <string>
#include <sstream>
int main() {
std::istringstream model("ABABACDA");
std::istringstream student("ABADBDBB");
int diff = 0;
char m, s;
while ((model >> m) && (student >> s))
if (m != s) diff++;
std::cout << diff << std::endl; // 5
return 0;
}
So I got asked this on a skills test for an internship, and at the time it completely baffled me. I have some code now that I thought should work, but isn't assigning the correct values to the string.
#include <iostream>
#include <string>
using namespace std;
int main()
{
// declarations
int i = 0, num= 63;
string b="";
while (num != 0)
{
i = num % 10;
b.insert(0,i + 48 + "");
num = num/10;
}
cout << b << endl;
return 0;
}
With "num" being the integer value (I just used 63 as an example)
EDIT:: I incorrectly paraphrased, I could not use any function that did an int to string conversion for me, not that I couldn't use the string library, my mistake.
Change the insert line to
b.insert(0, 1, '0' + i);
This will insert the character obtained from adding i to '0' once at index 0 in the string.
Explanation of why your code isn't working:
b.insert(0,i + 48 + "");
the line above is calling
basic_string::insert( size_type index, const CharT* s );
where the pointer is being determined by adding 48 + i to the address of the "" string literal, resulting in garbage.
I would suggest recursive function:
std::string f( int val )
{
if ( val >= 10 )
return f( val / 10 ) + ( char )( val % 10 + '0' ) ;
else
return std::string( 1, '0' + val ) ;
}
Usage:
std::cout << f( 63 ) << std::endl ;
Note that this function should append to your string instead of using very expensive shifting (and putting in the front of the string.)
It is worth noting that there are other errors with the code. For example, the transformation doesn't work for num == 0. Here is a better version:
#include <iostream>
#include <algorithm>
#include <string>
#include <cstdlib>
int main(int ac, char* av[])
{
int num(ac == 1? 0: std::atoi(av[1]));
std::string b;
do
{
b.push_back((num % 10) + '0');
num /= 10;
}
while (num != 0);
std::reverse(b.begin(), b.end());
std::cout << b << '\n';
return 0;
}
Very simple solution: Use string streams. In this case, an output string stream:
#include <iostream>
#include <string>
#include <sstream>
std::string IntToString(int value) {
std::ostringstream ss;
ss << value;
return ss.str();
}
const char* IntToCString(int value) {
std::ostringstream ss;
ss << value;
return ss.str().c_str();
}
Here's some code that doesn't use any libraries and doesn't perform allocations. Instead, the user is expected to provide a buffer that's large enough, and she receives a pointer to the beginning of the result string in return:
char * format(unsigned int n, char * buf, std::size_t len)
{
if (len == 0) return NULL;
char * p = buf + len;
*--buf = 0;
while (n && p > buf)
{
*--buf = '0' + (n % 10);
n /= 10;
}
return n == 0 ? p : NULL;
}
Embedded people might like this especially because the function doesn't do anything outside your control.
Usage:
char buf[100];
char * s = format(12345, buf, sizeof buf);
if (s) { printf("Formatted: %s\n", s); }
I would like to generate consecutive C++ strings like e.g. in cameras: IMG001, IMG002 etc. being able to indicate the prefix and the string length.
I have found a solution where I can generate random strings from concrete character set: link
But I cannot find the thing I want to achieve.
A possible solution:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
std::string make_string(const std::string& a_prefix,
size_t a_suffix,
size_t a_max_length)
{
std::ostringstream result;
result << a_prefix <<
std::setfill('0') <<
std::setw(a_max_length - a_prefix.length()) <<
a_suffix;
return result.str();
}
int main()
{
for (size_t i = 0; i < 100; i++)
{
std::cout << make_string("IMG", i, 6) << "\n";
}
return 0;
}
See online demo at http://ideone.com/HZWmtI.
Something like this would work
#include <string>
#include <iomanip>
#include <sstream>
std::string GetNextNumber( int &lastNum )
{
std::stringstream ss;
ss << "IMG";
ss << std::setfill('0') << std::setw(3) << lastNum++;
return ss.str();
}
int main()
{
int x = 1;
std::string s = GetNextNumber( x );
s = GetNextNumber( x );
return 0;
}
You can call GetNextNumber repeatedly with an int reference to generate new image numbers. You can always use sprintf but it won't be the c++ way :)
const int max_size = 7 + 1; // maximum size of the name plus one
char buf[max_size];
for (int i = 0 ; i < 1000; ++i) {
sprintf(buf, "IMG%.04d", i);
printf("The next name is %s\n", buf);
}
char * seq_gen(char * prefix) {
static int counter;
char * result;
sprintf(result, "%s%03d", prefix, counter++);
return result;
}
This would print your prefix with 3 digit padding string. If you want a lengthy string, all you have to do is provide the prefix as much as needed and change the %03d in the above code to whatever length of digit padding you want.
Well, the idea is rather simple. Just store the current number and increment it each time new string is generated. You can implement it to model an iterator to reduce the fluff in using it (you can then use standard algorithms with it). Using Boost.Iterator (it should work with any string type, too):
#include <boost/iterator/iterator_facade.hpp>
#include <sstream>
#include <iomanip>
// can't come up with a better name
template <typename StringT, typename OrdT>
struct ordinal_id_generator : boost::iterator_facade<
ordinal_id_generator<StringT, OrdT>, StringT,
boost::forward_traversal_tag, StringT
> {
ordinal_id_generator(
const StringT& prefix = StringT(),
typename StringT::size_type suffix_length = 5, OrdT initial = 0
) : prefix(prefix), suffix_length(suffix_length), ordinal(initial)
{}
private:
StringT prefix;
typename StringT::size_type suffix_length;
OrdT ordinal;
friend class boost::iterator_core_access;
void increment() {
++ordinal;
}
bool equal(const ordinal_id_generator& other) const {
return (
ordinal == other.ordinal
&& prefix == other.prefix
&& suffix_length == other.suffix_length
);
}
StringT dereference() const {
std::basic_ostringstream<typename StringT::value_type> ss;
ss << prefix << std::setfill('0')
<< std::setw(suffix_length) << ordinal;
return ss.str();
}
};
And example code:
#include <string>
#include <iostream>
#include <iterator>
#include <algorithm>
typedef ordinal_id_generator<std::string, unsigned> generator;
int main() {
std::ostream_iterator<std::string> out(std::cout, "\n");
std::copy_n(generator("IMG"), 5, out);
// can even behave as a range
std::copy(generator("foo", 1, 2), generator("foo", 1, 4), out);
return 0;
}
Take a look at the standard library's string streams. Have an integer that you increment, and insert into the string stream after every increment. To control the string length, there's the concept of fill characters, and the width() member function.
You have many ways of doing that.
The generic one would be to, like the link that you showed, have an array of possible characters. Then after each iteration, you start from right-most character, increment it (that is, change it to the next one in the possible characters list) and if it overflowed, set it to the first one (index 0) and go the one on the left. This is exactly like incrementing a number in base, say 62.
In your specific example, you are better off with creating the string from another string and a number.
If you like *printf, you can write a string with "IMG%04d" and have the parameter go from 0 to whatever.
If you like stringstream, you can similarly do so.
What exactly do you mean by consecutive strings ?
Since you've mentioned that you're using C++ strings, try using the .string::append method.
string str, str2;
str.append("A");
str.append(str2);
Lookup http://www.cplusplus.com/reference/string/string/append/ for more overloaded calls of the append function.
it's pseudo code. you'll understand what i mean :D
int counter = 0, retval;
do
{
char filename[MAX_PATH];
sprintf(filename, "IMG00%d", counter++);
if(retval = CreateFile(...))
//ok, return
}while(!retval);
You have to keep a counter that is increased everytime you get a new name. This counter has to be saved when your application is ends, and loaded when you application starts.
Could be something like this:
class NameGenerator
{
public:
NameGenerator()
: m_counter(0)
{
// Code to load the counter from a file
}
~NameGenerator()
{
// Code to save the counter to a file
}
std::string get_next_name()
{
// Combine your preferred prefix with your counter
// Increase the counter
// Return the string
}
private:
int m_counter;
}
NameGenerator my_name_generator;
Then use it like this:
std::string my_name = my_name_generator.get_next_name();