Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
#include <iostream>
using namespace std;
int main()
{
int a = 0, skrb = 0, j = 0;
char b, simboliai[2000];
char zodis[50][20];
char check[1][20] = {'f'};
cout << "Prasome irasykite sakini: ";
cin.getline(simboliai,sizeof(simboliai));
//----------------- Zodziu skaidymas ----------------------------------------------------------------------------------------------------------
a = 0;
for (int i = 0; i > -1; i++)
{
if ((simboliai[i] == 's' && simboliai[i++] == ' ') || (simboliai[i] == 's' && simboliai[i++] == '\n'))
{
check[0][a] = 't';
}
if (simboliai[i] == ' ')
{
a++;
}
else
{
zodis[i][a] = simboliai[i];
}
if (simboliai[i] == '\n')
{
break;
}
}
a = 0;
while (1)
{
if (simboliai[a] == '.' || simboliai[a] == ',' || simboliai[a] == '!' || simboliai[a] == '?')
{
skrb++;
}
a++;
if (simboliai[a] == '\n')
{
break;
}
}
a = 0;
cout << "Jus ivedete tokius zodius kurie baigiasi raide 's'" << endl;
while(1)
{
if (zodis[j][a] == 'Ì')
{
cout << '\n';
a++;
}
if (check[0][a] == 't')
{
cout << zodis[j][a];
}
if (zodis[0][a] == 'Ì')
{
break;
}
}
cout << "Pas jus yra (.','!'?) simboliu: " << skrb << endl;
cin.ignore();
cin.get();
}
Basically this program would work but that for part just ruins everything. It doesn't put characters one by one. And when I debug it shows that program have put symbol in its place but then there is Ì.
So it looks just like so
input: word word
zodis[0][0] goes like wÌÌÌÌÌÌÌÌÌÌ zodis [1][0] goes oÌÌÌÌÌÌÌÌÌÌ and so on and it breaks. Thank you in advance.
If you are saying the for loop wouldn't put characters 1 by 1, it was in your "simboliai[i++] == ' '" logic. integer 'i' been incremented twice each loop when current character is 's' which mean it will be incremented from i=2 to i=4 if simboliai[i] = 's'. Use i+1 instead for your checking.
for (int i = 0; i > -1; i++)
{
...
}
is the main problem. There might be others but I don't look too closely for them.
The values of i will be 0, 1, 2. etc.
All of them are greater than -1.
The loop will go on until the value i reaches INT_MAX. (Not sure what happens when i is incremented at that time).
That is way larger than the size of the array simboliai anyway. Your program will access the array simboliai beyond valid limits and cause undefined behavior.
I think what you need is:
size_t len = strlen(simboliai);
for (size_t i = 0; i < len; i++)
{
...
}
Other Problems
Some of the errors result from the assumption that there is a newline character in simboliai. That assumption is not correct. std::istream::getline reads and discards the newline character.
If Google Translate is correct, zodis is supposed to contain a list of words. When you are iterating over the characters of simboliai, you need three counters.
One to iterate over the characters of simboliai.
One to keep track of the number words.
One to keep track of the number of characters in the current word.
Your for loop is not doing that.
When you are trying to access the contents of an array, you need to always write defensive code and make sure that you never access the array using out of bounds indices. In the last while loop, you are not doing that.
In the last while loop, you are incrementing a only in the first if block. If the conditional of that if statement evaluates to false, a never gets incremented and you get stuck in an infinite loop.
In the last loop you use j as an index but its value is initialized to 0 at the start of the function and never gets updated. It's not clear what the intent of the last while loop is. Hence, I can't say whether it's a bug but it sounds like it could be.
Here's a cleaned up version of your posted code with still a few unknowns.
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int a = 0, skrb = 0, j = 0;
char b, simboliai[2000];
char zodis[50][20];
char check[1][20] = {'f'};
cout << "Prasome irasykite sakini: ";
cin.getline(simboliai,sizeof(simboliai));
//----------------- Zodziu skaidymas ----------------------------------------------------------------------------------------------------------
int word_counter = 0;
a = 0;
size_t len = std::strlen(simboliai);
for (size_t i = 0; i < len; i++)
{
if ((simboliai[i] == 's' && simboliai[i+1] == ' ') || (simboliai[i] == 's' && simboliai[i+1] == '\0'))
{
check[0][a] = 't';
}
if (simboliai[i] == ' ')
{
zodis[word_counter][a] = '\0';
a = 0;
++word_counter;
}
else
{
zodis[word_counter][a] = simboliai[i];
++a;
}
}
a = 0;
while ( simboliai[a] != '\0' )
{
if (simboliai[a] == '.' || simboliai[a] == ',' || simboliai[a] == '!' || simboliai[a] == '?')
{
skrb++;
}
a++;
}
a = 0;
cout << "Jus ivedete tokius zodius kurie baigiasi raide 's'" << endl;
while( j < 50 && a < 20 )
{
if (zodis[j][a] == 'Ì')
{
cout << '\n';
}
if (check[0][a] == 't')
{
cout << zodis[j][a];
}
if (zodis[0][a] == 'Ì')
{
break;
}
a++;
}
cout << "Pas jus yra (.','!'?) simboliu: " << skrb << endl;
cin.ignore();
cin.get();
}
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am attempting to write a Caesar encryption program. I have written two functions.
The first (sanitize) allows me to make sure that all strings are fully capitalized, here is the source code.
string sanitize(string message) {
for(int i; i < message.length(); i++){
message[i] = toupper(message[i]);
}
return message;
}
The second (caesar) encrypts the message given. Here is the source code for that as well.
string caesar(string c_message, char direction) {
if (direction = 'R') {
for(int j; j < c_message.length(); j++) {
if((int)c_message[j] + 3 > 90) {
c_message[j] = (char)(64 + (3 - (90 - (int)c_message[j])));
} else {
c_message[j] = (char)((int)c_message[j] + 3);
}
}
} else if (direction = 'L') {
for(int i; i < c_message.length(); i++) {
if((int)c_message[i] - 3 < 65) {
c_message[i] = (char)(91 - (3 - ((int)c_message[i] - 65)));
} else {
c_message[i] = (char)((int)c_message[i] - 3);
}
}
} else {
cout << "directions: 'L' or 'R'" << endl;
}
return c_message;
}
An example of execution :
int main(){
cout << sanitize("HELLO") << " " << (char)3 << endl;
cout << caesar("HELLO", 'L') << endl;
return 0;
}
The first if statement works, but the second does not.
if (direction = 'R') {
} else if (direction = 'L') {
These lines are wrong. = in C++ is an assignment operator and it sets the value of a variable in lefthand to the value of righthand. Then, it is evaluated to the new (righthand) value. Another point is that nonzero values are considered as true when used as condition.
You should use a comparision operator == instead of that like this:
if (direction == 'R') {
} else if (direction == 'L') {
#include <iostream>
using namespace std;
int main() {
char a[101]{0};
cin>>a;
cin.getline(a,101);
cin.ignore();
int currLen{0};
int maxLen{0};
int startInd{-1};
int endInd{-1};
for(int i=0; i<101; i++) {
if(a[i]!=' ' ) {
++currLen;
} else if(a[i]==' '||a[i]=='\0') {
if(currLen>maxLen) {
maxLen=currLen;
startInd=i-currLen;
endInd=i-1;
}
if(a[i]=='\0')
break;
currLen=0;
}
}
cout<<maxLen<<endl;
if(startInd==-1)
cout<<-1;
else
for(int i=startInd; i<=endInd; i++)
cout<<a[i];
return 0;
}
If I take an input here, for example, "My name is Manav Kampani"
It will output 5
Manav instead of 7
Kampani
But if I write "My name is Manav Kampani ", with space after the last word
than it is considering Kampani too printing Kampani.
Also when I input "Kampani Manav is my name" then too it's displaying the wrong output. That means it is not considering the first word of the sentence.
if(a[i]!=' ' )
{
++currLen;
}
else if(a[i]==' '||a[i]=='\0')
{
....
}
Consider the case of a[i] == 0. Which of these if-statements will apply.
Answer: the first one. Which means you'll never look at the final word in the string. You also don't exit at the end of the string, but instead loop through whatever is in your string all the way out to character 101.
As a general structure, be very, very careful with this:
if (condition)
else if (condition)
// without a final else section
If you do that, you need to think about what you're doing. In this particular case, you can have:
if (a[i] != 0 && a[i] != ' ')
else
It may not solve all your issues, but it should solve some.
A nice sliding window pattern implementation.
You have 3 problems in your code
You must not write cin >> a;
You must not write cin.ignore();
You need to modify your if statement like so: if (a[i] != ' ' && a[i] != '\0') Otherwise you will not detect the last word.
Your complete working code with that minor fixes will lokk like that.
int main()
{
char a[101]{ 0 };
//cin >> a;
cin.getline(a, 101);
//cin.ignore();
int currLen{ 0 };
int maxLen{ 0 };
int startInd{ -1 };
int endInd{ -1 };
for (int i = 0; i < 101; i++)
{
if (a[i] != ' ' && a[i] != '\0')// Add comparison
{
++currLen;
}
else if (a[i] == ' ' || a[i] == '\0')
{
if (currLen > maxLen)
{
maxLen = currLen;
startInd = i - currLen;
endInd = i - 1;
}
if (a[i] == '\0')
break;
currLen = 0;
}
}
cout << maxLen << endl;
if (startInd == -1)
cout << -1;
else
for (int i = startInd; i <= endInd; i++)
cout << a[i];
return 0;
}
Additionally. You should not use C-Style arrays in C++. And please use std::string
There is a couple of things here:
1- You don't need to do a cin>>a this is actually consuming the first word, and afterwards the content is overrided by cin.getline(). So removing the firsst cin>>ayou'll be fine.
2- The last word is not read because there isn't any if condition that matches the condition aka.
if(a[i]!=' ' ) case of not a space
//not end of word
else if(a[i]==' '||a[i]=='\0') case of space or null
//end of word
So your last character is not a space nor null, that means you don't detect the last word.
I am trying to convert input text/numbers (string), which will include any characters, but I want to separate the numbers from the characters and store them into an integer array, once it is converted from a string.
I believe the problem is where the string is converting to an integer by use of stoi(), but I cannot seem to spot the problem.
Currently, the code accepts any input and turns it into a string, the string is then checked character by character, and all the numbers without separation with comma or space is added together, once a comma or space, or any other character separates the number, the number as a whole is added to the array, and then continues to check the string for more numbers.
Any ideas?
Input Example1: 12, 13, 15
Input Example2: 12 13 15
Input Example3: 12ab13cd15ef
Result in integer array: 0[12] 1[13] 2[15]
These numbers will be used in the specific order, by using the numbers within the array.
#include<iostream>
#include<string>
#include <sstream>
using namespace std;
int main()
{
string datainput, str1, str3;
cin >> datainput;
int n = 0, raycount = 0, c;
int myray[10];
while (datainput[n])
{
if (datainput[n] == ('0') || datainput[n] == ('1') || datainput[n] == ('2') || datainput[n] == ('3') || datainput[n] == ('4') ||
datainput[n] == ('5') || datainput[n] == ('6') || datainput[n] == ('7') || datainput[n] == ('8') || datainput[n] == ('9'))
{
str1 = datainput[n];
str3 += str1;
}
else
{
c= stoi(str3);
c >> myray[raycount];
raycount++;
}
n++;
}
cout << myray[0] << endl;
cout << myray[1] << endl;
cout << myray[2] << endl;
cout << myray[3] << endl;
system("pause");
return 0;
}
I see quite a few issues with your code.
Prior to C++11, while (datainput[n]) has undefined behavior once n reaches the end of the string.
The way you are checking for numeric digits can be greatly simplified using std::isdigit(), or even just a simple range check using the >= and <= operators.
You are not correctly accounting for numbers that are separated by other characters, or when the last number in the string is at the very end of the string.
The statement c >> myray[raycount]; needs to be changed to myray[raycount] = c; instead. And you are not breaking your loop if raycount reaches the max capacity of myray[].
You are not resetting str3 back to an blank string after converting it with std::stoi(). You just keep appending new digits to the end of previous digits with no break in between numbers.
With that said, try something more like this instead:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string datainput, str3;
cin >> datainput;
int myray[10];
int raycount = 0;
bool gettingDigits = false;
for (int n = 0; n < datainput.size(); ++n)
{
char ch = datainput[n];
//if (isdigit(ch))
if (ch >= '0' && ch <= '9')
{
if (!gettingDigits)
{
str3 = "";
gettingDigits = true;
}
str3 += ch;
}
else
{
if (gettingDigits)
{
myray[raycount] = stoi(str3);
raycount++;
str3 = "";
gettingDigits = false;
if (raycount == 10) break;
}
}
}
if (gettingDigits && (raycount < 10))
{
myray[raycount] = stoi(str3);
raycount++;
}
for (int n = 0; n < raycount; ++n)
cout << myray[n] << endl;
system("pause");
return 0;
}
Live Demo
Alternatively:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string datainput, str3;
cin >> datainput;
int myray[10];
int raycount = 0;
string::size_type start = datainput.find_first_of("0123456789");
string::size_type end;
while (start != string::npos)
{
end = datainput.find_first_not_of("0123456789", start+1);
if (end == string::npos)
{
str3 = datainput.substr(start);
myray[raycount] = stoi(str3);
raycount++;
break;
}
str3 = datainput.substr(start, end-start);
myray[raycount] = stoi(str3);
raycount++;
if (raycount == 10) break;
start = datainput.find_first_of("0123456789", end+1);
}
for (int n = 0; n < raycount; ++n)
cout << myray[n] << endl;
system("pause");
return 0;
}
Live Demo
So, you want to segregate numbers and characters into different arrays.
In if block, you are checking for characters, so, I suspect stoi() wouldn't work.
Better typecast it to an integer.
int temp[10];
if (datainput[n] == ('0') || ...) {
temp[n] = int(datainput[n]);
}
This way your temp array would contain the numbers.
I know that I can check if a "word" is all letters by:
bool checkAlpha(string str){
bool retVal;
for(int i = 0; i < str.size(); i++){
if(isalpha(str[i]) == 0){
retVal = true;
cout << "Input must only contain letters\n";
break;
}
else{
retVal = false;
cout << "all good\n";
}
}
return retVal;
}
Because of how I use the function return value, I need it to return TRUE if it is NOT all letters, and FALSE if it IS all letters. There's probably an easier way to do this but I just started C++ so this works for my current purpose.
My question is how do I check if a string is multiple "words"? When it reaches a space the function (correctly) says the space is not an alpha and tells me the input must only be letters. I tried doing
if((isalpha(str[i]) != 0) || (str[i] == " "))
and changing the "if" to return false (input only letters & space) and "else" to return true, but when I tried this I got a compiler error:
ISO C++ forbids comparison between pointer and integer [ -fpermissive]
So what can I do to get that a string of user input is only letters or space? (Preferably the simplest method)
This statement:
str[i] == " "
Is incorrect, it should be:
str[i] == ' '
but even better
isspace( str[i] )
as your condition does not check for other symbols like tab etc.
Also you have break in logic, in case you meet not alpha and not space you can set retVal to true (and also should terminate loop as you already got the answer), but you cannot set it to false otherwise. So your corrected code could be:
bool checkAlpha(const string &str){
bool retVal = false;
for(int i = 0; i < str.size(); i++){
if( !isalpha(str[i]) || !isspace(str[i]){
retVal = true;
cout << "Input must only contain letters\n";
break;
}
}
if( !retval )
cout << "all good\n";
return retVal;
}
if you do not need to provide diagnostic messages, function can be as simple as:
bool checkAlpha(const string &str){
for(int i = 0; i < str.size(); i++)
if( !isalpha(str[i]) || !isspace(str[i])
return true;
return false;
}
And your function name is confusing, based on return values it should be called checkNotAlpha
I guess it should be enought to fix it as follows:
if((isalpha(str[i]) != 0) || (str[i] == ' '))
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
main()
{
string str1;
char strArray[80];
cout << "Enter string: ";
getline(cin, str1);
transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
for(int i = 0;i < str1.length();i++)
{
if(str1[i] == ' ' || str1[i] == ',' || str1[i] == '.')
{
}
else
{
strArray[i] = str1[i];
}
}
cout << strArray;
return 0;
}
The for loop keeps stopping after it finds a space, comma, or period. Could someone explain to me why this is happening?
The problem is that i keeps incrementing even though you erased a character from the input. It's not actually stopping, just skipping a character. Since strArray now has a hole in it, it's likely that the hole is filled with 0 thus ending the C-string. P.S. this behavior is not guaranteed and you might end up with completely different results on another run of the program.
When you call erase it affects the container, so you need to handle this. erase() returns the iterator to the next element after the deleted one, so you should use that instead:
int i = 0;
for(string::iterator it = str1.begin(); it != str1.end(); )
{
if(*it == ' ' || *it == ',' || *it == '.')
{
it = str1.erase(it);
}
else
{
strArray[i++] = *it++;
}
}
strArray[i] = '\0'; // terminate string
Can you post which string you input for str1? Cause I try run it and it run well without stop. The only proplem I found with your code is that you erase the char in the loop which will lead to wrong result string.
You are erasing characters from the string while still continuing to increment the counter. Remove ++i from the for loop. Put it under the else clause.
for(int i = 0;i < str1.length();)
{
if(str1[i] == ' ' || str1[i] == ',' || str1[i] == '.')
{
str1.erase(i, 1);
}
else
{
strArray[i] = str1[i];
++i;
}
}
strArray[str1.length()] = '\0';