C++ - Gettings size from vector in FOR loop - c++

I have a loop that asks for user input, and adds it too a vector, then when if they type "EXIT" it will stop and display the list. What I am trying to do now is determine the number of elements with size()
This is what I have:
#include <iostream>
#include <string>
#include <unistd.h>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
write(1,"\E[H\E[2J",7);
vector<string> list;
cout << "Enter UIDs: \n\n";
for(string uid ; cin >> uid && uid != "EXIT"; list.push_back(uid))
cout << " \n";
copy(list.begin(), list.end(), ostream_iterator<string>(cout, "\n\n"));
cout << "Vector size: " << uid.size() << endl;
return 0;
}
When attempting to compile that I get the error:
g++ sof.cpp -o sof
sof.cpp: In function ‘int main()’:
sof.cpp:16:32: error: name lookup of ‘uid’ changed for ISO ‘for’ scoping
sof.cpp:13:16: error: cannot use obsolete binding at ‘uid’ because it has a destructor

You're querying uid.size() instead of list.size()

Related

Sorting a textfile that contains player name and score in descending order

I am trying to open a text file and then rearrange it in descending order, to show who has the highest score. In the text file there's the player name and their score.
I've managed to print out the textfile in c++, but I cannot find a way to sort it since the variables are in the text file.
#include <string>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
using namespace std;
struct player {
string name;
int score;
int position;
};
int main()
{
string line;
ifstream inFile;
inFile.open("C:/Users/kkpet/Desktop/highscore.txt");
if (inFile.is_open()) {
while (getline(inFile, line)) {
player x;
ifstream inFile;
inFile.open("C:/Users/kkpet/Desktop/highscore.txt");
cout << line << '\n';
}
inFile.close();
}
else
cout << "Unable to open text";
}
Assuming your text file looks like this:
Name1 1
Name2 1
Name4 5
Name3 6
you could do something like this:
#include <string>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
#include <vector>
int main()
{
std::string line;
std::ifstream inFile;
inFile.open("/C:/Users/kkpet/Desktop/highscore.txt");
if (inFile.is_open()) {
std::vector<std::pair<int, std::string> > score_vector;
std::string name;
int score;
while (inFile >> name >> score) {
score_vector.push_back(std::make_pair(score, name));
std::cout << line << '\n';
}
inFile.close();
std::sort(score_vector.begin(), score_vector.end());
std::reverse(score_vector.begin(), score_vector.end());
for(auto it = score_vector.begin(); it != score_vector.end(); ++it){
std::cout << "Name: " << it->second << " Score: " << it->first << std::endl;
}
}
else
std::cout << "Unable to open text";
}
You first read the file line by line using inFile << name << score directly gives you the name and score of the player. You then create a pair out of them with score as first, which just makes it easier to sort, you could also sort by the second element of a pair using your own compare function, but for simplicity I put it this way around. Then you can easily sort the vector with the std::sort method. Afterwards it needs to be reverted.
Full code with custom compare function:
#include <string.h>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
#include <vector>
// This is a compare funciton for the sort algorithm of std::sort. See [1]
bool compareScorePair(std::pair<std::string, int>&a, std::pair<std::string, int>&b){
if(a.second > b.second){return true;}
if(a.second == b.second){return a.first.compare(b.first) > 0;}
return false;
}
int main()
{
std::ifstream inFile;
inFile.open("C:/Users/kkpet/Desktop/highscore.txt");
if (inFile.is_open()) {
std::vector<std::pair<std::string, int> > score_vector;
std::string name;
int score;
while (inFile >> name >> score) { // Can be used to directly assign istream data to variables. See [2]
score_vector.push_back(std::make_pair(name, score)); // Storing data as pair, to keep relationships between score and name.
}
inFile.close();
std::sort(score_vector.begin(), score_vector.end(), compareScorePair); // Sort the vector with the custom compare function, See top of code.
int place = 1;
//auto is used purely for convenience. auto represents std::vector<std::pair<std::string, int> >::iterator here.
for(auto it = score_vector.begin(); it != score_vector.end(); ++it){
std::cout << "Place: " << place << " Name: " << it->first << " Score: " << it->second << std::endl;
++place;
}
// The whole for loop could look like this:
/*
for(uint i = 0; i < score_vector.size(); ++i){
std::string name_out = score_vector[i].first;
int score_out = score_vector[i].second;
std::cout << "Place: " << i << " Name: " << name_out << " Score: " << score_out << std::endl;
}
*/
}
else
std::cout << "Unable to open text";
}
Output:
Place: 1 Name: Name3 Score: 6
Place: 2 Name: Name4 Score: 5
Place: 3 Name: Name2 Score: 1
Place: 4 Name: Name1 Score: 1
Links:
[1]: https://en.cppreference.com/w/cpp/named_req/Compare
[2]: http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
Information on pair:
https://en.cppreference.com/w/cpp/utility/pair
Information on iterators (see auto keyword):
https://www.geeksforgeeks.org/iterators-c-stl/
No need to use C++ for this problem! Just enter this in the shell prompt.
sort -rk 2 highscore.txt > sorted_scores.txt
Explanation:
'sort' sorts a file, typically by the first letter.
The -k 2 option means to sort by the second column.
The -r option means to reverse (so highest score is on top).

the vector constructor doesn't change the end_file istream_iterator

i'm studying C++ for C programmers course (coursera) and in module 4 there is an example for how to use istream iterators to load data to STL vector ..but when i tried the code it only printed the first number from the file. i can't find the mistake in the code.
note :the instructor didn't run the code, he Taught is using PDF. so maybe there something missing in it.
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
fstream data_file("data.txt");
istream_iterator<int> start_file(data_file), end_file;
vector<int> data(start_file, end_file);
int sum = 0;
for (auto i = start_file; i != end_file; i++)
{
sum += *i;
cout << *i << endl;
}
cout << data.size()<<endl;
cout << sum << endl;
cout << (sum* 1.0) / data.size() << endl;
return 0;
}

Using the find() function with sets

I have just encountered this chapter in my book and I dont really understand how find() works. I tried to create a simple function to check how the find() function works, but I am getting a multitude of errors in my code.
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> setA(1,2);
int item;
cout << "Enter a number: ";
cin >> item;
int setIter;
setIter = setA.find(item);
if (setIter != setA.end())
{
cout << "It's in the list." << endl;
}
return 0;
}
Here is the correct implementation of your program...
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> setA;
setA.insert(1); // use insert function
setA.insert(2);
set<int>::iterator setIter; // take set iterator
int item;
cout << "Enter a number: ";
cin >> item;
setIter = setA.find(item);
if (setIter != setA.end())
{
cout << "It's in the list." << endl;
}
return 0;
}
You are making two mistakes in your program. First you are initializing set using constructor which does not work so you have to use insert function of set. Secondly you are taking iterator as an int which is not correct. Iterator is basically a pointer of set type. So you have to take the iterator of set
Your code has two issues- first is the usage of constructor and the other is assigning set iterator returned by set.find() to an int. Here is the corrected code:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> setA({1,2});
int item;
cout << "Enter a number: ";
cin >> item;
set<int>::iterator setIter = setA.find(item);
if (setIter != setA.end())
{
cout << "It's in the list." << endl;
}
return 0;
}

C++ std::getline error

I'm new to C++, could someone please explain to me why I received the below errors when I do use "std::getline"? Here's the code:
#include <iostream>
#include <string>
int main() {
string name; //receive an error here
std::cout << "Enter your entire name (first and last)." << endl;
std::getline(std::cin, name);
std::cout << "Your full name is " << name << endl;
return 0;
}
ERRORS:
te.cc: In function `int main()':
te.cc:7: error: `string' was not declared in this scope
te.cc:7: error: expected `;' before "name"
te.cc:11: error: `endl' was not declared in this scope
te.cc:12: error: `name' was not declared in this scope
However, the program would run and compile when I used "getline" with "using namespace std;" instead of std::getline.
#include <iostream>
#include <string>
using namespace std;
int main() {
string name;
cout << "Enter your entire name (first and last)." << endl;
getline(cin, name);
cout << "Your full name is " << name << endl;
return 0;
}
Thank you!
The errors are not from std::getline. The error is you need to use std::string unless you use the using namespace std. Also would need std::endl.
You need to use std:: on all the identifiers from that namespace. In this case, std::string and std::endl. You can get away without it on getline(), since Koenig lookup takes care of that for you.
#include <iostream>
#include <string>
int main()
{
std::string name; // note the std::
std::cout << "Enter your entire name (first and last)." << std::endl; // same here
std::getline(std::cin, name);
std::cout << "Your full name is " << name << std::endl; // and again
return 0;
}
You just needed to state the namespace for various elements that are in the std namespace (alternatively, you can remove all the std::s and place a using namespace std; line after your includes.)
Try this:
#include <iostream>
#include <string>
int main()
{
std::string name;
std::cout << "Enter your entire name (first and last)." <<
std::endl;
while(getline(std::cin, name))
{
std::cout <<"Your name is:"<< name << '\n';
}
return 0;
}

c++ sscanf reading string vector

thanks for the support on the previous post... i am now trying to store the vector string on another string and do a sscanf to check for a text eg. "TEXT" and if found append another text at the end of line....
any ideas???
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
using namespace std;
int main() {
vector<string> vs;
vector<string>::iterator vsi;
string agent;
string buffer;
string line;
while (!(cin.eof())) {
getline(cin, buffer);
cout << buffer << endl;
vs.push_back(buffer);
};
vsi = vs.begin();
for (int count=1; vsi != vs.end(); vsi++,count++){
cout << "string" << count <<"="<< *vsi << endl;
line = *vsi;
sscanf(line, "%s %[^\n]",text);
//dummy code
if text=="TEXT" do this:
cout << "agent" << text << "endl";
}
else: do nothing
return 0;
}
[root#server dev]# g++ -o newcode newcode.cpp
newcode.cpp: In function ‘int main()’:
newcode.cpp:24: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int sscanf(const char*, const char*, ...)’
[root#server dev]#
UPDATE:
i used line.c_str() on sscanf and gives out this error
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
using namespace std;
int main() {
vector<string> vs;
vector<string>::iterator vsi;
string agent;
string buffer;
string line;
while (!(cin.eof())) {
getline(cin, buffer);
cout << buffer << endl;
vs.push_back(buffer);
};
vsi = vs.begin();
for (int count=1; vsi != vs.end(); vsi++,count++){
cout << "string" << count <<"="<< *vsi << endl;
line = *vsi;
cout << "LINE:" << line.c_str() << endl;
sscanf(line.c_str(), "%s %[^\n]",agent);
/* cout << "agent" << agent << "endl"; */
}
return 0;
}
[root#server dev]# g++ -o newcode newcode.cpp
newcode.cpp: In function ‘int main()’:
newcode.cpp:25: warning: cannot pass objects of non-POD type ‘struct std::string’ through ‘...’; call will abort at runtime
[root#server dev]#
what i want to do is when a string on a particular line is detected it will append a text to the end of line and stdout...
It's not entirely clear what you are trying to do but if you want to get the right type passed into sscanf you'll need to change some things around. sscanf only deals with c strings and you've tried to pass it in a c++ string object, to fix this you might want to use line.c_str() in sscanf to get it passed in the right format.
A better approach would be to use a c++ algorithm like string::find though as this will remove the need to use sscanf.
I'm not sure of you want to do, but you should check out string::find : Cplusplus reference
Instead of using sscanf try using stringstream which work nearly the same as cin/cout.