Where is this code wrong?
It won't let me cast strlen(s) into an int that I can iterate it until i is equal to the length of the string.
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int main()
{
string s;
cin >> s;
for (int i = 0; int n = (int)strlen(s); i < n, i++)
{
cout << s[i] << endl;
}
}
The problem is not that the result of strlen can't be cast to an int, but that strlen can't be used with std::string.
strlen is for "C strings", zero-terminated arrays of characters.
std::string has a size member function:
int main()
{
string s;
cin >> s;
for (int i = 0; i < s.size(); i++)
{
cout << s[i] << endl;
}
}
There is nothing inside the C header <string.h> that applies to std::string.
A reference can be useful.
strlen is for char arrays.
std::string has a member function called size and length.
If you still want to use strlen, you can call c_str and pass the returned string to strlen.
std::size_t length = s.size();
for (int i = 0; i < length; ++i)
You can also iterate over the elements of the std::string:
for (std::string::iterator itr = s.begin(); itr != s.end(); ++itr)
{
std::cout << *itr << std::endl;
}
Because strlen expects to get a char const* as it's argument. You should probably use s.size() instead as s is a std::string.
In addition you should probably not compute strlen inside a loop like that due to performance issues (s.size on the other hand should be able to complete in O(1) time so it would be OK).
Then there's a few other problems with your program, already at line one. You can't include a file by using #include //iostream, you should use #include <iostream> instead.
Second you cannot declare a variable in the condition of a for loop as you try to do, and you probably shouldn't assign instead of comparing (one equal sign is not the same as two). You should have written for( int i = 0; i != s.size(); i++ )
Third you shouldn't do the check in the update expression in the for construct. What goes there will only be evaluate to update the loop variables and such and the truth value will be disregarded.
Overall I think you should pick up an introduction to C++ book or find a good tutorial online. Your code simply has to much problems to conclude that you have learnt even the most basic C++.
Related
#include<stdio.h>
#include <string>
#include <stdint.h>
#include<sstream>
#include <stdlib.h>
using namespace std;
string IntToString(int&);
int main()
{
char output[45] = "0";
int str = 0;
char enc[8] = "0";
int enc1[1] = { 0 };
int arrayLength = sizeof(enc1) / sizeof(enc1[0]);
string strs;
for (int i = 0; i <= 100000; i++)
{
int enc1[1];
enc1[0]={ i };
for (int i = 0; i < arrayLength; i++)
{
int& temp = enc1[i];
strs+= IntToString(temp);
enc == strs.c_str();
}
if (atoi(enc)+46*2 == 3251)
{
output == enc;
}
}
printf("%s", output);
}
string IntToString(int& i)
{
string s;
stringstream ss(s);
ss << i;
return ss.str();
}
This is what I want to convert an integer array into a string by continuously increasing, and then convert the string into a number according to the atoi function as a function,I've looked at tutorials on using stoi and I'm not sure what I'm doing wrong. I would appreciate it if you could help me
You code has a lot of problems...
As for your question, if you want to convert an integer into a string, just use std::string your_string = std::to_string(you_integer);.
Then some of the problems that you have:
enc == strs.c_str(); <- the operator == is not the assignment operator. What you do here is that you compare two pointers, that is probably not what you intended, because you don't even check the result of the comparison.
Don't use the loop index i in a nested loop when it is already in use.
Don't use char arrays in C++ unless you have an explicit reason to use it. Even if you are worried about performance, for small strings you can look at std::string as a char array. And you cannot have large strings, because the largest possible integer value represented as a string still counts as a small string.
If you have arrays with constant size, use #define ARRAY_SIZE 15 or something like this rather than what you did.
Don't pass primitive types by reference if you don't have to. As far as I know, only double and long long are larger (on most platforms) than a reference, so you won't gain anything from passing by reference. On the contrary, the optimizer won't like you if you use unnecessary aliasing.
I have to say, I am not sure that I understood your goal correctly. But as I understood it, you want to convert an integer array into a string then to an integer. I am not quiet sure why you would want to do that, but that's on me.
The following code does what I think you wanted. It converts an integer array into an integer by first converting it into a string. But even so, you cannot increase the array size much, because std::stoi will throw an std::out_of_range exception when the number in the string would be too large for an integer.
#include <string>
#include <iostream>
#define ARRAY_SIZE 9
int int_arr_to_int (const int * const arr) {
std::string str;
for (size_t i = 0; i < ARRAY_SIZE; ++i) {
str += std::to_string(i);
}
return std::stoi(str);
}
int main(int argc, char* argv[]) {
int arr[15] = { 0 };
for (size_t i = 0; i < ARRAY_SIZE; ++i) {
arr[i] = i;
}
std::cout << int_arr_to_int(arr) << std::endl;
return 0;
}
To find all sequences of fixed length which contain only 0 and 1 I use this code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
void print_array(vector<string> arr) {
cout << '[';
int n = arr.size();
for (size_t i = 0; i < n; i++) {
cout << arr[i];
if (i < (n - 1)) {
cout << ", ";
}
}
cout << ']' << endl;
}
vector<string> get_variants(int n) {
vector<string> result = {"0", "1"};
vector<string> temp;
temp.reserve(2);
result.reserve(2);
for (int i=0; i < (n - 1); ++i) {
copy(result.begin(), result.end(), temp.end()); // [1]
for (int j=0; j < result.size(); ++j) {
temp[j] += "0";
result[j] += "1";
}
copy(temp.begin(),temp.end(), result.end());
temp.clear();
}
return result;
}
int main(int argc, char const *argv[]) {
int n;
cin >> n;
vector<string> maybe = get_variants(n);
print_array(maybe);
return 0;
}
But vector temp is empty, before copying in line which I marked [1] and after. So, my program's output was [0111, 1111]. What I'm doing wrong?
A more straightforward way than using std::copy is the use of .insert():
temp.insert(temp.end(), result.begin(), result.end()); //1
...
result.insert(result.end(), temp.begin(), temp.end()); // 2nd copy
You are writing to temp.end() and result.end(). These iterators represent "one past the end", and therefore writing to these iterators is Undefined Behavior.
You seem to be looking for std::back_inserter. This will create an iterator that will insert a new element to your container when it is written through.
std::copy(result.begin(), result.end(), std::back_inserter(temp));
While this answers the posted question, there remain other errors in your code leading to Undefined Behavior.
Trying to compile your program with a C++ compiler will not work, because you include #include <bits/stdc++.h>which is a non tC++ standard compliant header.
You should never include this file.
You are using typical competitive programming stuff, but including all C++ headers and not use them will eat up Compile time for no good reason.
Then, you typedef the typical competitive programming abbreviations. 2 of them, you do not use. Then there is no reason to define them.
I recommend to not do this any longer. And in C++, please use the using statement.
Then, although you want to be fast, you pass arr by value to your print function. This will copy the whole vector.
You assign/compare a lot of int with unsigned int values. This you should not do.
Additionally: Please use meaningful variable names and write comments. The more the better.
Regarding your specific bug. Both std::copy statements use end iterator as target. End is end. It is past the end of the vector. Please use std::back_inserter instead.
Regarding the algorithm. I took a while for me to realize that you basically want to create binary numbers. Nothing else. Unfortunately you translated that in a very complicated way.
Normally, you just would count from 0 to 2^n-1 and then show the data. Thats all. Becuase the numbers may be of arbitraty length, we will use manual addition of digits like in scholl on a peice of paper. Very simple.
Everthing then biols down to some lines of code.
Please see:
#include <iostream>
#include <vector>
int main() {
// Read length of binary number to create and validate input
if (int numberOfDigits{}; (std::cin >> numberOfDigits and numberOfDigits > 0)) {
// Here we will store the binary digits, so 0s or 1s
std::vector<int> digits(numberOfDigits,0);
// Som printing helper
std::cout << '[';
bool printComma{};
// We need to print 2^n possible combinations
for (int i = 0; i < (1 << numberOfDigits); ++i) {
// Print comma, if need
if (printComma) std::cout << ','; printComma = true;
// Print all digits of the binary number
for (const int d : digits) std::cout << d;
// Calculate next binary number
int carry = 0;
for (int index=numberOfDigits -1; index >=0; --index) {
const int sum = digits[index] + ((index == (numberOfDigits - 1)?1:0)) + carry;
carry = sum / 2;
digits[index] = sum % 2;
}
}
std::cout << ']';
}
}
If there should be questions, then I am happy to answer.
The purpose of this code is to insert an x in between repeating letters. For example, if I were to input "CoolBoolFallmoose", the output would be "CoxolBoxolFalxlmoxose".
The code is also supposed to make an even number of pairs of letters, so if there is an odd amount of characters, an x is added to the end of the string. An example for this would be if we had "ball", it would become "balxlx" to make even pairs: "ba" "lx" "lx".
This is the code I have so far:
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(){
string cipher, plain, paired = "";
cout << "input plaintext(no spaces, lowercase):\n";
cin >> plain;
for (int i=0;i<plain.length();i++){
if (plain[i]==plain[i+1]){
plain.insert(i,'x');
}
paired[i]=paired[i];
cout<<paired[i];
}
if (paired.length() % 2!= 0){
paired=+'x';
}
cout<<paired<<endl;
return 0;
}
The output I get is just the same as my input, no "x" added in any place.
The issue I am having is, every time I try to use the append() or insert() function for strings, I get an error from my compiler, which is xCode. Is there another way to solve this code?
EDIT: The error says:
No matching member function to call for insert
It also comes up for append().
I don't really know what you wanted to do with this part:
paired[i]=paired[i];
cout<<paired[i];
but otherwise the logic is good. Here is my take on it, x is a counter:
#include <iostream>
#include <string>
using namespace std;
int main(){
string m,n;
int x = 0;
cout << "Input: " << endl;
getline(cin, m);
for(int i = 0;i < m.length();i++){
x++;
n = n + m[i];
if(m[i] == m[i+1]){
n = n + 'x';
x++;
}
}
if((x % 2) != 0){
n = n + 'x';
}
cout << n;
return 0;
}
If you look at the available overloads of std::string::insert(), you will see that your statement plain.insert(i,'x'); does not match any of them, hence the compiler error. The overloads that takes a single char require either:
an index and a count (you are omitting the count)
an iterator and an optional count
There is, however, a couple of overloads that take just an index and a value, but they require a const char* or a std::string, not a single char.
Also, paired[i]=paired[i]; is a no-op. Except in your case, since paired has a size() of 0 since you never append anything to paired, so actually any access to paired[...] is undefined behavior.
Try this instead:
#include <iostream>
#include <string>
using namespace std;
int main(){
string plain, paired;
cout << "input plaintext(no spaces, lowercase):\n";
cin >> plain;
paired = plain;
for (string::size_type i = 1; i < paired.size(); ++i){
if (paired[i] == paired[i-1]){
paired.insert(i, 1, 'x');
// or: paired.insert(paired.begin()+i, 'x');
// or: paired.insert(i, "x");
// or: paired.insert(i, string{'x'});
// or: paired.insert(paired.begin()+i, {'x'});
++i; // skip the x just inserted
}
}
if (paired.size() % 2 != 0){
paired += 'x';
}
cout << paired << endl;
return 0;
}
Demo
A couple of points
First, Although the string.insert function says it takes an int as its first argument it really wants an iterator in this case.
Second, you are inserting elements into your "plain" string which increases its length and you have plain.length within your loop so you create an infinite loop.
Third, insert inserts BEFORE the index so you need to add 1 to I.
The code below will work for your loop:
Int len = plain.length();
Int count = 0;
for (int i = 0; i < len + count; i++)
{
If (plain[i] == plain[i + 1])
{
plain.insert(plain.begin() + (i +1), 'X');
++count;
}
}
cout << plain;
And as, mentioned below, if you want to handle spaces you can use getline(cin, plain) instead of cin.
Good night to everyone!
I am trying to compare 2 strings in c++, using the .compare() function. However, the result i see is not what is expected from this function. Take a look please.
#include <iostream>
#include <string>
using namespace std;
class game
{
private:
char mtx [2][2];
int i = 0, j = 0, a = 0;
std::string matrix1;
std::string xis = "xx";
public:
game();
char winner();
};
game::game()
{
for(i = 0; i<2; i++)
{
for (j = 0; j<2; j++)
{
mtx [i][j] = 'x';
}
}
char game::winner()
{
i = j = 0;
for (j=0; j<2; j++)
{
matrix1 = mtx [0][j]; //string recieve the first line of the matrix.
}
a = xis.compare(matrix1);
cout << a<<endl;
}
int main(void) {
velha game;
velha.winner;
}
When I compile the program the a value printed is neither a '0' nor any other integers. It prints #85.
Notes: I've also tried to use <string.h> and strncmp() using a char array instead of std:: string but with no success.
I was trying to create a game class and I did not put here the other methods because they are not relevant). (also, I use Linux Mint to code)
Can anyone help me please in this context?
#include <iostream>
#include <string>
int main(void) {
std::string first, second;
std::cout << "First String: ";
getline(std::cin, first);
std::cout << "Second Line: ";
getline(std::cin, second);
if (first == second)
std::cout << "Same strings.";
else
std::cout << "Different strings.";
return 0;
}
Explanation: Just taken two strings from the user and matches straightforward without using any much complexity, just used a conditional operation.
For string compare and even strcmp the value returned will be the lexicographical comparison of the two strings. The following are the values you should see:
negative if *this appears before the character sequence specified by the argument in lexicographical order
0 if *this and the character sequence specified are equivalent
positive if *this appears after the character sequence specified by the argument in lexicographical order
If you are looking to get the first column of your matrix, do a string comparison on, you would want to do something like:
for(int col = 0; col < 2; col++) {
matrix1.push_back(mtx[0][col]); // This appends that character to the end of your string
}
If you are looking to get the rows you can just do the following:
matrix1 = mtx[0];
// To ensure you have a null terminated string
// Otherwise you will have garbage.
matrix1.replace(matrix1.begin() + 2, matrix1.end(), 1, "\0");
I have ran through the test with comparing that the matrix contains "xx" and ended up receiving 0. However a much easier comparison is to us operator == to simply return a true or false value.
#include <iostream>
using namespace std;
int main(){
int findMax(int *);
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
int mval = findMax(values);
cout << values << endl << mval;
return 0;
}
//Function to find the maximum value in the array
int findMax(int arr[]){
int localmax = 0;
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
if(arr[i] > localmax){
localmax = arr[i];
}
}
return localmax;
}
The purpose of this program is for the user to input a space-separated series of values ended by a 0. That array is then to be analyzed to find the max. I figured out how to convert what is originally a char[] into an int[] so that I can use the findMax() function on it without error but the sorting loop seems to have a problem of its own and when "cout << values << endl << mval;" is called, it returns only a memory address instead of what should be a non-spaced sequence of ints. Can anybody explain what I am doing wrong? It seems that I may have made some mistake using the pointers but I cannot figure out what.
Printing values won't print the contents of the array as you expect, it will print the memory location of the first element of the array.
Try something like this instead:
#include <iterator>
#include <algorithm>
// ...
copy(&values[0], &values[MAX], ostream_iterator(cout, " "));
Sorry I can't post actual working code, but your original post is a mess with many syntax and syntactic errors.
EDIT: In the interest of being more complete and more approachable & understandable to beginners, I've written a small program that illustrates 4 ways to accomplish this.
Method 1 uses copy with an ostream_iterator as I've done above.
Method 2 below is probably the most basic & easiest to understand.
Method 3 is a C++0x method. I know the question is tagged C++, but I thought it might be educational to add this.
Method 4 is a C++ approach using a vector and for_each. I've implemented a functor that does the dumping.
Share & Enjoy
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
struct dump_val : public unary_function<int,void>
{
void operator()(int val)
{
cout << val << " ";
}
};
int main(){
int vals[5] = {1,2,3,4,5};
// version 1, using std::copy and ostream_iterator
copy(&vals[0], &vals[5], ostream_iterator<int>(cout, " "));
cout << endl;
// version 2, using a simple hand-written loop
for( size_t i = 0; i < 5; ++i )
cout << vals[i] << " ";
cout << endl;
// version 3, using C++0x lambdas
for_each(&vals[0], &vals[5], [](int val)
{
cout << val << " ";
}
);
cout << endl;
// version 4, with elements in a vector and calling a functor from for_each
vector<int> vals_vec;
vals_vec.push_back(1);
vals_vec.push_back(2);
vals_vec.push_back(3);
vals_vec.push_back(4);
vals_vec.push_back(5);
for_each( vals_vec.begin(), vals_vec.end(), dump_val() );
cout << endl;
}
When you pass around an array of X it's really a pointer to an array of X that you're passing around. So when you pass values to cout it only has the pointer to print out.
You really should look into using some of the standard algorithms to make your life simpler.
For example to print all the elements in an array you can just write
std::copy(values, values+MAX, std::ostream_iterator<int>(std::cout, "\n"));
To find the max element you could just write
int mval = *std::max_element(values, values+MAX);
So your code becomes
#include <iostream>
using namespace std;
int main(){
const int MAX = 100;
int values[MAX];
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
char *helper;
// Clean input array and transfer it to values.
for(int i = 0; i < (MAX) && ivals[i] != 0; i++){
helper = ivals[i * 2];
values[i] = atoi(helper);
}
copy(values, values+MAX, ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values, values+MAX);
return 0;
}
Doing this removes the need for your findMax method altogether.
I'd also re-write your code so that you use a vector instead of an array. This makes your code even shorter. And you can use stringstream to convert strings to numbers.
Something like this should work and is a lot less code than the original.
int main(){
vector<int> values;
char ivals[256];
// Get the space-separated values from user input.
cin.getline(ivals, 256, '0');
int temp = 0;
stringstream ss(ivals);
//read the next int out of the stream and put it in temp
while(ss >> temp) {
//add temp to the vector of ints
values.push_back(temp);
}
copy(values.begin(), values.end(), ostream_iterator<int>(cout, "\n"));
cout << *std::max_element(values.begin(), values.end());
return 0;
}
Array of int is promoted to a pointer to int when passed to a function. There is no operator << taking ordinary array. If you want to use operator << this way, you need to use std::vector instead.
Note: it is possible technically to distinguish array when passed to a function using template, but this is not implemented for standard operator <<.
for(int i = 0; i < (sizeof(arr)/sizeof(int)); i++){
sizeof(arr) here is the size of the pointer to the array. C++ will not pass the actual array, that would be grossly inefficient. You'd typically only get one pass through the loop. Declare your function like this:
int findMax(int* arr, size_t elements) {
//...
}
But, really, use a vector.
Oh, hang on, the question. Loop through the array and print each individual element.