I am trying to print out whatever is necessary from my program. What it does is it takes a long list from a text file and sort it based on first choice and GPA and put it into a vector. I manage to sort by First choice and GPA however how can I remove whatever output that isn't necessary?
This is an example of my Txt File (The sequence of each line is 1st choice, 2nd choice, 3rd choice, GPA, Name):
CC,DR,TP,3.8,AlexKong
SN,SM,TP,4,MarcusTan
DR,TP,SC,3.6,AstaGoodwin
SC,TP,DR,2.8,MalcumYeo
SN,SM,TP,3.7,DavidLim
SN,SM,TP,3.2,SebastianHo
SC,TP,DR,4,PranjitSingh
DR,TP,SC,3.7,JacobMa
and so on...
This is my output now (it is a long vector):
TP,DR,SC,4,SitiZakariah
TP,DR,SC,3.9,MuttuSami
TP,DR,SC,3.5,SabrinaEster
TP,DR,SC,3,KarimIlham
TP,DR,SC,3,AndryHritik
SN,SM,TP,4,MarcusTan
SN,SM,TP,3.8,MarcusOng
SN,SM,TP,3.7,DavidLim
SN,SM,TP,3.4,MollyLau
SN,SM,TP,3.2,SebastianHo
SN,SM,TP,3.2,NurAfiqah
SN,SM,TP,2.4,TanXiWei
SC,TP,DR,4,SallyYeo
SC,TP,DR,4,PranjitSingh
SC,TP,DR,3.6,RanjitSing
SC,TP,DR,2.8,MalcumYeo
SC,TP,DR,2.8,AbdulHalim
SC,TP,DR,2.7,AlifAziz
DR,TP,SC,3.9,SitiAliyah
DR,TP,SC,3.9,LindaChan
DR,TP,SC,3.8,SohLeeHoon
DR,TP,SC,3.7,PrithikaSari
DR,TP,SC,3.7,NurAzizah
DR,TP,SC,3.7,JacobMa
DR,TP,SC,3.6,AstaGoodwin
CC,DR,TP,3.9,MuruArun
CC,DR,TP,3.8,AlexKong
CC,DR,TP,3.7,DamianKoh
CC,DR,TP,3.3,MattWiliiams
CC,DR,TP,3.3,IrfanMuhaimin
And this is the output that I need (Basically students with CC as their 1st choice without displaying the 3 options):
3.9,MuruArun
3.8,AlexKong
3.7,DamianKoh
3.3,MattWiliiams
3.3,IrfanMuhaimin
This is my program.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
struct greater
{
template<class T>
bool operator()(T const &a, T const &b) const { return a > b; }
};
void main()
{
vector<string> v;
int p = 0;
ifstream File;
File.open("DSA.txt");
if (!File.is_open()) return;
string First;
cout << "Round 1:\n";
while (File >> First)
{
v.push_back(First);
p++;
}
for (int i = 0; i < v.size(); i++)
{
sort(v.begin(), v.end(), greater());
cout << v[i] << endl;
}
}
your last for loop:
for (int i = 0; i < v.size(); i++)
{
sort(v.begin(), v.end(), greater());
cout << v[i].substr(9) << endl;
}
EDIT:
If you want to only display ones with CC as 1st choice you can add if statement to your loop:
for (int i = 0; i < v.size(); i++)
{
if (v[i].substr(0,2) != "CC") continue;
cout << v[i].substr(9) << endl;
}
Also, I noticed another problem in your code. You should not sort the vector at every iteration. You should do it only once before the loop:
sort(v.begin(), v.end(), greater());
for (int i = 0; i < v.size(); i++)
{
if (v[i].substr(0,2) != "CC") continue;
cout << v[i].substr(9) << endl;
}
as I propose in the comment,
since the data is well defined as a structure, you can interpret semantically each row and filter according to that: here is what am talking about
int main()
{
std::vector<std::string> v;
std::string r = "CC,DR,TP,3.9,MuruArun";
std::string delimiter = ",";
std::string token = r.substr(0, r.find(delimiter));
if(token == ??)// compare to what ever you want
{
v.emplace_back(r);
}
cout << "token: " << token << endl;
cout << v.size() << endl;
return 0;
}
I need to take 200 randomizes numbers from a file, separate them into even and odd, and make them show up from lowest to highest in their even or odd parts.
I got the code for making it into even and odd from here but the original way had 10 instead of 200 and made the user input the numbers.
I reworked it into this but I get a repeat of the same number then an error that reads Exception thrown: write access violation with a mark near the odd[oddcnt++] = arr[i];
My code so far
#include <iostream>
#include <fstream>
using namespace std;
class Random
{
private:
int x, arr[200], even[200], odd[200], evncnt = 0, oddcnt = 0, i;
public:
void readFile();
};
void Random::readFile()
{
fstream File("Random.txt");
if (File.is_open())
{
while(File >> x)
{
for (i = 0; i < 200; i++)
{
arr[i] = x;
}
for (i = 0; i < 200; i++)
{
if (arr[i] % 2 == 0)
{
even[evncnt++] = arr[i];
}
else
{
odd[oddcnt++] = arr[i];
}
}
cout << "\n The even numbers are: ";
for (i = 0; i < evncnt; i++)
{
cout << even[i] << "";
}
cout << "\n The odd numbers are: ";
for (i = 0; i < oddcnt; i++)
{
cout << odd[i] << "";
}
}
File.close();
}
}
int main()
{
Random file;
file.readFile();
system("pause");
return 0;
}
Your loops are all wrong. This is how it should look
i = 0;
while (file >> x)
{
arr[i] = x;
i++;
}
for (i = 0; i < 200; i++)
{
if (arr[i]%2==0)
...
}
If you put one loop inside another (like you did) then the inner loop executes fully every time the outer loop executes once. That's not what you want (in this case).
The answer is given already by John. So everything OK.
Additionally, I would like to show you the power of modern C++. Especially with using algorithms. You can write very elegant solutions.
Thers is no loop and only vey few variables.
You will of course not copy and paste it, because you will not understand it fully. But it should give you an idea how such a problem could be analysed, then designed, and then coded.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
class Random {
std::vector<int> values{};
public:
void readFile(const std::string& fileName);
void printOdds();
void printEvens();
};
void Random::readFile(const std::string& fileName) {
// Open file and check, if it could be opened
if (std::ifstream inputFileStream(fileName); inputFileStream) {
// Clear old content in our class
values.clear();
// Copy the contents from the vile into our vector
std::copy(std::istream_iterator<int>(inputFileStream), {}, std::back_inserter(values));
// sort the values
std::sort(values.begin(), values.end());
}
else { // File could not be opened
std::cerr << "\n*** Error: File could not be opened: " << fileName << "\n\n";
}
}
// Copy all odd values to std::cout
void Random::printOdds() {
std::copy_if(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "), [](const int i) { return (i % 2) != 0; });
std::cout << "\n\n";
}
// Copy all even values to std::cout
void Random::printEvens() {
std::copy_if(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "), [](const int i) { return (i % 2) == 0; });
std::cout << "\n\n";
}
// Driver code
int main() {
Random r;
r.readFile("r:\\random.txt");
r.printEvens();
r.printOdds();
return 0;
}
I am currently working on a project that displays a table after reading the contents and dimensions of the table from a text file.
The contents of puzzle.txt:
5 5
ferac
asdvb
mfkgt
opemd
welsr
I want my program to read the left number and store it in the variable numRow, and the right number in numCol, then read the letters into the puzzle array. However, when the dimension numbers print, they print as 0 0 instead of 5 5, and the puzzle array only outputs empty box characters.
#include <iostream>
#include <map>
#include <fstream>
#include <cstring>
#include <string>
using namespace std;
char puzzle [numRow][numCol];
void initializePuzzle() {
string storeInput;
int numRow, numCol;
cout << "What is the name of the file?" << endl;
getline(cin, storeInput);
ifstream inFile (storeInput);
inFile.open(storeInput.c_str());
for (int c = 0; c < sizeof(storeInput); c++) {
if (c == 0) {
inFile >> numRow >> numCol;
cout << numRow << ' ' << numCol << endl;
}
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
inFile >> puzzle[i][j];
}
}
}
void displayPuzzle() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
cout << puzzle[i][j];
}
cout << endl;
}
}
int main() {
initializePuzzle();
displayPuzzle();
return 0;
}
You can do this just by using the C++ Standard Library. Try this: (See about std::copy(), std::array and std::vector...)
#include <iostream> // For std::cout, std::endl, etc.
#include <fstream> // For std::ifstream
#include <vector> // For std::vector
#include <iterator> // For std::ostream_iterator
int main() {
std::string file_src;
// Ask for file name...
std::cout << "What is the name of the file? " << std::endl;
std::getline(std::cin, file_src);
// Declare the file stream...
std::fstream reader(file_src);
// Terminate the program with value '1' in case of failure when reading file...
if (reader.fail()) return 1;
// Declaring necessary varibles...
unsigned num_row, num_column;
std::string temporary;
/* Extracting 'num_row' and 'num_column' and declaring a 'std::vector' (which are
better than dynamic arrays in numerous ways) with the dimensions... */
reader >> num_row >> num_column;
std::vector<std::vector<char>> puzzle(num_row, std::vector<char>(num_column));
// Iterating over each line and copying the string where required...
for (auto i = 0; std::getline(reader, temporary, '\n') && i < num_row; i++)
if (!temporary.empty())
std::copy(temporary.begin(), temporary.end(), puzzle[i].begin());
else --i;
// Close the stream...
reader.close();
// Print the resulting vector...
for (auto & elem : puzzle) {
std::copy(elem.begin(), elem.end(), std::ostream_iterator<char>(std::cout, " "));
std::cout << std::endl;
}
return 0;
}
Example:
Input:
puzzle.txt
Output:
f e r a c
a s d v b
m f k g t
o p e m d
w e l s r
I need help for my university homework. i'm still new to this.
Basically i am doing a run-length encoding and i don't know how to add the letter after the counter:
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
void error(std::string str)
{
throw std::runtime_error(str);
}
int main()
{ int counter = 1;
std::string id;
std::vector<int> v;
std::cout << "Enter the data to be compressed: ";
std::cin >> id;
try
{ for(int i = 0; i < id.size(); i++)
{
if(std::isdigit(id[i]))
error("invalid input");
}
std::cout << "The compressed data is: ";
for(int i = 0; i < id.size(); i++)
{
if(id[i] == id[i+1])
{
counter++;
}
else if(id[i]!= id[i+1])
{
v.push_back(counter);
v.push_back(id[i]);
counter=1;
}
}
for(int j = 0; j < v.size(); j++)
std::cout << v[j];
}
catch(std::runtime_error& str)
{
std::cerr << "error: " << str.what() << std::endl;
return 1;
}
return 0;
}
For example if i input aaabbb, the probram should output 3a3b. The problem is that it outputs 397398 97 and 98 being the ascii code for a and b.
i don't know how to put the letter after the counter and for them to be in the same vector.
If you want to serialize as a string try this :
#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <sstream>
void error(std::string str) {
throw std::runtime_error(str);
}
int main() {
std::ostringstream stream;
int counter = 1;
std::string id;
std::cout << "Enter the data to be compressed: ";
std::cin >> id;
try {
for (int i = 0; i < id.size(); i++) {
if (std::isdigit(id[i]))
error("invalid input");
}
std::cout << "The compressed data is: ";
for (int i = 0; i < id.size(); i++) {
if (id[i] == id[i + 1]) {
counter++;
} else if (id[i] != id[i + 1]) {
stream << counter;
stream << (char) id[i];
counter = 1;
}
}
std::cout << stream.str() << std::endl;
} catch (std::runtime_error& str) {
std::cerr << "error: " << str.what() << std::endl;
return 1;
}
}
v[j] from std::cout << v[j] is of type int and that is why std::cout writes a number. To write it as a character, you should cast v[j] to char as follows: std::cout << (char)v[j]. In this way, std::cout will use the char specialization, not the int one.
While the other answers might give you the output you need, I believe the idiomatic way to solve this is using a class to hold both the character and its count. There are two obvious choices.
std::pair
Could also be std::tuple if you prefer it for consistency or whatever reason. Save your results in a std::vector<std::pair<char, int>. This saves the information, but to print it you would need to define an appropriate function. Add elements via
v.emplace_back(character, count);
Wrapper Class
If you want to offer some functionality without outside helper classes, define a custom wrapper class such as the following.
class CharacterCount {
private:
char character;
int count;
public:
CharacterCount(char character, int count):
character(character), count(count) {}
explicit operator std::string() const { return std::to_string(count) + character;
// Other helper functions or constructors you require
}
This simplifies printing
for (auto& character_count : v)
std::cout << static_cast<std::string>(character_count);
I believe because std::ostream::operator<< is templated, you cannot get an implicit conversion to std::string to work. I would advise against implicit conversion anyway.
You can use the same emplace_back syntax as before because we offer an appropriate constructor.
So you take your input in a string and ultimately just need to stream this information out, ultimately meaning there's really no reason to store the information in a vector, just output it! You can use find_if with a lambda to find the non-consecutive character (or find_if_not if you prefer.)
for(string::const_iterator finish, start = cbegin(id); start != cend(id); start = finish) {
finish = find_if(start, cend(id), [value = *start](const auto i) { return i != value; } );
cout << distance(start, finish) << *start;
}
Live Example