C++ Help. Arrays not working with integers - c++

Here is my code: (C++)
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(){
string sentence[9];
string word[9];
inb b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int f = 0;
for (int i = 1; i <= 10; i += 1){
cin >> sentence[i - 1];
}
for (int a = 10; a > 1; a = a - b[f]){
b[f] = 0;
int f = rand() % 10;
b[f] = 1;
word[f] = sentence[f];
cout << world [f] << endl;
}
}
However, when I run this I get a "runtime error". That's it, no line, no further error. Nothing.
The Arrays in the bottom side of the code, like word[f] and b[f] do not work if I use f inside the "[]"'s.
When I change all the "f"'s with [1] to test the code, it works. But when I use "f"'s instead, it returns a runtime error.
Not sure if that is my compiler. But hey - I am a 2 day old C++ coder.

Your sentence is 9 "slots" big (addressed as sentence[0] to sentence[8]). You try to put something in the 10th slot (sentence[9]), which is a no-no.
(This pattern is repeated below with word.)
You most likely want to declare those arrays as 10-element ones.

That's because sentence and word contain nine units. But rand()%10 will produce 9, when you use word[f] = sentence[f], word[9] and sentence[9] are out of range. word[9] is the 10th element of array word.

There are several problems with your code. Firstly, sentence and word only have 9 entries, but you try to use 10. Array declaration is 1-based, e.g.
char foo[2];
declares two characters. However, they are numbered 0 and 1, thus
char foo[2];
foo[0] = 'a'; //valid
foo[1] = 'b'; //valid
foo[2] = 'c'; //very bad.
this problem might be obfuscated for you by the fact that you are making 'b' an auto-sized array.
The second problem is that you declare 'f' twice.
int f = 0;
for (int i = 1; i <= 10; i += 1){
and inside the loop
int f = rand() % 10;
b[f] = 1;
Your for loop, then, is broken:
for (int a = 10; a > 1; a = a - b[f]){
it uses the external 'f', which is always 0, to access element zero of b and subtract that from a.
Here is how I would write the code you're trying to write:
I honestly don't understand what your code is supposed to do, but here is how I might write a simpler version of the same thing:
#include <iostream>
#include <stdlib.h>
#include <array>
//using namespace std; <-- don't do this.
int main(){
std::array<std::string, 10> sentence; // ten strings
// populate the array of sentences.
for (size_t i = 0; i < sentence.size(); ++i) { // use ++ when ++ is what you mean.
std::cin >> sentence[i];
}
for (size_t i = 0; i < sentence.size(); ++i) {
size_t f = rand() % sentence.size(); // returns a value 0-9
std::cout << sentence[f] << " ";
}
std::cout << std::endl;
}
Requires C++11 (-std=c++11 compiler option). ideone live demo here

Related

(C++) Finding all prime numbers between two integers (without using sieve of Eratosthanes)

I'm trying to find all the prime numbers between two integers and place them in an integer array.
The catch is that i have to use a specific method of doing so (divide each subsequent integer by all the primes in my array). So I can't use the sieve of Eratosthanes or any other 'easier' methods.
My code successfully prompts the user for two integers, but for now I do not use either of them. First I want to make sure the program works for values between 0 and whatever, in this case 200 just to test it.
Problem is, when I run the program and print the first 20 or so values in the array, I'm getting
2, 3, 5, 7, 11, 200, 0, 0, 0, 0, 0, 0 ...... more zeroes.
The first 5 values are correct because they start in the array, but after that the whole thing goes haywire.
I've worked through my nested loop by hand for a couple values and it SEEMS like it should work. I feel like there's a specific array property that I'm overlooking.
Here's my code:
#include "stdafx.h"
#include "iostream"
#include "climits"
#include "cmath"
#include "array"
using namespace std;
int main()
{
// declare variables to store user input
int lowerBound, upperBound;
// prompt user for lesser and greater integers and store them
cout << "Program to find all primes between two integers." << endl;
cout << "Enter lesser integer: " << endl;
cin >> lowerBound;
cout << "Enter greater integer: " << endl;
cin >> upperBound;
// if statement to switch the input variables if the user accidentally enters them backwards
if (lowerBound > upperBound) {
int temp = lowerBound;
lowerBound = upperBound;
upperBound = temp;
}
// initialize int array with the first 5 primes
int primes[100] = { 2, 3, 5, 7, 11 };
// loop to find primes between 12 and 200 (since we already have primes from 1-11 in the array)
for (int i = 12; i <= 200; i++) {
// the maximum divisor needed to determine if the current integer being tested is prime
double maxDivisor = sqrt(i);
// variable for the current size of the array
int size = 5;
// boolean variable is set to true by default
bool isPrime = true;
for (int j = 0; j < size; j++) { // changed "j<=size" to "j<size"
int remainder = (i % primes[j]);
// once the maximum divisor is reached, there is no need to continue testing for the current integer
if (primes[j] > maxDivisor) {
break;
}
// if the remainder of divison by a prime is 0, the number is not prime, so set the boolean variable to false
if (remainder = 0) {
isPrime = false;
}
}
// if isPrime is still true after the nested loop, the integer value being tested will be placed in the next element of the array
if (isPrime == true) {
primes[size] = i;
// since we added to the array, increment size by 1
size++;
}
}
// display the first 20 values in the array for debugging
for (int k = 0; k < 20; k++) {
cout << primes[k] << ", ";
}
system("pause");
return 0;
}
This here
if (remainder = 0) {
isPrime = false;
}
Needs to be changed to
if (remainder == 0) {
isPrime = false;
}
Because = does assignment, not comparison. So what remainder = 0 does it setting remainder to 0, and then it returns that 0, which gets casted to false, which is on of the reasons why it's not finding any primes.
Also, as Fantastic Mr Fox pointed out, for (int j = 0; j <= size; j++) needs to be changed to for (int j = 0; j < size; j++).
Also, did your compiler issue any warnings? If not, try to see if you can set it to be more strict with warnings. I figure most modern compilers will give you a hint at if (remainder = 0). Getting useful warnings from the compiler helps a lot with preventing bugs.
Edit:
As Karsten Koop pointed out, you need to move the int size = 5; out of the loop, to before the for (int i = 12;. With those changes, it's now working on my machine.
Last but not least, a tip: instead of if (isPrime == true), you can just write if (isPrime).

Program to find greatest divisors returns 0

I just recently figured I'd try to learn how to code. I'm at the basics and found some exercises to do online, but I've sat at this for ~40 mins and can't figure it out. So even though this might seem basic to most of you I'll ask for some help :)
So here's the task:
The specified integers are in the range [m, n]. Write a program to find the number with the greatest divisors.
Input / output :
Initial data | Result
10 40 | 36
Code :
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char *argv[])
{
int m, n, s, sd = 0, ats;
double a = 0;
ifstream fd("Duomenys.txt");
fd >> m >> n;
for(int i = m; i<=n; i++){
s = 0;
for(int j = 1; j<=i; ++j){
a = 0;
a = i % j;
if(a = 0) s= s + 1;
}
if(s > sd) {
i = ats;
s = sd;
}
}
cout << ats;
system("PAUSE");
return EXIT_SUCCESS;
}
Now I'm only using cout << ats to test it for the moment, but if I run it it gets a 0 as an answer.
If you want to test whether a is equal to 0 or not, you have to use the Equal to operator, which is ==.
With if (a = 0), you're actually assigning 0 to a and then testing the result of this operation, which will always be 0. That's why the instructions of the if, here s = s + 1; will never be executed.
Other problems in your code:
You use the variable ats but never initialize it, so its value is undetermined
I don't see any reason why a is a double instead of an int
I suggest you to turn on all your compiler warnings and to start with a good book or tutorial about C++

C++ reversing a string with only one string

I am trying to reversing a string with only using one string, but when I output the string it is missing a letter. Is something being over written that I do not know about? Here is my code:
#include <iostream>
using namespace std;
int main() {
string d = "jakejosh"; //11
char temp = '\0';
int j = d.size()/2;
for (int i=d.size()/2; i> 0; i--) //5
{
temp = d[i+j];
d[j+i] = d[j-i];
d[j-i] = temp;
}
cout << d << endl;
return 0;
}
Output is: ttam olle
Output should be: ttam olleh
When the size of a string is even then the code is wrong. For example if the size is equal to 2 then size() / 2 is equal to 1 and in the loop you will get thet d[i+j] is equivalent to d[size() / 2 + size() / 2] that is equal to d[2] while the valid range of indices is [0,1]
Also you should include header <string> and you could use standard function std::swap
The simplest approach is the following
#include <iostream>
#include <string>
int main()
{
std::string s = "hello matt";
s = std::string( s.rbegin(), s.rend() );
std::cout << s << std::endl;
return 0;
}
If you want to write the loop yourself then the code can look like
#include <iostream>
#include <string>
int main()
{
std::string s = "hello matt";
for ( std::string::size_type i = 0; i < s.size() / 2; i++ )
{
char c = s[i];
s[i] = s[s.size()-i-1];
s[s.size()-i-1] = s[i];
}
std::cout << s << std::endl;
return 0;
}
Or you can write some exotic solution.:) For example
#include <iostream>
#include <string>
#include <utility>
int main()
{
std:: string s = "Jake Smith";
std::cout << s << std::endl;
for ( std::string::size_type i = 0, j = s.size(); j - i > 1; i++ )
{
std::swap( s[i], s[--j] );
}
std::cout << s << std::endl;
return 0;
}
The program output is
Jake Smith
htimS ekaJ
Or you can try to write a recursive function.
At last you could use standard algorithm std::reverse declared in header <algorithm>.
Use std::reverse() to do that. For educational purposes take a look at the following pure C algorithms: http://www.programmingsimplified.com/c-program-reverse-string
for (int i=d.size()/2; i> 0; i--) //5
{
temp = d[i+j-1]; // d[9] i.e.must be 9 not 10 for swapping with 'h'
d[j+i-1] = d[j-i];
d[j-i] = temp;
}
It's very easy to trip up with indices when reversing a string in place.
If your string is of length LEN, then the valid indices are 0 - N-1.
In your case, let's take a look at the middle and how you start swapping from there.
hello matt
For reversing the string, you'll have to swap
hello matt (swap 0-th and 9-th)
^ ^
hello matt (swap 1-st and 8-th)
^ ^
hello matt (swap 2-nd and 7-th)
^ ^
hello matt (swap 3-rd and 6-th)
^ ^
hello matt (swap 4-th and 5-th)
^^
The start value for i is (N-1)/2.
The end vale for i is 0.
The index for swapping the value at i is len - 1 - i. (swap d[0] with d[9] in your case)
Putting that all together, the function should be something like:
void reverse_string(string& d)
{
int len = d.length();
for (int i=(len-1)/2; i >= 0; i--)
{
int j = len - 1 - i;
char temp = d[j];
d[j] = d[i];
d[i] = temp;
}
}
Here's the main function to test it.
int main()
{
string d = "hello matt";
reverse_string(d);
cout << d << endl;
d = "hello max";
reverse_string(d);
cout << d << endl;
return 0;
}

Sum two Dynamic Arrays

I'm doing a homework problem where I have two take input from a user in the form of two dynamic char arrays (max of 100 characters each) and returning their sum.
I'm struggling with coming up with a sum function that works correctly when the two numbers are of different length or when the answer is less than 100 digits. When the numbers are of different length, they get added as if they were the same (e.g. 100 + 1000 becomes 1000+1000). When the result is less than 100 digits, the full arrays is printed anyway (so there are dozens of trailing zeros). (EDIT: Fixed, see below).
I know that there is no way to tell the actual size of a dynamic array, and I can't figure out any way to place some sort of sentinel value that stops the program from processing farther. I'm not allowed to use vectors or traditional arrays, which would give me a clear path to the solution. EDIT: This has been fixed by checking for '\0'.
I know SO doesn't want to do people's homework for them (nor am I asking that), but I do need some guidance as to how I can solve this problem. I've been working for hours and still can't think of a solution.
My program is as follows:
#include <iostream>
#include <algorithm>
int* sum(char*, char*);
int main() {
char * arr = new char[100];
char * arr2 = new char[100];
std::cout << "Enter value 1: ";
std::cin >> arr;
std::cout << "Enter value 2: ";
std::cin >> arr2;
int * result = sum(arr, arr2);
std::cout << "Result: ";
for (int i = 0; i < 100 && result[i] != '\0'; i++) {
std::cout << result[i];
}
std::cout << std::endl;
return 0;
}
int* sum(char * num1, char* num2) {
std::reverse(num1, num1 + 100);
std::reverse(num2, num2 + 100);
bool carryOver = false;
int* retarr = new int[100]; //Array to return to user
for (int i = 0; i < 100; i++) {
//Numerical value is char - 48, unless
//char value is zero, then int val is zero
int val1 = std::max(num1[i] - 48, 0);
int val2 = std::max(num2[i] - 48, 0);
int carry = (carryOver)? 1 : 0;
carryOver = false; //Reset carryOver var
int t = val1 + val2 + carry;
if (t >= 10) {
t = t % 10;
carryOver = true;
}
retarr[99 - i] = t;
}
return retarr;
}

Any ways to make this shorter?

The output is supposed to be in this fashion
I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I
I was wondering if there is anyway to make my program shorter.
Maybe use 2 while loops or 2 for loops instead of 4.
#include<iostream>
#include<conio.h>
using namespace std;
void main()
{
char a[]={'I','N','D','I','A'};
int r,c;
for(r=1;r<=5;r++)
{
for(c=0;c<r;c++)
cout<<a[c]<<" ";
cout<<endl;
}
for(r=5;r>=0;r--)
{
for(c=0;c<r;c++)
cout<<a[c]<<" ";
cout<<endl;
}
_getch();
}
This is nice and short, if you have C++11:
#include <stdio.h>
#include <initializer_list>
int main() {
for (int i : {1,3,5,7,9,9,7,5,3,1})
printf ("%.*s\n", i, "I N D I A") ;
}
I put it on ideone at this link.
The "cheating" ;-) but very short solution is
#include <cstdio>
int main() {
puts("I\nIN\nIND\nINDI\nINDIA\nINDIA\nINDI\nIND\nIN\nI\n");
}
Yet another solution based on TonyK's beautiful idea (works in C and C++):
#include <stdio.h>
int main() {
for (int i = 1; i < 11; ++i)
printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") ;
}
Update: (After TonyK's comment):
If you want spaces, then replace the printf above with this
printf("%.*s\n", 2*(i < 6 ? i : 11 - i), "I N D I A ");
Update: A solution with no loop:
#include <stdio.h>
int main(int i, char**) {
return printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") - 1 && main(i + 1, 0);
}
Detailed explanations for the benefit of beginners follow.
The most important point is that this is an "academic" exercise. The code is obscure and one should refrain from writing serious code like this.
The standard doesn't fix a particular signature for the function main. It only says that it must return an int and the compiler must accept two particular forms:
int main();
int main(int argc, char** argv);
I'm using the second one. The more popular form int main(int argc, char* argv[]) is equivalent to (2). Indeed, in general, an array of T used as a function argument is implicitly converted to pointer to T. In this example, char* argv[] is an array of pointer to char which becomes a pointer to pointer to char. The above program is not using the second parameter though (it's either ignored or given a NULL, i.e. 0 value).
Instead of doing a loop, the program calls main recursivelly. Actually, this is illegal but the major compilers turn a blind eye to it (at most GCC gives a warning if you ask it to be pedantic with option -Wpedantic). When the program is called from the command line with no arguments the operating system calls main passing 1 (which is 1 + the number of arguments) and a pointer to pointer to char which, as said, is ignored by this program. Hence, i = 1 at the first call.
Subsequently, main potentially calls itself incrementing i each time. In summary, main is sequentially called with i being 1, 2, 3, 4, ...
It's easy to see that for this sequence of values for i, the expression i < 6 ? i : 11 - i evaluates to 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, ... (This can also be expressed by 5.5 - abs(5.5 - i) as per Drew Dorman's solution but using the ternary operator avoids the need to #include <cmath> which saves a line ;-) These numbers are the quantity of characters of "INDIA" that should be displayed at each time.
The call printf("%.s\n", j, "INDIA"), where j = i < 6 ? i : 11 - i, displays the first j characters of "INDIA" followed by a new line and returns the number of characters effectivelly printed (including the new line), i.e. j + 1. Taking away 1 yields j.
We recall now an important point of the semantics of a && b, for integers a and b. If a == 0, then b is not evaluated. Otherwise, b is evaluated. For us, a = printf("%.*s\n", j, "INDIA") - 1 (i.e. a = j) and b = main(i + 1, 0).
Now, let's put these pieces together.
1. Initially, i = 1 and j = 1. The call to printf outputs "I\n" and returns 2. Taking away 1, gives a = 1 != 0. Therefore, b = main(2, 0) is evaluated (that is, main(2, 0) is called).
2. Well, for this second call to main, we have i = 2, j = 2, printf displays "IN\n", a = 2 != 0 and b = main(3, 0) is evaluated.
Repeating this argument, at each call to main we have:
3. i = 3, j = 3, "IND\n" is printed, a = 3 != 0 and main(4, 0) is called.
4. i = 4, j = 4, "INDI\n" is printed, a = 4 != 0 and main(5, 0) is called.
5. i = 5, j = 5, "INDIA\n" is printed, a = 5 != 0 and main(6, 0) is called.
6. i = 6, j = 5, "INDIA\n" is printed, a = 5 != 0 and main(7, 0) is called.
7. i = 7, j = 4, "INDI\n" is printed, a = 4 != 0 and main(8, 0) is called.
...
10. i = 10, j = 1, "I\n" is printed, a = 1 != 0 and main(11, 0) is called.
11. i = 11, j = 0, "\n" is printed, a = 0. Now main(12, 0) is not exectued and the main returns
Notice that main in step 1 calls main in step 2, which calls main in step 3, ... which calls main in step 11. Therefore, main in step 11 returns to main in step 10, which returns to main in step 9, ..., which returns to main in step 1. Finally, main in step 1 returns to the operating system.
If you are interested in even more obfuscated code, see present and past winners of the IOCCC. Enjoy!
Shorter.
#include <iostream>
#include <cmath>
int main()
{
char a[]={'I','N','D','I','A'};
for(int r=1;r<=10;r++)
{
int c = 5.5 - std::abs(5.5 - r);
std::cout << std::string(a, 0, c) << std::endl;
}
}
You could use substr.
Additionally, if you want to add spaces between the characters (as it's in your code right now) you could do that once for the whole word and then work on that modified string:
input = "INDIA";
modifiedInput = ...; // Figure out a way to get "I N D I A " here
for (int i = 1; ...)
cout << substr(modifiedInput, 0, 2 * i) << endl;
...
smth like this:
Anyway, 2 loops is hard thing)
int i=1;
bool ind=0;
for(r=0;r<10;r++)
{
if (ind == 0){
for(c=0;c<i;c++)
cout<<a[c]<<" ";
i++; }
if (ind == 1){
for(c=0;c<i;c++) cout<<a[c]<<" ";
i--;
}
if (i % 5 == 0) ind=1;
cout<<endl;
}
Here is an example using two loops:
#include<iostream>
using namespace std;
int main()
{
char a[]={'I','N','D','I','A'};
int arr_length=5;
bool two_times=false;//if you want to output INDIA twice
for(int i=2*arr_length-1; i>=1; i--)
{
for(int j=0; j<arr_length-abs(arr_length-i); j++)
{
cout << a[j];
}
if(i==arr_length && !two_times){ two_times=true; i++;}//if you want to output INDIA twice
cout << endl;
}
return 0;
}
Output:
I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I
You can do like this:
void main()
{
char a[]={'I','N','D','I','A'};
int r,c;
int x = 0; // initially x is 0
int l = 5;
for(r=1;r<= 11 ;r++) //loop runs for 5*2 + 1 times
{
if(r>=6){
x = l - r % 6; //set x to remaining length
l--;
}
for(c=0;c< (r % 6) + x; c++) // add x
cout<<a[c]<<" ";
cout<<endl;
}
}
and you can find it working here.
Another solution based on TonyK's answer. You can enter your desired string.
#include <stdio.h>
#include <string.h>
int main() {
char s[100];
gets(s);
for (int i = 0; i < strlen(s) * 2; i++)
printf ("%.*s\n", i < strlen(s) ? i + 1: 2 * strlen(s) - i, s);
}
http://ideone.com/Zsg5Lu