How could/should I print text strings above number columns in C++? - c++

I would like to print the strings at the top of columns with a 1 x 3 array.
I have edited this simple function several times, and this produces the least errors. New to C++, reading Deital Chap 6 Recursive.
What am I missing? I started with half brackes around strings, and brackets seemed to produce less errors.
Here is the code:
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main() {
array a[1][3] = ["Car" "Hours" "Charge"]
cout<< a << endl;
}
Terminal produces errors as such:
parking_charges_6_12.cpp: In function ‘int main()’:
parking_charges_6_12.cpp:8:7: error: missing template arguments before ‘a’
8 | array a[1][3] = ["Car" "Hours" "Charge"]
^

This should work:
#include <array>
#include <iostream>
#include <string>
int main(){
std::array<std::string, 3> headlines = {"Car", "Hours", "Charge"};
for( auto const& elem : headlines ){
std::cout << elem << "\t";
}
}

It should be curly braces {} in the initializer, not []. And you need a comma between each element.
On the other hand, in later C++ revisions array can detect the type and number of elements, so you don't have to give that.
#include <iostream>
#include <array>
using namespace std;
int main() {
array a = {"Car", "Hours", "Charge"};
for (auto& item : a)
cout<< item << endl;
}

How about something like this:
#include<iostream>
using namespace std;
int main() {
string data[3] = {"Car", "Hours", "Charge"};
for (int i = 0; i < 3; i++)
cout << data[i] << " ";
}
Obviously it is not using the array header, but it's a working example. If you do need to use the array header, you can try something like :
#include <array>
#include <iostream>
#include <iterator>
#include <string>
using namespace std;
int main() {
array<string, 3> ar3 = {"Car", "Hours", "Charge"};
cout << ar3.size() << endl;
for (auto i : ar3)
cout << i << ' ';
return 0;
}
You can see it working online here

Related

sort in lexicographic order in map C++

I am using STL map in C++ for counting the frequency of words in a text file and words must be sort in lexicographic order. Input data is given as a text file. Ive already read and added them in map but i got a problem with sorting.
Example, i have { "Abc", "abc", "bag", "Boom", "great"}. When i added them in map, i got
Abc 1 Boom 1 abc 1 bag 1 great 1
but expected result is
Abc 1 abc 1 Boom 1 bag 1 great 1
#include <iostream>
#include <cstring>
#include <map>
#include <fstream>
using namespace std;
typedef map<string, int> word_count;
int main(){
word_count wc;
fstream f_in;
f_in.open("test.in");
string x;
while( !f_in.eof()){
f_in >> x;
wc[x]++;
}
f_in.close();
return 0;
}
Here is my code for reading input. Any help for my problem? Thanks
The OP wants a custom sort order that's subtly different from the standard lexicographical order. A map with a custom sort order can be achieved by passing in a custom Compare (Compare is the third template parameter of map):
#include <algorithm>
#include <cctype>
#include <cstring>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <vector>
using std::string;
using std::transform;
using std::map;
using std::cout;
struct Compare {
bool operator() (const string& s0, const string& s1) const {
// construct all lowercase versions of s0 and s1
string str0(s0.length(),' ');
string str1(s1.length(),' ');
transform(s0.begin(), s0.end(), str0.begin(), tolower);
transform(s1.begin(), s1.end(), str1.begin(), tolower);
if (!str0.empty() and !str1.empty() and str0.front()==str1.front()) {
// do a standard lexicographic sort if the first character is the same
return s0 < s1;
}
else {
// otherwise, do a case-insensitive lexicographic sort using the lowercased strings
return str0 < str1;
}
}
};
typedef map<string, int, Compare> word_count;
int main(){
word_count wc;
auto words = { "Abc", "abc", "bag", "Boom", "great"};
for (auto word : words)
wc[word]++;
for(auto elem : wc)
cout << elem.first << " " << elem.second << '\n';
return 0;
}
This indeed produces the desired output:
Abc 1
abc 1
Boom 1
bag 1
great 1
Try out a live version of the code online
By default, the third template parameter of a map is less<key> (in this case, less<string>), which will sort strings in the standard lexicographical A-z order.
Here is a complete example with file reading included, and using the base sorting functionality of std::map.
#include <iostream>
#include <cstring>
#include <map>
#include <fstream>
typedef std::map<std::string, int> word_count;
int main(int argc, char** argv){
if(argc < 2){
std::cout << "Please provide a file name." << std::endl;
return 1;
}
word_count wc;
std::ifstream inputfile(argv[1]);
if (inputfile.is_open()){
std::string x;
while(inputfile >> x){
wc[x]++;
}
inputfile.close();
}else {std::cout << "Program aborted: unable to open input file" << std::endl; return 1;}
for(auto word: wc){
std::cout << word.first << "\t" << word.second << std::endl;
}
return 0;
}

Vectors and Strings C++

#include <vector>
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
int main()
{
vector<string> test;
test.push_back("yasir");
test.push_back("javed");
for(int i=0; i!=test.end();i++)
{
cout << test[i];
}
}
Why is this code giving up an error? I am unable to identify the cause of the error.
Error: No Match for operator !=....
First of all, you are trying to compare int with the iterator of vector.
for(int i=0; i!=test.end();i++)
{
cout << test[i];
}
Here, the test.end() returns the iterator. There is no overloaded operator!= which can compare integer (int i = 0) with that iterator (test.end()).
So your loop should look more like:
for (std::vector<string>::iterator i = test.begin(); i != test.end(); i++)
{
cout << *i;
}
You can replace std::vector<string>::iterator with auto, if using C++11 or newer.
The next thing, you included <string.h> which contains old functions such as: strlen, strcpy. Similarly, <cstring> contains C-style strings.
If you want to you use operator<<, so if you want to write:cout << then you have to do: #include <string>.
As already mentioned, the problem is, that you try to compare an integer with an iterator in the "middle" of your for statement. Try this instead, it's more intuitive from my point of view
#include <vector>
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
int main()
{
vector<string> test;
test.push_back("yasir");
test.push_back("javed");
for(int i=0; i<test.size();++i)
{
cout << test[i];
}
}

Removing specific chunks from std::vector using a lambda function

EDIT: Sorry, i didn't put any result. I expected to remove the (10th, 11th), then the (20th, 21st), then the (30th, 31st) and so forth but instead I get this http://imgur.com/TbVmLo4
I have a vector composed by several vectors of the same size and i want to get rid of part of their end using remove if and a lambda function but there seems to be a displacement in the removal. Here is the code that I am running:
#include <vector>
#include <numeric>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <cmath>
#include <typeinfo>
int main()
{
int sizeOfSpectrum=10;
int desiredSizeOfSpectrum=8;
int count=-1;
std::vector<int> v(100);
std::iota (std::begin(v), std::end(v), 0);
auto newend=std::remove_if(v.begin(),v.end(),[&](int i)->bool{
count++;
int temp=count%sizeOfSpectrum;
bool test=(temp) > desiredSizeOfSpectrum;
return ( test);
});
v.erase(newend, v.end());
std::cout << "\n";
std::cout << "v[i]: \n";
for(int i : v)std::cout <<v[i]<<": ";
std::cout << "\n";
return 0;
}
The problem is in this line:
for(int i : v)std::cout <<v[i]<<": ";
When this line runs, i is given the value of the contents of each element of the vector. You are treating this as an index into the vector, rather than the value.
Instead use:
for(int i : v)
std::cout <<i<<": ";
Note: you still won't get quite the output you are after, but this should give you enough to work that out for yourself.

Is it possible to sort such strings: "30/11/2012:13:49:55" by date, as they're map keys? [duplicate]

This question already has answers here:
std::map - how to change key sorting?
(4 answers)
Closed 7 years ago.
I have a map with string date-time keys, and int values. I would like to sort my map by the date and time (by the map keys actually) which are in format like this: 30/11/2012:13:49:55. Is that possible? How to sort them? When sorting only string there's no such a big deal, but I really don't know how to do this with date/time string.
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main()
{
map<string, int> mymap;
mymap["30/11/2012:13:49:09"] = 122;
mymap["30/11/2012:13:49:55"] = 100;
mymap["30/11/2012:13:49:12"] = 123;
mymap["29/11/2012:19:26:11"] = 45;
for (std::map<string, int>::iterator i = mymap.begin(); i != mymap.end(); i++)
{
cout << i->first << "\n";
}
};
The output of the program suggests that this map is already ordered, however, I'm not quite sure if it always (in every case) sort it like I want it to.
Ok folks, will something like this work fine?
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <ctime>
using namespace std;
time_t string_to_time_t(string s)
{
struct tm tmp;
time_t t;
memset(&tmp, 0, sizeof(struct tm));
strptime(s.c_str(), "%d/%m/%Y:%H:%M:%S", &tmp);
t = mktime(&tmp);
return t;
}
int main()
{
time_t t, u;
t = string_to_time_t("30/11/2012:13:49:09");
u = string_to_time_t("30/11/2012:13:49:08");
if (u>t)
{
cout << "true" << endl;
}
else if (u==t)
{
cout << "same" << endl;
}
else
{
cout << "false" << endl;
}
return 0;
}
EDIT:
Huh, it seems to work now, thanks!
#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <map>
using namespace std;
time_t string_to_time_t(string s)
{
struct tm tmp;
time_t t;
memset(&tmp, 0, sizeof(struct tm));
strptime(s.c_str(), "%d/%m/%Y:%H:%M:%S", &tmp);
t = mktime(&tmp);
return t;
}
int main()
{
map<time_t, int> mymap;
mymap[string_to_time_t("30/11/2012:13:49:09")] = 122;
mymap[string_to_time_t("30/11/2012:13:49:55")] = 100;
mymap[string_to_time_t("30/11/2012:13:49:12")] = 123;
mymap[string_to_time_t("29/11/2012:19:26:11")] = 45;
for (std::map<time_t, int>::iterator i = mymap.begin(); i != mymap.end(); i++)
{
cout << i->first << " " << i->second << "\n";
}
};
You can provide your own functor as a template argument when instantiating your map, cf. std::map - how to change key sorting?. The sort functor should parse the string and give the proper relations.
That said, I am a big fan of date strings whose alphabetical order is the same as their logical one, e.g. 2015-12-31-23-59-49.999 or such (for 11.59 pm plus a few sconds on new year's eve). I use such strings when I name pictures and when I print to log files.

Program to initialize a vector from an array of ints. Cout is getting error?

Is the first element of arr1 getting added?
cout is giving me an error. What am I doing wrong?
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <cstddef>
using std::size_t;
int main ()
{
vector <int> ivec1; //defines a vector named ivec1 to hold values not yet defined
int arr1 [5] = {10, 20, 30 , 40, 50}; // defines array named arr1 with 5 values
ivec1.push_back (arr1 [0]);
cout << ivec1 << endl;
return 0;
}
The answer is quite simple: The operation you are invoking is simply not defined. The IO stream library is blissfully unaware of C++ standard library containers (besides std::string) and does not know how to print them. You will need to do that yourself.
std::vector<int> v;
for(auto& x : v)
std::cout << v << " "; // print each element
std::cout << std::endl; // and a linebreak
I guess cout is not able to work with vectors. I'd implement something like this (I'm sorry for my C++ I didn't write in C++ since 2006...
#include "stdafx.h"
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <cstddef>
using std::size_t;
void fillVector(int output[], vector<int>& input, int size)
{
for(int i=0;i<size; i++)
{
input.push_back(output[i]);
}
}
void printVector(vector<int>& input)
{
for(int i=0; i<input.size(); i++)
{
cout << input.at(i);
if(i!=input.size()-1)
{
cout << ",";
}
}
cout << endl;
}
int main ()
{
vector <int> ivec1; //defines a vector named ivec1 to hold values not yet defined
int arr1 [5] = {10, 20, 30 , 40, 50}; // defines array named arr1 with 5 values
int sz = sizeof(arr1) / sizeof(int);
fillVector(arr1, ivec1, sz);
printVector(ivec1);
return 0;
}