I have recently started learning C++ and have written a few lines which accepts a string, displays the number of characters in it and also displays the reverse of the input string. This is what I have written.
#include <iostream>
int main()
{
char string[25],rev_string[25];
int counter=0,length=0;
std::cout << "\n Enter the string : ";
std::cin >> string;
while(counter==!'\0')
{
counter=counter+1;
length=length+1;
}
counter=0;
std::cout << "The string has "<<length<<" characters in it.";
while(length>=0)
{
rev_string[counter]=string[length];
counter=counter+1;
length=length-1;
}
std::cout << "\n The reverse of the given string is : "<<rev_string;
return(0);
}
There is no error when I debug, however when I run the program, I get some unexpected value and the string length shows zero. Can you please point out where have I made mistakes.
This is what I get when I run the program.
while ( counter == !'\0' ) { … }
Well, !'\0' is true, which as an integer is 1. So you have while (counter == 1), and counter is initialized to 0, making the expression immediately false, so the loop never executes.
You probably meant to write != '\0'. But this is still a problem, since counter starts off with the value 0, and 0 != 0 is still false and the loop doesn’t loop.
When you input Hey as your string, the characters H, e, y, and \0 are placed in the string variable. You want to find where that \0 character is, which we see is at string[3]. So why are you comparing counter with '\0'? Maybe you want string[counter]?
When you get the number of characters in Hey, which is 3, you begin your reverse loop copying the \0 at index 3 to index 0 ... all 4 characters in the reverse order: \0, y, e, H. Unfortunately, the \0 at the start will mark the end of the string, so the string will appear empty..
C++ is difficult to learn if you learn it as C. And also you get some ugly habits. Please learn and practice C++.
#include <string>
#include <algorithm>
#include <iostream>
int main()
{
std::string s;
std::cin >> s;
std::cout << "number of characters: " << s.size() << std::endl;
std::reverse(s.begin(), s.end());
std::cout << "reverse string: " << s << std::endl;
}
This is how you write your problem in C++. Now compare with what you are trying to do and I think it speaks for itself.
Related
I want to take in a code, for example ABC and check whether the characters in the code appear in that exact order in a string, for example with the code ABC, and the string HAPPYBIRTHDAYCACEY, which meets the criteria. The string TRAGICBIRTHDAYCACEY with the code ABC however does not pass, because there's a "c" before the "b" after the "a". I want to use the find_first_of function to search through my string, but i want to check for any of the characters in "code", without knowing what characters are in "code" beforehand. Here is my program so far:
#include <iostream>
#include <string>
using namespace std;
int main() {
string code, str, temp;
int k = 0;
int pos = 0;
cin >> code >> str;
while (k < code.size()) {
pos = str.find_first_of(code,pos);
temp[k] = str[pos];
++k;
++pos;
}
cout << temp << endl; // debug. This is just outputs a newline when i
//run the program
if (temp == code) {
cout << "PASS" << endl;
}
else {
cout << "FAIL" << endl;
}
return 0;
}
I think your best bet is to find just the first character, once found, find the next in the remainder of the string, repeat until end of string or all characters found (and return false or true, respectively).
I don't think there's anything builtin for this. If the characters would need to appear directly after each other, you could use std::string::find() which searches for a substring, but that is not what you want.
So we got an optional assignment in our C++ class. The assignment is basically this:
Write a program that holds a string of at least 8 words.
Do the following:
1. Replace the letters of first word with '?'
2. Turn the letters of the last word to uppercase
We did not yet study vectors in our class.
When I first read the assignment, storing the strings to a vector seemed like a good idea so I went with it.
To replace the characters with a '?' I used a for loop. I know that this would not work if I only had to change only certain characters or every other character to a '?'.
My issue is with converting chars of a string to uppercase.
My thought process was: for loop iterates through all chars in the last word, if the char is lowercase it gets turned to uppercase, if it is already uppercase it does not change.
I believe that my approach could work for this problem, I just maybe did not express myself correctly or I made a silly error somewhere. Could anyone assist me or push me in the right direction?
What other options are there to iterate through all chars of a string stored in a vector? Is there another approach that might work better for this? Thank you for your time.
#include <vector>
#include <cctype>
#include <string>
#include <iostream>
using namespace std;
vector<string>words;
//stores words to vector words
void storeWords()
{
cout << "Input 8 words: " << endl;
string s = " ";
for(int i=0; i<=7; i++)
{
cin >> s;
words.push_back(s);
}
}
//prints our words
void printWords()
{
cout << "\n Words stored in vector: " << endl;
for (const string s : words)
cout << s << endl;
}
//replaces chars of the first word with a '?' sign
void replace1(vector<string>&v)
{
cout << "\nReplaced characters of the first word " << words[0] << " with '?'" << endl;
for (char c : words[0])
cout << "?";
}
void replace2(vector<string>&v)
{
for (char c : words[7])
{
if(islower(c))
c = toupper(c);
}
cout << endl;
cout << words[7]<<endl;
}
int main()
{
storeWords();
printWords();
replace1(words);
replace2(words);
return 0;
}
c = toupper(c) will assign c the uppercase value. However, changing c will not change what's inside words[7]. You can get around this by referencing the char directly (char &c).
void replace2(vector<string>&v)
{
for (char &c : words[7]) {
c = toUpper(c);
}
cout << endl;
cout << words[7]<<endl;
}
Also note that your requirements are to hold a string of at least 8 words. So words[7] will probably end up looking like words[words.size() - 1].
This
for (char c : words[7])
Should be:
for (char& c : words[7])
The first version modifies a local variable, while the second changes the actual characters in words[7].
The little ampersand (&) makes c a reference to a certain character in words[7], allowing you to change c as you would words[7][some_i].
Also, I should add that your replace functions do not need that vector argument.
Ideone Example with that change
I am fairly new to programming and have to create a program which reads the prompt: "I have 8 dollars to spend." It then needs to print out with each word on a separate line, and then if any of the strings is numeric, it needs to be divided by 2. Therefore it should end up printing out as:
I
have
4
dollars
to
spend.
I have managed to do everything, except finding the numeric value and dividing it by 2. So far I have this:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main()
{
string prompt;
string word;
cout << "Prompt: ";
getline(cin, prompt);
stringstream ss;
ss.str(prompt);
while (ss >> word)
{
cout << word << endl;
}
return 0;
}
After looking through various other posts, I cannot manage to get this to work. I'm assuming its an if/else statement within the while loop along the lines of, if numeric, set int num to num / 2 then cout << num << endl;, else cout << word << endl;, but I can't figure it out.
Thanks in advance.
You can use the stringstream class, which handles conversions between strings and other data types, to attempt to convert a given string to a number. If the attempt is successful, you know
The stringstream object allows you to treat a string as though it is a stream similar to cin or cout.
Incorporate this into your while loop, like so:
while (ss >> word)
{
int value = 0;
stringstream convert(word); //create a _stringstream_ from a string
//if *word* (and therefore *convert*) contains a numeric value,
//it can be read into an _int_
if(convert >> value) { //this will be false if the data in *convert* is not numeric
cout << value / 2 << endl;
}
else
cout << word << endl;
}
The strtol (C++11 version that works on std::string directly: std::stol) function is really good for testing whether a string holds a number, and if so, what the numeric value is.
Or you could continue using iostreams like you have been... try extracting a number (int or double variable), and if that fails, clear the error bit and read a string.
I dont have 50 rep so I cant comment, thats why I'm writing it as answer.
I think you can check it character by character, using Ascii value of each char, & if there are ascii values representing numbers between two spaces(two \n in this case as you've already seperated each word), then you have to divide the number by 2.
----------------- EDIT -----------------------
Based on juanchopanza's comment : I edit the title
Based on jrok's comment : I'm using ofstream to write, and ifstream to read.
I'm writing 2 programs, first program do the following tasks :
Has a vector of integers
convert it into array of string
write it in a file
The code of the first program :
vector<int> v = {10, 200, 3000, 40000};
int i;
stringstream sw;
string stringword;
cout << "Original vector = ";
for (i=0;i<v.size();i++)
{
cout << v.at(i) << " " ;
}
cout << endl;
for (i=0;i<v.size();i++)
{
sw << v[i];
}
stringword = sw.str();
cout << "Vector in array of string : "<< stringword << endl;
ofstream myfile;
myfile.open ("writtentext");
myfile << stringword;
myfile.close();
The output of the first program :
Original vector : 10 200 3000 40000
Vector in string : 10200300040000
Writing to File .....
second program will do the following tasks :
read the file
convert the array of string back into original vector
----------------- EDIT -----------------------
Now the writing and reading is fine, thanks to Shark and Jrok,I am using a comma as a separator. The output of first program :
Vector in string : 10,200,3000,40000,
Then I wrote the rest of 2nd program :
string stringword;
ifstream myfile;
myfile.open ("writtentext");
getline (myfile,stringword);
cout << "Read From File = " << stringword << endl;
cout << "Convert back to vector = " ;
for (int i=0;i<stringword.length();i++)
{
if (stringword.find(','))
{
int value;
istringstream (stringword) >> value;
v.push_back(value);
stringword.erase(0, stringword.find(','));
}
}
for (int j=0;j<v.size();i++)
{
cout << v.at(i) << " " ;
}
But it can only convert and push back the first element, the rest is erased. Here is the output :
Read From File = 10,200,3000,40000,
Convert back to vector = 10
What did I do wrong? Thanks
The easiest thing would be to insert a space character as a separator when you're writing, as that's the default separator for operator>>
sw << v[i] << ' ';
Now you can read back into an int variable directly, formatted stream input will do the conversion for you automatically. Use vector's push_back method to add values to it as you go.
Yes, this question is over a year old, and probably completely irrelevant to the original asker, but Google led me here so it might lead others here too.
When posting, please post a complete minimal working example, having to add #include and main and stuff is time better spent helping. It's also important because of your very problem.
Why your second code isn't working is all in this block
for (int i=0;i<stringword.length();i++)
{
if (stringword.find(','))
{
int value;
istringstream (stringword) >> value;
v.push_back(value);
stringword.erase(0, stringword.find(','));
}
}
istringstream (stringword) >> value interprets the data up to the comma as an integer, the first value, which is then stored.
stringword.find(',') gets you the 0-indexed position of the comma. A return value of 0 means that the character is the first character in the string, it does not tell you whether there is a comma in the string. In that case, the return value would be string::npos.
stringword.erase deletes that many characters from the start of the string. In this case, it deletes 10, making stringword ,200,3000,40000. This means that in the next iteration stringword.find(',') returns 0.
if (stringword.find(',')) does not behave as wished. if(0) casts the integer to a bool, where 0 is false and everything else is true. Therefore, it never enters the if-block again, as the next iterations will keep checking against this unchanged string.
And besides all that there's this:
for (int j=0;j<v.size();i++)
{
cout << v.at(i) << " " ;
}
it uses i. That was declared in a for loop, in a different scope.
The code you gave simply doesn't compile, even with the added main and includes. Heck, v isn't even defined in the second program.
It is however not enough, as the for condition stringword.length() is recalculated every loop. In this specific instance it works, because your integers get an extra digit each time, but let's say your input file is 1,2,3,4,:
The loop executes normally three times
The fourth time, stringword is 4, stringword.length() returns 2, but i is already valued 3, so i<stringword.length() is invalid, and the loop exits.
If you want to use the string's length as a condition, but edit the string during processing, store the value before editing. Even if you don't edit the string, this means less calls to length().
If you save length beforehand, in this new scenario that would be 8. However, after 4 loops string is already empty, and it executes the for loop some more times with no effect.
Instead, as we are editing the string to become empty, check for that.
All this together makes for radically different code altogether to make this work:
while (!stringword.empty())
{
int value;
istringstream (stringword) >> value;
v.push_back(value);
stringword.erase(0, stringword.find(',')+1);
}
for (int i = 0; i < v.size(); i++)
{
cout << v.at(i) << " " ;
}
A different way to solve this would have been to not try to find from the start, but from index i onwards, leaving a string of commas. But why stick to messy stuff if you can just do this.
And that's about it.
Consider this problem
User will enter input to one dimensional array(char test[100]) in sequence of
letter/space/index/space/letter....
like this
a 1 s 1 e 3 r 4 r 3 t 3 until an 'enter'is hit.
Index can be repeated as well as letter.
So above sequence should mean test[1]=a ,test[1]=s and so on.
To build this problem what I have thought is that I should test whether character entered is newline(enter) or not.
but i don't understand how to do that
can you suggest some code for this
Scrap the entire idea; your question is wrong. The user does not enter a char[100]. Rather, the user enters a string. And suddenly it's very easy:
#include <string>
#include <iostream>
int main()
{
std::string user_input;
std::getline(std::cin, user_input);
// done: now use user_input
}
Now you can iterate over the string, tokenize it, or whatever. For example:
std::istringstream iss(user_input);
char c;
int n;
while (iss >> c >> n)
{
std::cout << "We have a pair (" << c << ", " << n << ")\n";
}