I am new to programming and I want to get an unlimited input of numbers from user, and I need to compare each number to 4 or 7; if the number is 4 or 7, I will increase counter.
The issue is that the if condition if(arr[i]!='4' || arr[i]!='7') is executed even if the number is 4 or 7.
I tried to implement another if by comparing ASCII code >>> if(arr[i]!=0x34 || arr[i]!=0x37) but this solution also doesn't work.
Can you help me to find the issue?
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
int main()
{
int counter=0;
char arr[]={};
cin >> arr;
for (int i=0 ; i<strlen(arr)-1 ; i++)
{
if(arr[i]!='4' || arr[i]!='7')
{
cout << "NO" << endl;
counter=0;
break;
}else
counter++;
}
cout << counter << endl;
if(counter==4 || counter==7)
cout << "YES" << endl;
}
Your program has undefined behavior, because this
char arr[]={};
creates an array of length zero. This is not even allowed in standard C++. If your compiler didn't complain about it, then that is because it is using a non-standard language extension.
In any case, the array has length zero. You then try to write to it with
cin >> arr;
which causes the array to be accessed out-of-bounds, no matter how long the given input is. This will cause undefined behavior and you will not have any guarantee whatsoever on how the program will behave.
Never use char arrays to store strings, especially not user input. Use std::string instead:
std::string arr;
cin >> arr;
Then instead of strlen(arr) you should use arr.size().
I am pretty sure you have further logic errors in your program (see question comments). But before you fix the program logic, you should make sure that you are writing a valid program in the first place.
Related
I have a program which takes the string and converts it into char array. I want to create regular expression without regex library which accepts all strings of a's and b's which has aa somewhere.
My code below is working fine but the only problem is that it accepts chars other than a's and b's as well e.g it accepts baabss as well.
Can you help to correct the code so that it rejects the string in that case ?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string input_string;
char char_string[20];
int counter=0;
cout << "type in some input text:$" << endl;
cin >> input_string;
strcpy(char_string, input_string.c_str());
for (int i = 0; i < sizeof(input_string); i++)
{
if(char_string[i]=='a' || char_string[i]=='b'){
switch(char_string[i])
{
case 'a' :
counter++;
break;
case 'b' :
if(counter==1){
counter=0;
}
break;
}
}
}
if(counter==2){
cout << "String accepted" << endl;
}
else{
cout << "String not accepted" << endl;
}
std::cin.get();
system ("PAUSE");
}
Problems with invalid chars
In your loop body, you have to reject the chars that are neither a nor b. So you have to complete
if(char_string[i]=='a' || char_string[i]=='b'){
...
}
with an else clause. For example:
else {
counter=0; // reset the counter so that the final check will fail
break; // exit the for loop
}
Problems that you have not detected so far
A first problem is that sizeof(input_string) doesn't return what you expect ! Use input_string.size() instead.
Then the program will fail to accept baaab, because it will cause the loop to end with counter being 3. Therefore you have to change your final check into:
if(counter>=2){ // instead of ==
Oops !
Finally if you'd have a user input of more than 19 characters, your program would have undefined behavior, because the strcpy() would copy more chars than there is place in the array, thus causing memory corruption. Strategies that you could use to correct this issue:
limit the size of the accepted user input using <iomanip> (e.g. cin >> setw(19) >>input_string;
limit the size of the copy using strncat() and inform the user if the input was truncated. You must then also ensure that the loop does not go beyond the truncated size.
You could directly access the original chars in input_string without doing any copy. Or if you prefer, you can remplace the char array with a vector that would get initialized from the string: vector<char>char_string(input_string.begin(), input_string.end());
Online demo of option 3
Just a heads up: My c++ programming skills and terminology is intermediate at best. So please be gentle ;).
I am working on a multi-sort algorithm for a college class. Originally, I built the program to take in an array of 20 integers, since that was as big as the .txt files were. The final lab is now asking to take in files that have 10, 100, 1000, 10000, 100000 and 1000000 different numbers. I originally used an ifstream inside a for loop to read in the ints. Now that I need to read a variable amount of ints from a file, I have run into issues with this code. I have extensively searched this site and Google to find an answer to this problem. I have tried dozens of different code snippets, to no avail. Here is the code I am currently running that works for 20 ints.
int i;
int A[20];
int length;
char unsortedFilename[200];
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
length = (sizeof(A) / sizeof(*A));
for( i = 0; i < length; i++ )
{
unsorted >> A[i];
cout << A[i] << "\n";
}
insertionSort();
I do have other code mixed in there, but it's error checking, selection of duplicate number removal, etc. I would like it so that code like this would run "i" number of times, where "i" is actually the number of ints in the file. Also, as I mentioned earlier, I will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers. Is it going to be as easy as swapping all my ints over to longs?
Thanks for any help you could provide.
As suggested in the comments, use std::vector<int> instead of an array.
Instead of a for loop, use a while loop. Break out of the while loop when there are no numbers to read.
The while loop:
std::vector<int> A;
int item;
while ( unsorted >> item )
{
A.push_back(item);
}
You can sort the std::vector by using std::vector::iterator or simply access the data through the int* returned by A.data().
You can simply read all the numbers into a vector. Then use the vector as you would have used the array.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
int main()
{
std::string unsortedFilename;
std::cout << "Please type the full name of the file you would like sorted.\n";
std::cin >> unsortedFilename;
std::ifstream is(unsortedFilename);
std::istream_iterator<int> start(is), end;
std::vector<int> A(start, end);
std::cout << "Read " << A.size() << " numbers" << std::endl;
}
What you want is a vector.
try this,
int i;
vector<int> A;
int length;
string unsortedFilename;
ifstream unsorted;
cout << "Please type the full name of the file you would like sorted.\n* ";
cin >> unsortedFilename;
unsorted.open(unsortedFilename);
int temp;
for( i = 0; unsorted >> temp; i++ )
{
A.push_back(temp);
cout << A[i] << "\n";
}
insertionSort();
A vector is basically a dynamic array. It automatically grows as more space is needed. That way it doesn't matter if you have 10, 100, or even 100000 items, it'll automatically grow for you.
Also use a string for your file name, some file names are longer than 200 characters.
Good Luck!
will need to input a file that has 1,000,000 numbers in it. I don't believe that an int array will be able to hold that many numbers.
Sure it can. 1 Million ints is ~4Mb of memory, which is a trivial amount. You can even declare it static just as you do now int A[1000000];.
But real problem is that you're assuming a fixed length in your code, rather than determine the length from the input. I guess this is what your assignment is trying to teach you, so I won't show you the solution. But consider using ifstream::eof and make your sort accept the length as an argument...
The first line contains an integer n (1 ≤ n ≤ 100). Each of the following n lines contains one word. All the words consist of lowercase Latin letters and possess the lengths of from 1 to 100 characters.
(Source: http://codeforces.com/problemset/problem/71/A)
How would you get input from the user given n? I tried using a while loop but it doesn't work:
#include <iostream>
using namespace std;
int main()
{
int n;
cin>>n;
int i;
while (i<=n) {
cin>>i ;
i++;
}
}
You probably meant to have something like:
#include <iostream>
int main() {
int n;
cin>>n;
int theInputNumbers[n];
for(int i = 0; i<n; ++i) {
cin >> theInputNumbers[i];
}
}
Your loop is really quite far off of what you need. What you wrote is extremely wrong such that I cannot provide advice other than to learn the basics of loops, variables, and input. The assistance you need is beyond the scope of a simple question/answer, you should consider buying a book and working through it cover to cover. Consider reading Programming Principles and Practice Using C++
Here is a working example of something approximating your question's requirements. I leave file input and output as an exercise up to you. I also make use of C++11's front and back std::string members. You would have to access via array index in older versions.
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
int totalWords;
cin >> totalWords;
stringstream finalOutput;
for (int i = 0; i < totalWords; ++i){
string word;
cin >> word;
if (word.length() > 10){
finalOutput << word.front() << (word.length() - 2) << word.back();
}else{
finalOutput << word;
}
finalOutput << endl;
}
cout << endl << "_____________" << endl << "Output:" << endl;
cout << finalOutput.str() << endl;
}
With that said, let me give you some advice:
Name your variables meaningfully. "int i" in a for loop like I have above is a common idiom, the "i" stands for index. But typically you want to avoid using i for anything else. Instead of n, call it totalWords or something similar.
Also, ensure all variables are initialized before accessing them. When you first enter your while loop i has no defined value. This means it could contain anything, and, indeed, your program could do anything as it is undefined behavior.
And as an aside: Why are you reading into an integer i in your example? Why are you then incrementing it? What is the purpose of that? If you read in input from the user, they could type 0, then you increment by 1 setting it to 1... The next iteration maybe they'll type -1 and you'll increment it by 1 and set it to 0... Then they could type in 10001451 and you increment by 1 and set it to 10001452... Do you see the problem with the logic here?
It seems like you are trying to use i as a counter for the total number of iterations. If you are doing this, do not also read input into i from the user. That completely undermines the purpose. Use a separate variable as in my example.
this script is supposed to output array values that were inputted by the user into array "store." I am trying to store all the char array values into string temp. I get the error on line 12: "[Error] invalid conversion from 'char*' to 'char' [-fpermissive]." Would appreciate any help!
Edit: so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so? The cmd only correctly couts the first string but after the space, it messes up.
#include <iostream>
#include <cstdlib>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50];
cout << "enter text: " << endl;
cin >> store;
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Using input from all answerers I finally got the fixed code:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
void coutArray(char[], int);
int main()
{
char store[50] = {0};
cout << "enter text: " << endl;
cin.getline(store, 50);
coutArray(store, 50);
system("pause");
return 0;
}
void coutArray(char store[], int max)
{
string temp = "";
int i = 0;
while (i < max && store[i]!=0)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
Thanks everyone. i learned a lot!!!
When you get an input using "cin" your input automatically ends with 0 (NULL).
You just need to add one little piece of code to your while statement.
instead of this :
while (i < max)
use this :
while (i < max && store[i]!=0)
Now it will stop when the input string is finished and won't print any garbage existed in the array beforehand.
To show that cin does add terminating zero, i initialized the array to 46, and put a breakpoint after the cin
so I fixed the declaration and now at least it compiles, but the answer I get on my cmd is all jumbled up. Why is this so?
Not sure what you mean by jumbled up. But since you did not tell us what you typed its hard to know it looks like it worked to me:
> ./a.out
enter text:
Plop
Plop�ȏU�
Notice that since my input is only 4 characters long. This means that a lot of the characters in the array still have undefined (ie random values). This is why I am seeing junk. To get past this initialize the array to have all 0 values.
char store[50] = {0};
Even bettern use a C++ object than handles longer strings.
std::string store;
std::getline(std::cin, store);
Note: passing arrays to functions by value is not a good idea. On the other end they have decayed to pointers and thus do not act like arrays anymore (they act like pointers whose semantics are similar but not identical).
If you must pass an array pass it by reference. But I would use a C++ container and pass that by reference (it is much safer than using C constructs). Have a look at std::string
The declaration of the function is wrong. Should be void coutArray(char *, int);
Look at the Implicit Conversion rules to understand what the compiler can do and what it cannot to do for you.
The issue with your program was that you were probably entering in less characters than the maximum size of the buffer. Then when you passed the maximum size as the parameter to coutArray, you assigned unfilled slots in the char array to temp. These unfilled slots could contain anything, as you have not filled them up to that point.
Your program is still correct, but what would be better would be to use read so that the number of bytes you specify is the minimum number of bytes that can be entered:
std::cin.read(store, 50);
Even better solution would be to use std::string:
std::string store;
std::cin >> store;
// or for the entire line
std::getline(std::cin, store);
It also follows that your coutArray should be changed to:
void coutArray(std::string);
// ...
void coutArray(std::string str)
{
std::cout << str << std::endl;
}
Look at this way
template<typename T, size_t N>
void MyMethod(T (&myArray)[N])
{
//N is number of elements, myArray is the array
std::cout<<"array elements number = "<<N<<endl;
//put your code
string temp;
temp.resize(N+1);//this is for performance not to copy it each time you use += operator
int i = 0;
while (i < max)
{
temp += store[i];
i++;
}
cout << temp << endl;
}
//call it like this
char arr[] = "hello world";
MyMethod(arr);
#include<iostream>
using namespace std;
int main()
{
char arr[200];
while(1) {
cin >> arr;
int i = sizeof(arr);
cout << "The arr input is "<< arr
<< " and the size of the array is "<< i << endl;
}
return 0;
}
For the input of 34,
This code outputs :The arr input is 34 and the size of the array is 200
while I want it to get the size of the used space of the array . So for The last input i want it to output :The arr input is 34 and the size of the array is 2
Can someone tell me how?
Maybe you want strlen(arr) here. It must be null terminated, otherwise the cout << arr would not have worked.
You would need to #include <cstring>
There's no automatic way to do what you want in the general case - you'll need to keep track somehow, either with your own counter, or by seeding the array with an 'invalid' value (that you define) and search for to find the end of the used elements (that's what the '\0' terminator character in a C-style string is).
In the example code you posted, the array should receive a null terminated C-style string, you can use that knowledge to count the number of valid elements.
If you're using C++ or some other library that has some more advanced data structures, you may be able to use one that keeps track of this kind of thing for you (like std::vector<>).
the size of the used space of the array
There is no such thing. If you have an array of 200 chars, then you have 200 chars. Arrays have no concept of "used" and "unused" space. It only works with C-strings because of the convention that those are terminated by a 0 character. But then again, the array itself cannot know if it is holding a C-string.
in a less involved manner, you can just count through each character till you hit a null with just a while loop. It will do the exact same thing strlen() does. Also, in practice, you should do type checking with cin, but i'll assume this was just a test.
#include <iostream>
using namespace std;
int main()
{
char arr[200];
int i;
while(1) {
cin >> arr;
i=0;
while (arr[i] != '\0' && i<sizeof(arr))
i++;
cout << "The arr input is "<< arr
<< " and the size of the array is "<< i << endl;
}
return 0;
}
Just for completeness, here is a much more C++ like solution that is using std::string instead of a raw char array.
#include <iostream>
#include <string>
int
main()
{
while (std::cin.good()) {
std::string s;
if (std::cin >> s) {
std::cout
<< "The input is " << s
<< " and the size is " << s.length()
<< std::endl;
}
}
return 0;
}
It doesn't use an array, but it is the preferable solution for this kind of problem. In general, you should try to replace raw arrays with std::string and std::vector as appropriate, raw pointers with shared_ptr (scoped_ptr, or shared_array, whatever is most appropriate), and snprintf with std::stringstream. This is the first step to simply writing better C++. You will thank yourself in the future. I wish that I had followed this advice a few years ago.
Try it
template < typename T, unsigned N >
unsigned sizeOfArray( T const (&array)[ N ] )
{
return N;
}