C++: Finding average for each salesperson from a text file [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 months ago.
Improve this question
I need to calculate the average sales for each salesperson from a text file. My code will produce the correct output as the sample, but will not work if I add more information to the file without manually modifying the code.
I'm completely stuck on this, tried many different methods that I know but they doesn't completely satisfy the question. This is what I have so far.
Edit:
Is there a way to read the file, then add together all the amount that have the same name?
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
class Sales
{
public:
int id;
string name;
int salesCount = 1;
double salesAmount;
double avgSalesAmount;
};
void read()
{
int i = 0;
Sales sale[4];
fstream read;
read.open("Sales.txt");
while(!read.eof())
{
read.ignore();
getline(read, sale[i].name);
read >> sale[i].salesAmount;
if (sale[i].name == sale[i-1].name)
{
sale[i-1].salesAmount = sale[i-1].salesAmount + sale[i].salesAmount;
sale[i-1].salesCount++;
sale[i].salesCount = 0;
}
i++;
}
read.close();
for (int x = 0; x < 4; x++)
{
if (sale[x].salesCount != 0)
{
sale[x].avgSalesAmount = sale[x].salesAmount / sale[x].salesCount;
cout << sale[x].name << endl;
cout << sale[x].salesCount << endl;
cout << sale[x].avgSalesAmount << endl;
}
}
}
int main()
{
read();
return 0;
}
Sample file "Sales.txt":
Matthew
123.45
Matthew
432.15
Brown
89.95
Cook
500.00
Sample Output: https://i.stack.imgur.com/QS6jE.png
Current Output (No Formatting): https://i.stack.imgur.com/QTA7K.png

This is caused by the static person count in your code, please try to replace the 4 with a larger constant.
const int PERSON_COUNT = 100;
void read()
{
int i = 0;
Sales sale[PERSON_COUNT];
fstream read, read2;
read.open("Sales.txt");
while(!read.eof())
{
read.ignore();
getline(read, sale[i].name);
read >> sale[i].salesAmount;
if (sale[i].name == sale[i-1].name)
{
sale[i-1].salesAmount = sale[i-1].salesAmount + sale[i].salesAmount;
sale[i-1].salesCount++;
sale[i].salesCount = 0;
}
i++;
}
read.close();
for (int x = 0; x < PERSON_COUNT; x++)
{
if (sale[x].salesCount != 0)
{
sale[x].avgSalesAmount = sale[x].salesAmount / sale[x].salesCount;
cout << sale[x].name << endl;
cout << sale[x].salesCount << endl;
cout << sale[x].avgSalesAmount << endl;
}
}
}
Note that using the variable-length array (VLA) in your functions is not recommended practice in most cases since it's a non-standard extension that doesn't work in all implementations. Please consider using std::vector<int> or other dynamic array solutions.
EDIT:
As Ted Lyngmo suggests, the code above is almost never the correct solution if the input amount is unknown during your coding period. But I'd keep that because it will need little effort for you to fix it if your scenario is simple enough.
Below is my humble refactor for you as a clearer solution. Hope this can enlighten you to build a better program on it.
#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>
#include <vector>
using namespace std;
class Sales {
public:
int id;
string name;
int salesCount = 1;
double salesAmount;
double avgSalesAmount;
};
void read() {
vector<Sales> sale;
ifstream fin("Sales.txt");
int i = 0;
string name;
double salesAmount;
while (fin >> name) {
fin >> salesAmount;
if (sale.empty() || sale.back().name != name) {
sale.push_back(Sales{i++, name, 1, salesAmount, 0});
} else {
sale.back().salesCount++;
sale.back().salesAmount += salesAmount;
}
}
fin.close();
for (auto &s : sale) {
s.avgSalesAmount = s.salesAmount / s.salesCount;
cout << s.name << endl;
cout << s.salesCount << endl;
cout << fixed << setprecision(2) << s.avgSalesAmount << endl;
cout << "---" << endl;
}
}
int main() {
read();
return 0;
}
test case:
A
1.00
A
2.00
A
3.00
B
2.00
B
3.00
C
4.00
A
3
2.00
---
B
2
2.50
---
C
1
4.00
---
EDIT 2:
If your data doesn't guarantee that records of the same person will come up in a row, in the simplest solution, please refer to std::map and use std::map<std::string, Sale> records to retrieve the person's record.

Related

I'm trying to figure out in issue in a simple line of coding [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>
#include <string>
using namespace std;
int main()
{
string bob;
string alice;
string name;
for (int i = 0; i < 1; i++) {
cout << "Please enter the name bob or alice ";
cin >> name;
}
if (name == alice && name == bob) {
cout << " Greetings " << name;
}
else {
cout << "This name is invalid try again." << endl;
}
return 0;
}
Hello, I understand that this may be an unimportant or irrelevant topic, but I have a review test coming up in my computer science class. I'm trying to get a quick refresher in all that I've learned in last semester and I'm curious to why in this line of code when you type in bob or alice it should come out saying Greetings alice, or Greeting bob which ever you have inputted. Though right now it's completely skipping it and going to invalid try again. It's almost as if the information is being completely bypassed and then the code coming to a conclusion that nothing has been inputted.
Again I'm extremely sorry for the stupid question I'm just looking for a refresher.
Initialize your strings and change the && which is a Logical AND to a Logical OR ||
Also it would be better to void using namespace std;, more here .
Also there is no point in looping where you looped,because name will hold only the last input. Below the code I added maybe a case you wanted to catch,which loops some inputs and Greets Bob or Alice if found.
int main()
{
std::string bob = "Bob";
std::string alice = "Alice";
std::string name;
std::cout << "Please enter the name bob or alice ";
std::cin >> name;
if (name == alice || name == bob) {
std::cout << " Greetings " << name;
}
else {
std::cout << "This name is invalid try again." << endl;
}
return 0;
}
Perhaps what you wanted to do with your loop?
int main()
{
const std::string bob = "Bob"; //This will not change and DOESN'T need to change during runtime,so we make it const (same as alice below)
const std::string alice = "Alice";
std::string name; //This WILL change in fact in runtime,because we take input here right? So we don;t make it const
for(int i = 0 ; i < 1 ; ++i){
std::cout << "Please enter the name bob or alice " << std::endl;
std::cin >> name;
if (name == alice || name == bob) {
std::cout << " Greetings " << name << std::endl;
}
else {
std::cout << "This name is invalid try again." << std::endl;
}
}
return 0;
}
Reading suggestion as stated in comments : const

Convert lowercase to uppercase in a string [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
The new typist in the printing cell is typing carelessly the jobs assigned. The typist while was supposed to type all the characters in upper case, has got in lower cases too. Your duty is to verify if all the characters are in upper case and do so if not. Also, notify how many mistakes the typist did.
Input bEGIN
Output BEGIN 1
I am getting wrong answer in some of the cases please help i am beginner
n=length of string
1<=n<=50
int main() {
string s;
cin >> s;
int ans = 0;
for (auto &c : s) {
if (islower(c)) {
ans++;
c = toupper(c);
}
}
cout << s;
cout << endl;
cout << ans;
return 0;
}
I think it includes spaces too, so instead of using >> operator use getline(cin,string), as >> gets terminate when whitespace is occurred.
#include <iostream>
using namespace std;
int main() {
string s;
getline(cin,s);
int ans = 0;
for (auto &c : s) {
if (islower(c)) {
ans++;
c = toupper(c);
}
}
cout << s;
cout << endl;
cout << ans;
return 0;
}
This might be a solution to other test cases.
This should work:
#include<stdio.h>
#include<iostream>
#include<string>
using namespace std;
int main() {
string s;
getline(cin,s);
int ans = 0;
for (auto &c : s) {
if (islower(c)) {
ans++;
c = toupper(c);
}
}
cout << s;
cout << endl;
cout << ans;
return 0;
}

Why can't compare two strings in if condition? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Why can't compare two strings in if condition?
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string sexo[20], feminino;
feminino = "f";
for (int i = 0; i < 3; i++) {
do {
cout << endl << "enter your " << i + 1 << "sexo: ";
cin >> sexo[i];
if (strcmp(sexo[i], feminino)==0){ // problem in here
cout << "that's ok" << endl;
}
} while (nome[i] == "0");
}
return 0;
}
You've been reading "tutorials" for C, or "tutorials" for C++ that actually teach you a terrible and outdated mix of C and C++.
The function strcmp is from the C Standard Library, and does not operate on the C++ std::string type.
To compare two std::strings, simply write:
if (sexo[i] == feminino) {
I find it hard to believe that your C++ book does not teach you this.
These are a few correct ways to compare these strings (in reverse order of preference)
if (strcmp(sexo[i].c_str(), feminino.c_str()) == 0) {
if (sexo[i].compare(feminino)) == 0) {
if (sexo[i] == feminino) {
You are using the wrong compare function. What you are using works with char * (it is used in C) but here you have std::string so you have to use std::string::compare()
Change your code to this:
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string sexo[20], feminino; // problem in here
feminino = "f";
for (int i = 0; i < 3; i++) {
do {
cout << endl << "enter your " << i + 1 << "sexo: ";
cin >> sexo[i];
if (sexo[i].compare(feminito) == 0){
cout << "that's ok" << endl;
}
} while (nome[i] == "0");
}
return 0;
Note that you can also use sexo[i] == feminito as you have relational operators for std::string (see here for examples)

How to write functions and call them from main [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
struct studentType
{
string studentFName[20];
string studentLName[20];
string studentData[20][3];
int testscore[20][5];
char grade[20];
};
studentType s;
int main()
{
int index;
int maxindex;
int maxindex1;
int coldex;
int coldex1;
int totalscore[20];
double avscore[20];
double highscore;
double highindivscore;
maxindex = 0;
maxindex1 = 0;
coldex1 = 0;
ifstream infile;
infile.open("test.txt");
for(index = 0; index < 20; index++)
{
infile >> s.studentFName[index] >> s.studentLName[index] >> s.testscore[index][0] >> s.testscore[index][1] >> s.testscore[index][2] >> s.testscore[index][3] >> s.testscore[index][4];
totalscore[index] = ((s.testscore[index][0]) + (s.testscore[index][1]) + (s.testscore[index][2]) + (s.testscore[index][3]) + (s.testscore[index][4]));
avscore[index] = (static_cast<double>(totalscore[index])/5);
if(avscore[index]<= 100)
{
s.grade[index] = 'A';
}
if(avscore[index]<= 89.9)
{
s.grade[index] = 'B';
}
if(avscore[index]<= 79.9)
{
s.grade[index] = 'C';
}
if(avscore[index] <= 69.9)
{
s.grade[index] = 'D';
}
if(avscore[index] <= 59.9)
{
s.grade[index] = 'F';
}
}
for (index = 0; index < 20; index++)
{
cout << s.studentLName[index] << "," << " " << s.studentFName[index] << " " << s.testscore[index][0] << " " << s.testscore[index][1] << " " << s.testscore[index][2] << " " << s.testscore[index][3] << " " << s.testscore[index][4] << " " << s.grade[index] << endl;
}
cout << endl;
for (index = 1; index < 20; index++)
for (coldex = 0; coldex < 5; coldex++)
{
if (s.testscore[maxindex1][coldex1] < s.testscore[index][coldex])
{
maxindex1 = index;
coldex1 = coldex;
}
}
highindivscore = s.testscore[maxindex1][coldex1];
for (index = 1; index < 20; index++)
{
if (avscore[maxindex] < avscore[index])
{
maxindex = index;
}
}
highscore = avscore[maxindex];
cout << s.studentFName[maxindex] << " " << s.studentLName[maxindex] << " Achieved The Highest Average Test Score Of A: " <<highscore <<endl;
cout << s.studentFName[maxindex1] << " " << s.studentLName[maxindex1] << " " << s.testscore[maxindex1][coldex1] << endl;
infile.close();
system("pause");
return 0;
}
here is the homework question, i know i did it wrong which is why i need help. How do i make main function calls. I am new to this. I have this lab that's got me stumped. The assignment reads (emphasis mine):
Write programs for the following and test to make sure they work. Please follow the book’s guidelines or my style guidelines to write code. Write a program that reads students’ names followed by their test scores from the given input file. The program should output to a file, output.txt, each student’s name followed by the test scores and the relevant grade.. Student data should be stored in a struct variable of type StudentType, which has four components: studentFName and studentLName of type string, testScore of type int and grade of type char. Suppose that the class has 20 students. Use an array of 20 components of type StudentType. Your program must contain at least the following functions:
A function to read the students’ data into an array.
A function to assign the relevant grade to each student.
Your program should output each student’s name in this form: last name followed by a comma, followed by a space, followed by the first name; the name must be left justified. Moreover, other than declaring the variables and opening the input and output files, the function main should only be a collection of function calls.
This is called refactoring. I guess for the assignment you want to move everything that is in main into individual functions. You could just cut and paste the whole body of main and move it to one function and call it in main. I don't really think that is the point of the assignment though.
Instead, read over main and separate/extract procedures. You should separate main into functions that do one thing i.e. handle input/output, loop, check some variable and return a letter, etc. These kind of changes not only make the program much easier to understand and come back to later, but also make it much easier to reuse procedures that are repeated throughout the program.
Your code looks fine logically and should work, however, what your homework is asking of you is to essentially code with good style and separate the sections of the program into functions.
Essentially, as an easy fix, just place different sections that do similar things from the code into void functions. For example, this cpp segment:
void function1();
void function2();
void function3();
void main(){
function1();
function2();
function3();
return 0;
}
void function1(){
// Your code. Ex: Some large algorithm.
}
void function2(){
//More code, for a different algorithm. Maybe some input or output.
}
void function3(){
//The final code you want the program to execute.
}
And then pass parameters and adjust return types as needed. It makes the code easier to follow, especially if you have the functions named after what they do such as gradingLogic() or studentOutput().

I am getting C++ syntax error [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
This script is supposed to read chars from keyboard, store them into arrays, and then output them:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
void storeArraysintoStruct(char[], int);
int main()
{
char test[] ="";
int a = 0;
storeArraysintoStruct(test, a);
system("pause");
return 0;
}
void storeArraysintoStruct(char test[], int a)
{
int n;
cout << "Enter number of entries: " << endl;
cin >> n;
int i = 0;
for (i=0, i<n, i++)
{
cout << "Enter your character: " << endl;
cin.getline(test, n);
}
while (i < n)
{
cout << test[i] << endl;
i++;
}
}
Edit: fixed it:
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
void storeArraysintoStruct(char[], int);
int main()
{
char test[40] = "";
int a = 0;
storeArraysintoStruct(test, a);
system("pause");
return 0;
}
void storeArraysintoStruct(char test[], int a)
{
int n;
cout << "Enter number of entries: " << endl;
cin >> n;
int i;
for (i=0; i < n; i++)
{
cout << "Enter your character: " << endl;
cin >> test[i];
if (test[n-1])
{
cout << endl;
}
}
i =0;
while (i < n)
{
cout << test[i] << endl;
i++;
if(test[n-1])
{
cout << endl;
}
}
}
However, I am getting the errors Expected: primary expression before ")" and ";" before while. Any help will be greatly appreciated.
Edit: The script doesn't work as expected, for it doesn't output the stored characters. Any advice would be greatly appreciated.
The syntax error has already been pointed out in the comments. Also, as it has been mentioned, you never reset i after for loop, which prevents your while loop from running.
However, you have to also take in mind that this
char test[] = "";
allocates array test of only 1 character long. You cannot put more than one character of data into that array. In other words, your storeArraysintoStruct is sure to overrun the array and fall into undefined behavior territory.
In you want to preallocate a larger buffer for future use in storeArraysintoStruct, you have to specify the size explicitly. For example
char test[1000] = "";
will make test an array of 1000 characters. Of course, regardless of how large the array is, it is your responsibility to observe the size limit.
P.S. What is the point of that parameter a, if you never use it inside storeArraysintoStruct?