Currently doing a project at uni where at first I need to de-hyphenate a string, seemed pretty simple however when i run the program it has an error WeirdPuncProgram.exe: Microsoft C++ exception: std::out_of_range at memory location 0x004EF898
It also is not returning the string value properly, inside the function answer() is changed and hyphens are removed but once it comes out its just the original input again.
#include <iostream>
#include <string>
using namespace std;
string answer;
string hyphonRemover(string answer)
{
string spacer = " ";
int h;
for (int i = 0; i < answer.length(); i++)
{
h = answer.find_first_of("-");
answer.replace(h, 1, spacer);
}
return answer;
}
int main()
{
cout << "Type a sentence which contains punctuation and ill remove it for you! " << endl << endl;
getline(cin, answer);
hyphonRemover(answer);
cout << answer << endl;
system("pause");
return 0;
}
every use of answer in hyphonRemover() will be local variable, not global answer you defined above.
thus the function will modify only its local variable.
Related
I have a c++ program where I need to iterate through a string and print the characters. I get the correct output but along with the output I get some garbage values(garbage value is 0). I don't know why i get those values? Can anyone help me with that?
#include <iostream>
using namespace std;
int number_needed(string a) {
for(int i=0;i<a.size();i++)
{
cout<<a[i];
}
}
int main(){
string a;
cin >> a;
cout << number_needed(a) << endl;
return 0;
}
sample Input
hi
Output
hi0
The behaviour of your program is undefined. number_needed is a non-void function so therefore it needs an explicit return value on all program control paths.
It's difficult to know what you want the cout in main to print. Judging by your question text, you may as well change the return type of number_needed to void, and adjust main to
int main(){
string a;
cin >> a;
number_needed(a);
cout << endl; // print a newline and flush the buffer.
return 0;
}
The problem is with this line:
cout << number_needed(a) << endl;
Change it to just:
number_needed(a);
The problem is that number_needed() is outputting each letter of the string, but after that, you're outputting the value returned by number_needed(), which is 0.
for(int i=0;i<50;i++,size++)
{
cin >> inputnum[i];
cout << size;
if(inputnum[i] == '.')
{
break;
}
}
The break breaks the input stream but the size keeps outputting.
The output of size is 012345678910111213...474849.
I tried putting size++ inside the loop but it made no difference. And size afterwards will be equal to 50, which means it went through the full loop.
I forgot to explain that I added the cout << size within the loop to debug/check why it outputted to 50 after the loop even if I only inputted 3 numbers.
I suspect that inputnum is an array of int (or some other numeric type). When you try to input '.', nothing actually goes into inputnum[i] - the cin >> inputnum[i] expression actually fails and puts cin into a failed state.
So, inputnum[i] is not changed when inputting a '.' character, and the break never gets executed.
Here's an slightly modified version of your code in a small, complete program that demonstrates using !cin.good() to break out of the input loop:
#include <iostream>
#include <ostream>
using namespace std;
int main()
{
int inputnum[50];
int size = 0;
for(int i=0;i<50;i++,size++)
{
cin >> inputnum[i];
if (!cin.good()) {
break;
}
}
cout << "size is " << size << endl;
cout << "And the results are:" << endl;
for (int i = 0; i < size; ++i) {
cout << "inputnum[" << i << "] == " << inputnum[i] << endl;
}
return 0;
}
This program will collect input into the inputnum[] array until it hits EOF or an invalid input.
What is inputnum ? Make sure t's a char[]!! with clang++ this compiles and works perfectly:
#include <iostream>
int main() {
int size = 0;
char inputnum[60];
for(int i=0;i<50;i++,size++) {
std::cin >> inputnum[i];
std::cout << size;
if(inputnum[i] == '.') {
break;
}
}
return 0;
}
(in my case with the following output:)
a
0a
1s
2d
3f
4g
5.
6Argento:Desktop marinos$
Your code seams OK as long as you're testing char against char in your loop and not something else.. Could it be that inputnum is some integral value ? if so, then your test clause will always evaluate to false unless inputnum matches the numerical value '.' is implicitly casted to..
EDIT
Apparently you are indeed trying to put char in a int[]. Try the following:
#include <iostream>
int main() {
using namespace std;
int size = 0;
int inputnum[50];
char inputchar[50];
for(int i=0;i<50;i++,size++) {
cin >> inputchar[i];
inputnum[i] = static_cast<int>(inputchar[i]); // or inputnum[i] = (int)inputchar[i];
cout << size << endl; // add a new line in the end
if(inputchar[i] == '.') break;
}
return 0;
}
Then again this is probably a lab assignment, in a real program I'd never code like this. Tat would depend on the requirements but I'd rather prefer using STL containers and algorithms or stringstreams. And if forced to work at a lower-level C-style, I'd try to figure out to what number '.' translates to (simply by int a = '.'; cout << a;`) and put that number directly in the test clause. Such code however might be simple but is also BAD in my opinion, it's unsafe, implementation specific and not really C++.
Hi i am trying to write a c++ program where the user will enter a name lets say for example: Tahmid Alam Khan Rifat and the computer will print the formatted version of the name which in this case will be: Mr. T. A. K. Rifat. I have included the code below. You will be able to see that I got close but still not exactly what i wanted. Please help.
#include<iostream>
#include<string>
using namespace std;
class myclass{
private:
string name,temp;
string p;
int i,j,sp;
public:
void work(){
cout << "Enter the name of the male student: ";
getline(cin,name);
cout << endl;
cout << "The original name is: ";
cout << name;
cout << endl << endl;
cout << "The formatted name is: " << "Mr." << name[0] << ".";
for(i=0;i<name.size();i++){
if(name[i]==' '){
sp=i;
for(j=sp+1;j<=sp+1;j++){
temp=name[j];
cout << temp << ".";
}
}
}
for(i=sp+2;i<name.size();i++){
cout << name[i];
}
cout << endl;
}
};
int main(){
myclass c;
c.work();
}
I guess the easiest way to solve this is to tokenize your string, print the first character from it, except from the last, where you print its full size.
To tokenize, you can do something like that:
std::vector<std::string> tokenize(std::istringstream &str)
{
std::vector<std::string> tokens;
while ( !str.eof() ) {
std::string tmp;
str >> tmp;
tokens.push_back(tmp);
}
return tokens;
}
Now you can easily transverse the tokens:
int main()
{
std::string name;
cout << "Enter the name of the male student: ";
getline(cin,name);
cout << endl;
cout << "The original name is: ";
cout << name;
cout << endl << endl;
std::istringstream str(name);
std::vector<std::string> tokens = tokenize(str);
for ( int i = 0 ; i < tokens.size() - 1; ++i)
std::cout << tokens[i][0] << ". ";
cout << tokens[tokens.size() - 1] << endl;
}
I hope this helps :)
It is probably a simpler version (originally I wrote this in C, you could easily convert it to C++ though, since the logic remains the same).
I have accepted the name and then inserted a space at the beginning of the string and one more space at the end, before the NULL character ('\0')
The program checks for a space.
When it encounters one, it checks for the next space that occurs in the string.
Now occurrence of this space helps us to identify an important determining factor as to what the next action should be.
See, if there is an null character after this subsequent space, then we can conclude that the subsequent space was the one we inserted at the end of the string.
That is, the space which occurs after the primary space, which came before the surname. Bingo!
You get the precise index of the array, from where the surname starts! :D
Looks long, but really is simple. Good luck!
#include<stdio.h>
#include<string.h>
void main()
{
char str[100]; /*you could also allocate dynamically as per your convenience*/
int i,j,k;
printf("Enter the full name: ");
gets(str);
int l=strlen(str);
for(i=l;i>=0;i--)
{
str[i+1]=str[i]; //shifting elements to make room for the space
}
str[0]=' '; //inserting space in the beginning
str[l+1]=' '; str[l+2]='\0'; //inserting space at the end
printf("The abbreviated form is:\n");
for(i=0;i<l+1;i++) //main loop for checking
{
if(str[i]==' ') //first space checker
{
for(j=i+1; str[j]!=' ';j++) //running loop till subsequent space
{
}
if(str[j+1]!='\0') //not the space after surname
{
printf("%c.",str[i+1]); //prints just the initial
}
else
for(k=i+1;str[k]!='\0';k++) //space after surname
{
printf("%c", str[k]); //prints the entire surname
}
}
}
}
Change your loop to the following:-
for(i=0;i<name.size();i++)
{
if(name[i]==' ')
{
initial = i + 1; //initial is of type int.
temp = name[initial]; //temp is char.
cout << temp << ".";
}
}
Try ravi's answer to make your code work, but I wanted to point out that there are more intuitive ways to program this which would make maintenance and collaboration easier in the future (always a good practice).
You can use an explode() implementation (or C's strtok()) to split the name string into pieces. Then just use the first character of each piece, disregarding the last name.
I think your question has already been answered. But in the future you could consider splitting up your program into more simple tasks, which makes things easier to read. Coupled with descriptive variable and function names, it can make a program easier to comprehend, and therefore to modify or fix later on.
Disclaimer - I am a beginner amateur programmer and this is just for ideas:
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
// I got this function from StackOverflow somewhere, splits a string into
// vector of desired type:
template<typename T>
std::vector<T> LineSplit(const std::string& line) {
std::istringstream is(line);
return std::vector<T>(std::istream_iterator<T>(is), std::istream_iterator<T>());
}
class Names {
private:
std::vector<std::string> full_name_;
void TakeInput() {
std::cout << "Enter the name of the male student: " << std::endl;
std::string input;
getline(std::cin,input);
full_name_ = LineSplit<std::string>(input);
}
void DisplayInitialsOfFirstNames() const {
std::cout << "Mr. ";
for (std::size_t i = 0; i < full_name_.size()-1; ++i) {
std::cout << full_name_[i][0] << ". ";
}
};
void DisplayLastName() const {
std::cout << full_name_.back() << std::endl;
}
public:
void work() {
TakeInput();
DisplayInitialsOfFirstNames();
DisplayLastName();
};
};
int main(){
Names n;
n.work();
}
When I run the following code and insert a new line (press enter) when prompted for
the golf structure, the second call to the function doesn't request input and finishes as if I've pressed enter again.
I've read up on : cin.get() , cin.clear() , cin.ignore(...) but nothing seems to help.
I'm pretty sure that it has nothing to do with multiple .cpp files and the header but I'm putting the code as is.
I'm using Visual Studio C++ 2010 - Express.
Thanks in advance for your help!
header file : golf.h
#ifndef GOLF_H
#define GOLF_H
const int Len = 40;
struct golf{
char fullname[Len];
int handicap;
};
int setgolf(golf & g );
void showgolf(const golf & g );
#endif
golf.cpp
#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>
using namespace std;
int setgolf(golf & g ){
cout << "Enter a name for the golf structure:" << endl;
if (cin.get(g.fullname,Len)) {
cin.get(); // deals with the '\n' incase the user inputs a valid string
return 1;
}
else{
return 0;
}
}
void showgolf(const golf & g ){
cout << "this golf structure contains the following information:" << endl;
cout << "name: " << g.fullname << endl ;
cout << "handicap: " << g.handicap << endl ;
}
main ()
#include "stdafx.h"
#include "golf.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
golf myGolf;
// check of int setgolf(golf & g );
int answ = setgolf(myGolf); //try to input empty string
showgolf(myGolf);
cout << "the number returned :" << answ << endl ;
answ = setgolf(myGolf); // normal string
showgolf(myGolf);
cout << "the number returned :" << answ << endl ;
return 0;
}
This problem happens when you just press enter in the first prompt. The input stream is marked as eof, an error condition flag (that's why it returns 0). The input stream then stops working.
It seems that you're using a kind of old C++, pre ISO 1998, while I don't think you need that. However, if you want to stick with your approach, then do the following: after cin.getline() (no need to return anything) write: cin.clear(); cin.sync();, as follows:
void setGolf(Golf &g)
{
cout << "Enter a name for the golf structure:" << endl;
getline( cin, g.fullname ) );
cin.clear();
cin.sync();
}
Now, about modernizing your code. First of all, you can use the standard library's class string, which is able to store a string literal, even growing if needed, without giving a maximum value of chars. This is somewhat confusing, since you are including the header string, which will include that class, but you're not using it. The use of string also comes with other advantages, such as automatically correcting the potential buffer overflow which could happen in your Golf structure. So I would change your structure to be:
struct Golf{
string fullname;
int handicap;
};
Now you can use getline(), in utility, which reads a whole line and stores it in string, doing all the magic for you. So you could change your golf.cpp file, to:
#include <utility>
//...
void setGolf(Golf &g)
{
cout << "Enter a name for the golf structure:" << endl;
getline( cin, g.fullname ) );
}
You can now also change the return type to void. It is not probable to experience an error of any kind while using getline(). Anyway, take into account that you could return bool (boolean type), which is a built-in type, with literals true and false.
I am certain that you could change your main() now, to a simpler style:
int main()
{
Golf myGolf;
setGolf(myGolf);
showGolf(myGolf);
setGolf(myGolf);
showGolf(myGolf);
return 0;
}
Finally, you could consider encapsulating your information in a class, instead of a struct, but that is a whole different issue.
Hope this helps.
You can also leave char[] instead of replacing it with string(I am still learning, so if I'm wrong please correct me). I think that when
std::cin.get(char *,Size) is not able to load characters, it's turning 2 bits on 0, fail and error, this is my solution:
std::cin.get(g.fullname, Len);
if(!std::cin)
{
std::cin.clear();
std::cin.get();
std::cout << "You inserted empty line." << std::endl;
return 0;
}
I'm new to C++, and right now I'm learning from the book called Accelerated C++. I finished the third chapter (vectors), and I came to this exercise:
"Write a program to count how many times each distinct word appears in its input."
After some thinking, I started working on it. I wanted to test the program, but std::cout wasn't working. I put cout << "test"; on a few places in my code to see where's the problem, and the conclusion is that it doesn't work inside the first for-loop. Don't recommend me to use maps to solve the problem, because I'm working on vectors. The variables aren't in English, so I'll translate some for you to know what's going on:
recenica - the sentence; rijec - a word; vel_vektora - size of the vector; duz_recenice - length of the sentence; br_ponavljanja - number of times a word appears in the sentence;
#include <vector>
#include <iostream>
#include <string>
using std::string; using std::vector;
using std::cin; using std::cout;
using std::endl;
int main()
{
string rijec;
vector<string> recenica;
while (cin >> rijec) recenica.push_back(rijec);
cout << endl;
typedef vector<string>::size_type vel_vektora;
vel_vektora duz_recenice = recenica.size();
cout << "test0, ";
for (int i = 0; i < duz_recenice - 1; ++i)
{
cout << "test, !";
int br_ponavljanja = 1;
for (int j = i + 1; j < duz_recenice; ++j)
{
cout << "test2, ";
if (recenica[i] == recenica[j])
{
cout << "test3, ";
++br_ponavljanja;
recenica.erase(recenica.begin() + j);
}
cout << "test4, ";
}
cout << recenica[i] << ": " << br_ponavljanja << endl;
}
cout << "test5, ";
getchar();
return 0;
}
What's the problem with the std::cout?
Add << flush to flush your output buffer (each place).
Or use << endl, which both adds newline and flushes.
There are problems with the code, especially for empty input, but that's what you're out to learn about, so I'll leave you to it! :-)
Cheers & hth.,
I'm afraid the language eludes me in terms of variable names, but this "Works for Me™".
Here is my output (First 3 lines input:)
ytreyert
tyryteter
gdhdfgdf
^Z
test0, test, !test2, test4, test2, test4, ytreyert: 1
test, !test2, test4, tyryteter: 1
test5,
You should definitely try flushing the cout buffers after printing (as per Alf's answer).
I notice that gdhdfgdf is not counted, this is because of this line:
for (int i = 0; i < duz_recenice - 1; ++i)
If you only give 1 input word, this loop will not run, as you do duz_recenice = recenica.size(); before looping.
Changing this line to
for (int i = 0; i < duz_recenice; ++i)
solves this problem.