My program stopped working because a p roblem has been detected? - c++

I tried looking at the other problems people were having that were along this line but i couldn't relate them to my program. This is probably very simple but I rarely if ever do anything C++ related so I am very confused. I try and run my program which and it works up until the point were I try to use "std::cout" to display the reversed name. The program runs for a bit in the command window but eventually a window's window pops up proclaiming there was a problem and that it will end the program. I have tried to break everything down so that it is simple as it can be yet I cannot for the life of me find what's wrong. Could anyone help? I apologize for anything I have done wrong in advance and apologies for bypassing the 'problem' title filter. Cheers!
#include <iostream>
#include <string.h>
std::string firstName;
std::string lastName;
std::string fullname;
std::string reverseName;
int x;
int Simplifier;
int willThisWork;
int main()
{
std::cout << "Welcome to this random program that serves \n";
std::cout << " NO PURPOSE! \n";
std::cout << "That being said, what is your first name? : ";
std::cin >> firstName;
std::cin.ignore();
std::cout << "Okay... Now what is your last name? : ";
std::cin >> lastName;
std::cin.ignore();
fullname = firstName + " " + lastName;
std::cout << "Your full name is : " << fullname;
nameLength = fullname.length();
for(x = 0; x <= nameLength; x++)
{
Simplifier = nameLength - x;
reverseName[x] = fullname[Simplifier];
}
std::cout << "Reversed name : " << reverseName;
return 0;
}

You have to include <string> (the C++ header) instead of <string.h> (the C header).
nameLength is undeclared – has to be int nameLength.
Lastly,
Simplifier = nameLength - x;
reverseName[x] = fullname[Simplifier];
tries for x==0 to access the one past the last element of fullname. Remember, indices go from 0 to N-1, where N is the number of elements in the array/vector/string.
Edit: And you have to adjust the for loop: x < nameLength instead of x <= nameLength.
reverseName is an empty string, but you try to access its elements with reverseName[x]. Use reverseName.push_back() or reverseName += instead.
Maybe add the odd \n to format your output.

Related

Transversing an Array of structs error in C++

Current code:
const int MAX_CODENAME = 25;
const int MAX_SPOTS = 5;
struct Team {
string TeamName[MAX_CODENAME];
short int totalLeagueGames;
short int leagueWins;
short int leagueLoses;
};
//GLOBAL VARIABLES:
Team league[MAX_SPOTS];
void addTeams(){
int i = 0; //first loop
int j; //second loop
while(i < MAX_SPOTS){
cout << "****** ADD TEAMS ******" << endl;
cout << "Enter the teams name " << endl;
scanf("%s", league[i].TeamName) ;
}
void searchTeam(){
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
for(int i = 0; i < MAX_SPOTS; i++){
if(decider == league[i].TeamName){
cout << endl;
cout << league[i].TeamName << endl;
break;
}else{
cout << "Searching...." << endl;
}
}
}
I really dont know why its not working but I have included all the perquisite header files such as and but the program crashes when i enter the data and then attempt to search. I get the circle of death and then program not responding then says Process returned 255 (0xFF) . It does not even out put Searching.... the program practically gives up as soon as I enter that name.
Also if this can be optimized by the use of pointers that would be great.
tl;dr run-time error causing the search to fail as soon as i type in a name. And for the record I have checked to make sure the name I entered is valid.
scanf doesn't know about std::string. Use std::cin >> league[i].TeamName.
scanf("%s", league[i].TeamName) ;
This should be changed to
std::cin >> league[i].TeamName ;
A couple of other things here....
string decider[MAX_CODENAME];
cout << "Please enter the team name you would like the program to retrieve: " << endl;
cin >> decider[MAX_CODENAME];
Every time you input a value, you are telling the computer to hold the inputted value at decider[25] but the computer only reads indexes 0-24.
if(decider == league[i].TeamName){
Which array slot are you comparing the team name to? If its the 25th element than the statement should be
if(decider[24] == league[i].TeamName){
Pointers are better suited if the number of TeamNames are unknown. Based on the limited code presented, I highly recommend you stay within the realm of basic data types. For the purposes of troubleshooting, please post your full code in the future.
Your TeamName member variable:
string TeamName[MAX_CODENAME];
is an array of 25 strings, so in this line:
scanf("%s", league[i].TeamName) ;
you are courrupting the array. You don't really want an array anyways, so change the TeamName declaration to:
string TeamName;
and then when you read the name, you'll need to use iostreams which knows how to populate a string type (scanf only works with c char arrays):
std::cin >> league[i].TeamName

How do i take the initials of all the parts of one's name except the last name?

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();
}

How to make simple one function read my previous answer and give different output? (c++)

So, im a very beginner in programming and i was making a simple code snippet to read user input and output persons First, Middle and Lastname.
I made 3 different functions for those inputs and outputs, but i was thinking, is it possible to make 1 function to do all this (in simple code language, im still a very beginner)?
Does it have something to do with Arrays and pointers?
My code snippet would be something like:
std::string getUserInput()
{
std::cout << "Please write your first name: " ;
std::string x;
std::cin >> x;
return x;
}
So, i would like it to read my previous answer and give me a different std::cout output i.e "Please write your middle name".
Thank you for your kind answers!
If I understand your question correctly, You'll want to use function arguments:
std::string getUserInput(std::string what)
{
std::cout << "Please write your " << what << ": " ;
std::string x;
std::cin >> x;
return x;
}
int main() {
std::string first_name = getUserInput("first name");
std::string middle_name = getUserInput("middle name");
...
}
Note: As was pointed out in the comments, it would be a good idea to pass what as a const reference.
In the above example, the whole string is unneccesarily copied when the function is called. You can avoid that by instead writing the function header as
std::string getUserInput(const std::string &what)
When you write it like that, getUserInput will work on the same string object instead of copying it. It is a property of C++ that you should always have in mind when writing fast code. I left it out here to keep things as simple as possible.
By specifying const, you prevent getUserInput from modifying the string. In this case, the string cannot be modified because you call the function with constant string literals as arguments (e.g. "first name"). These must never be modified in C or C++, or horrible things will happen (namely, your application will probably crash). Your C++ compiler will thus prevent you from compiling your code when what is a non-const reference.
For such a simple thing, do you need a separate function each?
std::cout << "Please write your first name: " ;
std::string first;
std::cin >> first;
std::cout << "Please write your middle name: " ;
std::string middle;
std::cin >> middle;
std::cout << "Please write your last name: " ;
std::string last;
std::cin >> last;
You could put the name parts into a concatenated string, or a struct, depending how you use it later.
You can take all the three in one input from user too.
cout << "Please write your firstname secondname lastname (with spaces): " << endl;
std::string fName,mName,lName;
cin >> fName >> mName >> lName;
cout << "First name : " << fName << " Second name: " << mName << "Last name " << lName << endl;
You could loop through the values using map<>
#include <map>
#include <string>
std::map<int, std::string> values;
std::vector<std::string> names;
values[0] = "first";
...
for (int i = 0; i < values.size(); i++)
{
std::cout << "Please write your " << values[i] << " name" << endl;
std::string name;
std::cin >> name;
names.push_back(name);
}

Unhandled Memory Exception

I'm working on a program that reads a set of data based on patient's ID numbers and their blood pressure readings. The program will then add all the readings together and come up with an average. It'll then display that average. This is my program so far:
#include <iostream>
#include <string>
#include <conio.h>
#include <fstream>
using namespace std;
int main()
{
//Initialize Required Variables For Program
int patientCount;
string id;
string rHowMany; //String To Read From File
int howMany;
int howManyCount;
int avg = 0;
int avg2;
string line;
int number_lines = 0;
ifstream reader ("data.txt"); //Open The Data File To Be Read From
patientCount = 0;
while (getline(reader, line))
{
number_lines += 1;
}
//getline(reader, id); //Get the patients ID
//getline(reader, rHowMany); //Get How Many BP Records The Patient Has
for (number_lines; number_lines > 0; number_lines--)
{
reader >> id;
reader >> rHowMany;
howMany = stoi(rHowMany);
howManyCount = howMany;
patientCount += 1;
cout << "Patient ID: " + id;
for (howManyCount; howManyCount > 0; howManyCount--)
{
reader >> avg2;
avg = avg + avg2;
}
}
cout << avg;
cout << "\n";
cout << howMany;
avg = avg / howMany;
cout << "\n";
cout << avg;
_getch();
return 0;
}
When I run the program I get this error:
Unhandled exception at at 0x756DB727 in Blood Pressure.exe: Microsoft C++ exception: std::invalid_argument at memory location 0x0042F794.
I'm not quite sure what that means, but it opens up a list of code I've never seen before. Like I said I'm not sure why it's throwing this error, or what the error means, but if someone could help me, I would appreciate it.
This line:
cout << "Patient ID: " + id;
Is flawed. You are trying to append id to "Patient ID: ", but that is not what is happening.
The string literal "Patient ID: " is actually a pointer to a sequence of characters (that is, an array). When you use the plus sign, you are performing pointer arithmetic between the memory address of the character sequence and id. If id is larger than the length of the string, this will probably lead to your program trying to access an invalid location.
To fix this, simply print id after the sequence by making two separate calls to the << operator:
cout << "Patient ID: " << id; // no +

(cin >> int).get() doesn't properly work in Xcode(4.3.3)

I'm currently working on the book "C++ Primer Plus" and doing some of the programming excersis.
As it seems, I'm having a problem with Xcode(4.3.3) because following code doesn't work how it's supposed to work:
#include <iostream>
#include <string>
struct car
{
std::string maker;
int year;
};
int main()
{
using namespace std;
cout << "How many cars do you wish to catalog? ";
int nCars;
(cin >> nCars).get();
car* aCars = new car[nCars];
for (int i = 0; i < nCars; i++)
{
cout << "\nCar #" << (i + 1) << endl;
cout << "Please enter the make: ";
getline (cin, (aCars + i)->maker);
cout << "\nPlease enter the year made: ";
(cin >> (aCars + i)->year).get();
}
cout << "Here is your collection: \n";
for (int i = 0; i < nCars; i++)
{
cout << (aCars + i)->year << " " << (aCars + i)->maker << endl;
}
delete [] aCars;
return 0;
}
The problem is, I don't have the chance to enter any maker. The program directly goes to the point where I have to enter the year, even though I'm using "(cin >> nCars).get();" to get rid of the newline character.
Am I overlooking something?
Thanks in advance!
I suspect that you may be running on windows and the two-byte newlines are hitting you. You may be able to improve things (for lines that aren't ridiculously long) with ignore:
cin >> nCars;
cin.ignore(1024, '\n');
Note that since you rely on stream numeric processing, entering a non-numeric year such as QQ will result in the programming just finishing without asking for any more input.
You don't need to do math on the years so treat them as strings instead of integers. Then if you need to you can do validation of each year after you get the input.
Ok, guys..I found the problem.
The console within Xcode doesn't work as expected when using cin.get().
I tried the same code in the terminal as well as with Visual Studio (Win 7) and the program works perfectly.
Anyway, thank you all for your advices. I'll try consider them the next time. :)
Cheers!