I need to input a string, if the string is just a whole string and not with spaces, the codes is fine, if the input is a string with spaces, the string only copys the first set of strings and not the whole strings? I'm an noob, please help.
#include <stdio.h>
#include <string.h>
int main() {
char again = 0;
do {
char str[60], s[60];
int i, j = 0;
printf("Enter any string->");
scanf("%s", str);
printf("The string is->%s", str);
for (i = 0; i <= strlen(str); i++) {
if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' ||
str[i] == 'o' || str[i] == 'u' || str[i] == 'A' ||
str[i] == 'E' || str[i] == 'I' || str[i] == 'O' ||
str[i] == 'U') {
str[i] = ' ';
} else {
s[j++] = str[i];
}
}
s[j] = '\0';
printf("\nThe string without vowel is->%s", s);
NSLog(#"Do you want to enter another string to be edit? (y/n) ");
scanf("%s", &again);
} while (again != 'n');
}
Your code stops reading at a space because that's how scanf works with the %s format. It reads a sequence of non-whitespace characters.
If you're really using C++, then you'd be wise to switch to std::string and std::getline, which will read all input up to the end of the line. Your code doesn't appear to use any C++ features, though, so maybe you're really using C. In that case, consider fgets instead. It will read the whole line, too (up to a specified size, which generally corresponds to the size of your buffer).
This code is a mess.
C++ features like std::string are not used at all.
You're mixing printf/scanf and NSLog for no reason.
Modifying str in the if branch makes no sense, as it won't be read later.
You probably want to use i < strlen(str) instead of <=, or you'll copy that terminating zero character twice.
Your scanf("%s", &again); specifies to read a string, but you only have memory for a character, thus you probably end up writing into some random memory position.
While some of these points are more severe than others, I suggest fixing those issues and see what happens. If you experience unexpected output, then please do give your example input and output as well.
You are allocating an array of 60 chars long (str). You can't expect to read a lot into it. Here are a few tips:
Don't use such buffers, they are dangerous. The C++ library provides you std::string.
Never omit the curly braces {}.
There are an easier way to check for chars than this horribly long if. Hint: std::string::find_first_of
Related
for (int i = 0; str1[i] && str2[i]; i++)
What does str1[i] && str2[i] mean? I have known the middle part of a for loop to be a condition but how is that a condition? What is it checking?
This loop keeps going until either one of the values is falsy. Most likely, both of them are C-style strings (which are simple char arrays or pointers, terminated with a NUL character, '\0'), and the loop is intended to continue until it's reached the end of the shortest string (the first one in which it finds NUL).
This expression:
str1[i] && str2[i]
Is equivalent to
(str1[i] != '\0') && (str2[i] != '\0')
The for loop terminates when either str1[i] or str2[i] is the end of the string.
In other words, when the for loop terminates, i is the length of the shorter of str1 and str2. (Although by then, i is out scope).
str1 and str2 are probably c strings (char *, char []) so the for loop iterates till either str1[i] or str2[i] are \0 which is the string terminator. The string "hi" is a more convenient way to write { 'h', 'i', '\0' }.
I am given a string and I have to remove a substring from it. Namely WUB, and replace it with a space character.
There are 2 WUB's between ÁRE' and 'THE'. SO the first condition in if statement is for not printing two blank spaces but on executing the code two blank spaces are being printed.
Input: WUBWEWUBAREWUBWUBTHEWUBCHAMPIONSWUBMYWUBFRIENDWUB
Output: WE ARE THE CHAMPIONS MY FRIEND
Here is my code so far:
#include <iostream>
using namespace std;
int main()
{
const string check = "WUB";
string s, p;
int ct = 0;
cin >> s;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
{
i += 2;
if (p[ct] == '32' || p.empty())
{
continue;
}
else
{
p += ' ';
ct++;
}
}
else
{
p += s[i];
ct++;
}
}
cout << p;
return 0;
}
Why is the first if statement never executed?
2 things are going to break your code:
you are doing a for loop like this int i=0;i<s.size() but reading (s[i]=='W' && s[i+1]=='U' && s[i+2]=='B')
and here: if(p[ct]=='32') you mean for sure if(p[ct]==32) or if(p[ct]==' ')
This condition
if(p[ct]=='32')
should read either
if(p[ct]==32)
or
if(p[ct]==' ')
that is, compare to the numeric value of the space character or to the space character itself.
Additionally, when your i grows close to the string's length, the subexpressions s[i+1] and s[i+2] may reach non-exiting characters of the string. You should continue looping with a i<s.length()-2 condition.
EDIT
For a full solution you need to fully understand the problem you want to solve. The problem statement is a bit vague:
remove a substring ("WUB") from (a given string). And put a space inplace of it if required.
You considered the last condition, but not deeply enough. What does it mean, 'if required'? Replacement is not required if the resulting string is empty or you appended a space to it already (when you encounter a second of further consecutive WUB). It is also not necessary if you are at WUB, but there is nothing more following it - except possibly another WUBs...
So, when you find a "WUB" substring it is too early to decide if a space is needed. You know you need a space when you find a non-WUB text following some WUB (or WUBs) and there was some text before those WUB(s).
There are actually three bugs here, so it's probably worth to conclude them in one answer:
The first condition:
if (s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
is out of bounds for the last two characters. One fix would be to check the length first:
if(i < s.length() - 2 && s[i] == 'W' && s[i+1] == 'U' && s[i+2] == 'B')
There's a multicharacter-literal in
if (p[ct] == '32' || p.empty())
Use ' ' or 32 or std::isspace instead. IMO the last one is the best.
In the same condition
p[ct] == '32'
is always out of bounds: ct is equal to p.length(). (Credits to Some programmer dude, who mentioned this in the comments!) The variable ct is also redundant, since std::string knows it's length. I suggest to use std::string::back() to access the last character and reorder the condition as so:
if (p.empty() || std::isspace(p.back()))
The algorithm to this program is on the right track.
However, there is a few issues..
The for loop goes out of index. A way to solve this issue is substracting the size -3. Something like this.
for (int i=0; i<s.size()-3; i++) {
}
I do not suggest using other variables as counters like ct. In this case ct can reach an index out of bound error by using p[ct] inside the for loop.
Creating a string and using append() function will be a better solution. In this case, we iterate through each character in the string and if we find "WUB" then we append a " ". Otherwise, we append the character.
I highly recommend to write the first if() statement using substring() from C++.
This makes the code easier to read.
Substring creates and returns a new string that starts from a specific position to an ending position. Here is the syntax
syntax: substr(startingIndex, endingIndex);
endingIndex is exclusive
#include <string>
#include <iostream>
int main() {
string s, p;
cin >> s;
for(int i=0;i<s.size()-3;i++) {
if (s.substr(i, i+3) == "WUB") {
p.append(" ");
} else {
p.append(s.substr(i,i+1));
i++;
continue;
}
i+=3;
}
}
I'm trying to make a program which modifies words in a specific manner:
It should first check the ending of the words and then proceed to modify them. I won't explain it in detail, because it doesn't make much sense in English.
I've written the following:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Por favor, introduzca los gentilicios separados por la tecla enter, para finalizar, escriba OK" << '\n';
string name[10];
string place[10];
for (int i(0); (i < 10); i++)
{
getline(cin, name[i]);
if (name[i] == "OK") //Error here
break;
}
for (int i(0); (i < 10); i++)
{
place[i] = name[i];
if (name[i][name[i].length() - 1] == 'c')
{
if (name[i][name[i].length()] == 'a' || (name[i][name[i].length()] == 'o') || (name[i][name[i].length()] == 'u'))
place[i][place[i].length() - 1] = 'q';
place[i][place[i].length()] = 'u';
place[i] = place[i] + "istan";
}
else if (name[i][name[i].length()] == 'a' || name[i][name[i].length()] == 'e' || name[i][name[i].length()] == 'i' || name[i][name[i].length()] == 'o' || name[i][name[i].length()] == 'u')
{
place[i][place[i].length()] = 'i';
place[i] = place[i] + "stan";
}
if (name[i][name[i].length()] == 's')
place[i] = place[i] + "tan";
else {
place[i] = place[i] + "istan";
}
place[i][0] = toupper(place[i][0]);
}
for (int i(0); (i < 10); i++)
{
cout << place[i] << '\n';
}
return 0;
}
Now I'm getting the error "String subscript out of range" . I would like to know where is the error exactly. I know it prompts when I write "OK", at line "18".
The condition i <= sizeof(name). sizeof(name) returns the size of the array in bytes, not the number of elements in it. Even if it returned the number of elements, <= is wrong and would cause an out-of-bounds access (should be <).
To loop through all elements in an array, you can use the range-based for-loop:
for(auto& n : name)
{
getline(cin, n);
if (n == "OK")
break;
}
Or to do it the right way with the C-style for-loop:
for (int i(0); i < sizeof(name)/sizeof(name[0]; i++)
{
…
}
Here:
for (int i(0); (i <= sizeof(name)); i++)
sizeof(name) is the size in bytes of the array, which as it is an array of std::string is effectively meaningless. If you want to iterate over 10 items, simply say so (note also that less-than-or-equals is also wrong here):
for (int i = 0; i < 10; i++)
And here:
getline(cin, name[i]);
whenever you perform input you must check the return value of the input function and handle any errors:
if( ! getline(cin, name[i]) ) {
// handle error somehow
}
And here:
string * p;
you do not want to be dealing with pointers to strings. If you want to access the contents of a string, you use operator[] or other string member functions on the string.
std::strings are not like cstrings. You can just grab a part of them using a std::string*. When you do
*(p+ (name[i].length()-2))
You actually say advance the address stored in p by name[i].length()-2 amount and access that string. If you go past the end of the name array then that is undefined behavior. If not you still haver a std::string which cannot be compared with a char. If you want to check if the string ends with "ca" then you can just use
if (name[i].substr(name[i].size() - 2) == "ca")
You're last loop is doing something quite funky. There's no need to go that far. You can just do something like:
if (name[i][name[i].length - 2] == 'c')
To compare the next to last character with c. And a very similar test to compare the last one with a.
To clarify why what you're doing is not OK, you first get p as a pointer to a string to the current element. Then you do some pointer arithmetic p + (name[i].length - 2), which still results in a pointer to a string. Finally, you dereference this, resulting in a string. Which you can't compare to a char. Moreover, the pointer was to some arbitrary address in memory, so the dereference would produce a string with very bad data in it. Quite arbitrary, one might say. If you tried to work with it you'd break your program
You seem to be working with the string as one would with a C-like string, a char*. The two are not the same, even though they represent the same concepts. A C++ string, usually, has a size field, and a char* pointer inside it, as well as a bunch of other logic to make working with it a char-m.
Because you aren't comparing against a specific char in the string, you're comparing against a string.
Considering the following bit of code:
*(p + (name[i].length() - 2))
This evaluates to a string because you are taking p (a string*) and concatenating a char to it. This means it's still a string (even though it's a one-character string), thus the other side of the equation won't be comparable to it.
What you need here instead is this:
if (name[i][name[i].length() - 2] == 'c')
Since name[i] is already a string, we can just get the char from it using the code above. This does return char, so it's comparable. This also allows you to get rid of the whole string* bit as it is not needed.
First, (i <= sizeof(name)) is wrong, it should be i < sizeof(name) / sizeof(*name). sizeof(array) return the size of array in bytes, you need to divide the size of an array's element to actually get the maximum element count of an array. If you find that complicated then use std::vector:
vector<string> name(10); //a vector of size 10
for (size_t i = 0; i < name.size(); i++) //name.size(), simple
Secondly, you need to keep track of how many strings in your name array. Or you need to check if name[i] == "OK" then break the second loop (similar to the first loop). name[i] after "OK" are invalid.
Thirdly, don't use *(p+ (name[i].length()-2)). If you want the second last character of name[i], you can write it as name[i][name[i].size()-2] or name[i].end()[-2] or end(name[i])[-2]
If you want to check if the word ends in "ca", then you can use substr:
if (name[i].substr(name[i].size() - 2) == "ca")
{
//...
}
I'm trying to count the total number of vowels in a string. I'm using strlen to get the total length of the string but then when I try and count through the string by each letter it says C++ forbids comparison. So I assume something is wrong in my if statement.
#include <iostream>
#include <cstring>
using namespace std;
int main() {
char sentence[] = "";
int count;
int total;
int length;
int lengthcount;
int output;
output = 0;
length = 0;
count = 0;
total = 0;
cin >> total;
while (total != count){
cin >> sentence;
length = strlen(sentence);
while (length != lengthcount)
if (sentence[length] == "a" ||sentence[length] == "e"||sentence[length] == "i"||sentence[length] == "o"||sentence[length] == "u"||sentence[length] == "y"){
++ output;
++ lengthcount;
else{
++lengthcount;
}
}
++count;
}
return 0;
}
sentence[length] is a single character. It should be compared to a 'a' and not "a".
"a" is a character array and direct comparison with the built in operator== is not supported.
sentence[index] == 'a'; // where index is probably lengthcount in your example
Should do the trick. If use of std::string is an option, you should favour that over char arrays.
In addition, your char sentence[] = ""; will need some more space than just the '\0' character. Some alternatives include the use of std::string and std::getline or char[nnn] with cin.get(...) to make sure that you don't overrun the buffer you allocate.
See Nialls answer for one of the main problems.
The algorithmic problem with your code is again in the if statement.
sentence[length] returns the last character of your c_string (in this case, the null character '/0' that terminates the string).
Your if statement should look more like:
if (sentence[lengthcount] == 'a'\
||sentence[lengthcount] == 'e'\
||sentence[lengthcount] == 'i'\
||sentence[lengthcount] == 'o'\
||sentence[lengthcount] == 'u'\
||sentence[lengthcount] == 'y')
{
\\do something
}
Please remember to pre-allocate space for the string too, i.e.
char sentence[50];
which would give you space for 49 chars + terminator.
Alternatively, use a std::string
If you wish to count the total number of vowels in the given string, you need to use sentence[lengthcount]. Lets say the sentence is abc strlen(sentence) would return 3, and since in c++, the indexing begins with 0 and not 1, therefore sentence[length] would check for '\0' hence in the entire loop you check against the last value which is '\0' which is meaningless. Also, don't forget to initialize lengthcount. Rest all the things per-mentioned.
char sentence [] = "" produces an array sentence with a length of 1.
cin >> sentence isn't going to work very well, is it, if sentence cannot hold more than one character and one character is already needed for the trailing nul byte?
lengthcount is an unitialised variable, and the rest of the code just makes my head hurt.
I'm trying to create a program that removes vowels from a string, add them into a vector and then give the user the possibility of having the original code again.
In my code i have this:
char s[20];
And soon after i have this comparison:
for(j=0;j<tam;j++)
{
if(strcmpi(s[j],"a")==1 ||
(strcmpi(s[j],"e")==1 ||
(strcmpi(s[j],"i") ==1||
(strcmpi(s[j],"o") ==1||
(strcmpi(s[j],"u")==1))
{
So if the array is char and the vowels are char(""), why the compiler give me this error?:
[Warning] passing arg 1 of `strcmpi' makes pointer from integer without a cast
EDIT
As someone said the correct is s[j] == 'a', but that result in wrong way. If a put car the result is still car. Don't know why.
if(s[j] == 'a' ||
s[j] == 'A' ||
s[j] == 'e' ||
s[j] == 'E' ||
s[j] == 'i' ||
s[j] == 'I' ||
s[j] == 'o' ||
s[j] == 'O' ||
s[j] == 'u' ||
s[j] == 'U')
{
s[j] = s[j++]; }
Strcmpi is for comparing strings. The first argument to strcmpi is of type char, when it expects a char*.
In order to compare single chars, s[j]=='e' is enough, or tolower(s[j])=='e' if you need it to be case insensitive. You'll need to include ctype.h. for tolower.
The arguments to strcmpi must be strings, but s[j] is just a single character, not a string. You can use == to compare characters directly. To get case-insensitive comparisons, get the lowercase version of the character first and compare it.
for (j = 0; j < tam; j++) {
char lower = tolower(s[j]);
if (lower == 'a' || lower == 'e' || lower == 'i' || lower == 'o' || lower == 'u') {
...
}
}
You don't want to use strcmp or any of its variants.
Because you want to know whether the string contains vowels or not, you may want to use a substring search using strstr.
You use function strcmpi incorrectly. It first parameter has type const char * while you pass an argument of type char. That is the function expects a string while you pass only one character.
Moreover this function is not a standard C/C++ function. So it should not be used.
You could achieve the same result using the following approach
char vowels[] = "aeiou";
//...
if ( strchr( vowels, tolower( s[j] ) )
{
std::cout << s[j] << " is a vowel" << std::endl;
}
You have already been told that strcmpi is not the right way to check single characters. This is an answer to the edit to your question, where you ask about actually stripping the vowels.
If you want to retain the original string, you need extra memory for the string without consonants. You also need two indices, because once you have skipped a vowel in the original string, the indices are out of sync. Here's an example implementation:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
char orig[] = "Jackdaws love my big sphinx of quartz.";
char cons[sizeof(orig)]; // Make new char buffer as big
// as the original
int i, j;
j = 0;
for (i = 0; orig[i]; i++) {
if (strchr("AEIOUaeiou", orig[i]) == NULL) {
cons[j++] = orig[i];
}
}
cons[j] = '\0'; // Terminate consonant string
printf("was: '%s'\n", orig);
printf("is: '%s'\n", cons);
return 0;
}
The expression strchr checks whether a character is in a string. You can use it as a shortcut to spelling out all vowels in explicit comparisons.