This code here is for reversing words in a string. The problem is that it only reverses the first word in the string. When I ran a trace I found that it is stopping after encountering the statement if(s[indexCount] == '\0') break;
Why the code is getting null character every time the first word is reversed even though some other character is present after the first word.
#include <iostream>
using namespace std;
int main()
{
string s;
char tchar;
int indexCount=0,charCount=0,wordIndex;
cin>>s;
while(1){
if(s[indexCount]==' ' && charCount==0) continue;
if(s[indexCount]==' ' || s[indexCount]=='\0' ){
wordIndex=indexCount-charCount;
charCount=indexCount-1;
while(charCount!=wordIndex && charCount>wordIndex){
tchar=s[wordIndex];
s[wordIndex]=s[charCount];
s[charCount]=tchar;
charCount--;
wordIndex++;
}
if(s[indexCount] == '\0') break;
indexCount++; charCount=0;
}
else{
charCount++;
indexCount++;
}
}
cout<<"\nReveresed words in the string : \n\t"<<s<<endl;
return 0;
}
Also I'm using while(1). Does it make this a bad code?
The problem indeed lies with the method of input. cin >> string_variable will consider whitespace to be a delimiter. That is why only the first word is being entered. Replace cin >> s; with getline(cin, s); and it will work correctly.
First of all I want to point out that
cin >> stringObject;
will never ever read space character! so inserting My name is geeksoul will cause above code to read only My and leave everything else in the buffer!
To read space character you should use getline function like this
std::getline(std::cin, stringObject);
read about getline
Second The standard doesn't say that in case of an std::string '\0' is any special character. Therefore, any compliant implementation of std::string should not treat '\0' as any special character. Unless of course a const char* is passed to a member function of a string, which is assumed to be null-terminated.
If you really want to check your string with null terminating character then you should consider using stringObject.c_str() which converts your C++ style string to old school C style string!
Check this for c_str
Finally this might be helpful for you!
Quick tip.
If you reverse all characters in the whole strings, and then all characters between each pair of consecutive spaces, you will achieve the same result, with way simple code, like this: (Note, this may not compile or be slightly buggy (haven't compiled or anything), but should convey the basic idea)
void reverseWords(std::string& aString) {
std::reverse(aString.begin(), aString.end());
size_t lastSpaceIndex = 0;
for (size_t index = 0; index != aString.size(); ++index) {
if (aString[index] == ' ') {
std::reverse(aString.begin() + lastSpaceIndex + 1, aString.begin() + index);
lastSpaceIndex = index;
}
}
}
Related
I was wondering if there is a way of using the cin.get() fuction in a loop to read a string that could be composed of more than one word.
For example
while (cin.get(chr)) // This gets stuck asking the user for input
while (cin.get(chr) && chr != '\n') // This code doesn't allow the '\n' to be read inside the loop
I want to be able to read a whole string and be able to use my chr variable to determine if the current character being read is a '\n' character.
I'm a little familiar with the getline function. But I don't know of a way to individually go through every character in the string while counting them when using the getline. I hope what I'm saying makes sense. I'm new to programming and c++.
I basically want to determine when these characters ( ' ' , '\n') happen in my string. I will use this to determine when a word ends and a new one begins in my string.
If you want to read a whole line and count the spaces in it you can use getline.
std::string s;
std::getline(std::cin, s);
//count number of spaces
auto spaces = std::count_if(s.begin(), s.end(), [](char c) {return std::isspace(c);});
std::getline will always read until it encounters an \n.
You could try the following:
using namespace std;
int main() {
char ch;
string str = "";
while (cin.get(ch) && ch != '\n')
str += ch;
cout << str;
}
and the string str would have all characters till end line.
As the title says, how do I replace a string with another string? For example: the user would enter three inputs. The first input is the string that the program would replace; the second is the string that would replace input1; and the third is the string that would be printed out. So if:
Input1 = peanut
Input2 = coconut
Input3 = replacepeanutreplace
Output: replacecoconutreplace
I have started it but my program can only replace words with the same length. I tried searching my problem, but I do not understand the given solutions since I am just new at C/C++.
char replacing[100];
char replacement[100];
char original[1000];
int count;
cin >> replacing;
cin >> replacement;
while(! cin.eof())
{
cin >> original;
char * pch;
pch = strstr (original, replacing);
count = strlen(replacement);
strncpy (pch, replacement, count);
cout << original << endl;
}
What about:
You first find (if any) an occurrence of that string
Use replace to substitute the occurrence with the second string
Here is something that should work:
bool replaceFirst(string& input, const std::string& toBeReplaced, const std::string& replacement) {
size_t start_pos = input.find(toBeReplaced);
if(start_pos == std::string::npos)
return false; //substring not found!
input.replace(start_pos, toBeReplaced.length(), replacement); //found. now i can replace!
return true;
}
Since you are using an array of char instead of string you have to make sure that replacing does not lead you out of bound (strings auto-resize for you).
The key problem is that strncpy does not allocate (or free) any memory. This means that if replacement is shorter that replacing, part of replacing will not be overwritten. Similarly if replacement is longer it will overwrite beyond the end of replacing.
As already said, you would be better off using std::string (or some other C++ string class like Qt's QString if Qt is your cup of tea).
One other little thing, in general with streams it's best not to just check for eof, rather write something like
while (cin >> original) {
This will terminate if the stream is in any fail state, not just eof.
I am a beginner in c++ and I want to enter a string as character by character into an array , so that I can implement a reverse function .. However unlike C when the enter is hit a '\n' is not insterted in the stream.. how can I stop data from being entered ?
my code is :
#include<iostream>
#include<array>
#define SIZE 100
using namespace std;
char *reverse(char *s)
{
array<char, SIZE>b;
int c=0;
for(int i =(SIZE-1);i>=0;i--){
b[i] = s[c];
c++;
}
return s;
}
int main()
{
cout<<"Please insert a string"<<endl;
char a[SIZE];
int i=0;
do{
cin>>a[i];
i++;
}while(a[i-1]!= '\0');
reverse(a);
return 0;
}
When you read character by character, it really reads characters, and newline is considered a white-space character.
Also the array will never be terminated as a C-style string, that's not how reading characters work. That means your loop condition is wrong.
To begin with I suggest you start using std::string for your strings. You can still read character by character. To continue you need to actually check what characters you read, and end reading once you read a newline.
Lastly, your reverse function does not work. First of all the loop itself is wrong, secondly you return the pointer to the original string, not the "reversed" array.
To help you with the reading it could be done something like
std::string str;
while (true)
{
char ch;
std::cin >> ch;
if (ch == '\n')
{
break; // End loop
}
str += ch; // Append character to string
}
Do note that not much of this is really needed as shown in the answer by Stack Danny. Even my code above could be simplified while still reading one character at a time.
Since you tagged your question as C++ (and not C) why not actually solve it with the modern C++ headers (that do exactly what you want, are tested, save and work really fast (rather than own functions))?
#include <string>
#include <algorithm>
#include <iostream>
int main(){
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
return 0;
}
output:
Enter a string: Hello Test 4321
1234 tseT olleH
I'm pretty new to C++, coming from Java. I'm working on just extracting the first word from a Char array, so I figure that creating a new array to hold all the first word chars and transferring them till the loop runs into a space in the sentence would work. Here is the code:
void execute(){
//start with getting the first word
char first_word[20];
int i = 0;
while (input[i] != ' '){ // input is a char array declared and modified with cin, obtaining the command.
first_word[i] = input[i];
i++;
}
print(first_word + ' ' + 'h' + ' ' + 'h' + 'a');
}
When trying to execute this, I get the error "Stack around the variable 'first_word' was corrupted". Why is this happening?
cin >> input doesn't do what you think it does when input is a character array. The >> operator cannot read into a character array, you have to use cin.getline() or cin.read() instead. So you are actually causing undefined behavior by processing invalid memory.
Even if it did work, you are also not doing any bounds checking. If input has more than 20 characters before encountering a space character (or worse, does not contain a space character at all), you will write past the end of first_word into surrounding memory.
If you really want to code in C++, don't use character arrays for strings. That is how C handles strings. C++ uses std::string instead, which has find() and substr() methods, amongst many others. And std::cin knows how to operate with std::string.
For example:
#include <string>
void execute()
{
//start with getting the first word
std::string first_word;
std::string::size_type i = input.find(' '); // input is a std::string read with cin, obtaining the command.
if (i != std::string::npos)
first_word = input.substr(0, i);
else
first_word = input;
std::cout << first_word << " h ha";
}
I created the program to read from text file and remove special characters. I can't seem to code better the if statement. Please help. I searched online for the right code statements but they have all advanced code statements. The book I am learning from has the last(14th) chapter with strings and file open and closing code. I tried creating an array of special chars, but did not work. Please help me!
int main()
{
string paragraph = "";
string curChar = "";
string fileName = "";
int subscript=0;
int numWords=0;
ifstream inFile; //declaring the file variables in the implement
ofstream outFile;
cout << "Please enter the input file name(C:\owner\Desktop\para.txt): " << endl;
cin >> fileName;
inFile.open(fileName, ios::in); //opening the user entered file
//if statement for not finding the file
if(inFile.fail())
{
cout<<"error opening the file.";
}
else
{
getline(inFile,paragraph);
cout<<paragraph<<endl<<endl;
}
numWords=paragraph.length();
while (subscript < numWords)
{
curChar = paragraph.substr(subscript, 1);
if(curChar==","||curChar=="."||curChar==")"
||curChar=="("||curChar==";"||curChar==":"||curChar=="-"
||curChar=="\""||curChar=="&"||curChar=="?"||
curChar=="%"||curChar=="$"||curChar=="!"||curChar==" ["||curChar=="]"||
curChar=="{"||curChar=="}"||curChar=="_"||curChar==" <"||curChar==">"
||curChar=="/"||curChar=="#"||curChar=="*"||curChar=="_"||curChar=="+"
||curChar=="=")
{
paragraph.erase(subscript, 1);
numWords-=1;
}
else
subscript+=1;
}
cout<<paragraph<<endl;
inFile.close();
You might want to look into the strchr function which searches a string for a given character:
include <string.h>
char *strchr (const char *s, int c);
The strchr function locates the first occurrence of c (converted to a char) in the
string pointed to by s. The terminating null character is considered to be part of the
string.
The strchr function returns a pointer to the located character, or a null pointer if the
character does not occur in the string.
Something like:
if (strchr (",.();:-\"&?%$![]{}_<>/#*_+=", curChar) != NULL) ...
You'll have to declare curChar as a char rather than a string and use:
curChar = paragraph[subscript];
rather than:
curChar = paragraph.substr(subscript, 1);
but they're relatively minor changes and, since your stated goal was I want to change the if statement into [something] more meaningful and simple, I think you'll find that's a very good way to achieve it.
In <cctype> header we have functions like isalnum(c) which returns true iff c is an alpanumeric character, isdigit(c) etc... I think the condition you are looking for is
if(isgraph(c) && !isalnum(c))
But c must be a char, not an std::string (well, technically speaking c must be int, but the conversion is implicit:) hth
P.S. This isn't the best idea, but if you want to keep sticking with std::string for curChar, c will be this char c = curChar[0]
since you are learning c++, I will introduce you the c++ iterator way of erasing.
for (string::iterator it = paragraph.begin();
it != paragraph.end();
++it)
while (it != paragraph.end() && (*it == ',' || *it == '.' || ....... ))
it = paragraph.erase(it);
First, try using iterator. This won't give you best performance, but its concept would help you work with other c++ structure.
if(curChar==","||curChar=="."||curChar==")" ......
Second, single quote ' and double quote " differs. You use ' for char.