Removing duplicates string array c++ - c++

I would like to read from a file containing one column of strings, i.e.
AAAA
BBBB
22
4556
.
.
.
and rewrite in the same file only the unique elements.
sprintf(nameID,"Try.dat");
IDFile = fopen (nameID,"r+");
std::vector<std::string> test;
fputs (test,IDFile)
std::sort(test);
auto it = std::unique(std::begin(test), std::end(test));
test.erase(it, test.end());
for(int k = 0; k<test.size();k++){
fprintf (IDFile,"%s \n",test[k].c_str());
}
fclose (IDFile);
But I get the following errors
error: cannot convert ‘std::vector<std::basic_string<char> >’ to ‘const char*’ for argument ‘1’ to ‘int fputs(const char*, FILE*)’
error: no matching function for call to ‘sort(std::vector<std::basic_string<char> >&)’
warning: ‘auto’ changes meaning in C++11; please remove it [-Wc++0x-compat]
error: ‘it’ does not name a type
Any help/better way of doing it ?
thanks

The standard library is your friend:
#include <set>
#include <iostream>
int main()
{
std::set<std::string> set;
for (std::string line; getline(std::cin, line);)
set.insert(line);
for (auto const& s : set)
std::cout << s << '\n';
}

Related

While Searching for a key in a map in C++ STL, gives the following error

I have a created a Map with key as string type and the associated value stored in vector. Now I have a string and need to check if the each of the character in the string is present as a key in the map.
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, vector<string>> umap;
umap["1"] = {"a","b","c"};
umap["2"] = {"d","e","f"};
string s = "23";
for(int i=0; i<s.length(); i++) {
if(umap.find(s[i]) != umap.end())
cout<<"Present"<<endl;
else
cout<<"Not Present"<<endl;
}
}
Error:
main.cpp: In function ‘int main()’:
main.cpp:15:26: error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::vector<std::__cxx11::basic_string<char> > >::find(__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&)’
if(umap.find(s[i]) != umap.end())
The error is maybe a bit cryptic. Lets translate it into something human readable.
main.cpp: In function ‘int main()’:
main.cpp:15:26: error: no matching function for call to ‘std::map<std::__cxx11::basic_string<char>, std::vector<std::__cxx11::basic_string<char> > >::find(__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type&)’
if(umap.find(s[i]) != umap.end())
First std::__cxx11::basic_string<char> is a complicated way to denote a std::string. Then __gnu_cxx::__alloc_traits<std::allocator<char> >::value_type& is an even more complicated way to denote the return type of s[i] which is actually just char&. Putting this together we get
main.cpp: In function ‘int main()’:
main.cpp:15:26: error: no matching function for call to ‘std::map<std::string, std::vector<std::string> >::find(char&)’
if(umap.find(s[i]) != umap.end())
I hope now you can see that the error complains that there is no overload of find that would take a char& as parameter.
Instead you should pass a std::string, eg via s.substr(i,1).

c++ error compiling when trying to unlink files

I'm using this code I found on stackoverflow.. this seems to work well for my requirement.
#include <stdio.h>
#include <iostream>
#include <string>
#include <map>
#include <conio.h>
int main () {
std::map< std::string, std::string > MyMap;
std::map< std::string, std::string >::iterator MyIterMap;
MyMap["Teste1"] = "map1";
MyMap["Teste2"] = "map2";
MyMap["Teste3"] = "map3";
MyIterMap = MyMap.begin();
while(MyIterMap != MyMap.end() ) {
std::string key = (*MyIterMap).first;
std::cout << "Key: " << key << ", Value: " << MyMap[key] <<std::endl;
MyIterMap++;
}
_getch();
return 0;
}
After each loop, before MyInterMap++ I'm trying to unlink a file based on the value of key as the filename. eg:
unlink ("/tmp/" + key);
When I try and complie I get:
In function ‘int main()’:
error: cannot convert ‘std::string {aka std::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int unlink(const char*)’
Please can some one advise how I do this ?
Thank you for you time.
You need to pass a pointer to a C string to the unlink function:
const std::string filename = "/tmp/" + key;
unlink(filename.c_str());
It's probably not a problem in this case as unlink is unlikely to store the C string pointer anywhere, but do note that the pointer becomes dangling as soon as the variable filename goes out of scope. If you pass a pointer to a C string obtained from a std::string anywhere, make sure that that pointer does not get used after the std::string is destroyed.
I've resolved it by using
unlink( ("/tmp/" + key).c_str() ) ;
Thanks

Long, nearly incoherent errors C++

Sometimes I get incredibly long errors in my code that I don't understand so I just rework my code to avoid whatever was causing the error. I had another one today that I simply can't avoid.
My code:
#include <iostream>
#include <fstream>
#include <string>
#include <cctype>
#include <vector>
using namespace std;
void readFile(string);
class info {
public:
int rows;
int cols;
vector < string > data;
};
int main(int argc, char **argv){
string filename1;
filename = argv[1];
readFile(filename);
return 0;
}
//should read onle line at a time from a file and print it
void readFile(string filename1){
fstream datafile;
datafile.open(filename1);
while (!datafile.eof()){
string line;
getline(datafile,line);
cout<<line<<endl;
}
datafile.close();
}
The error stems from trying to get the name of the file from argv[1]. It was working fine when I just gave it the file name.
The error:
project2.cpp: In function ‘int main(int, char**)’:
project2.cpp:22:2: error: ‘filename’ was not declared in this scope
filename = argv[1];
^
project2.cpp: In function ‘void readFile(std::string)’:
project2.cpp:32:25: error: no matching function for call to ‘std::basic_fstream<char>::open(std::string&)’
datafile.open(filename1);
^
project2.cpp:32:25: note: candidate is:
In file included from project2.cpp:2:0:
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/fstream:889:7: note: void std::basic_fstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]
open(const char* __s,
^
/usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/fstream:889:7: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘const char*’
I am using Cygwin. I used it last semester as well when I was writing code in C, and my professor had us check certain installation options at the time. Could these installation options be the root of the problem? Or are errors like this common in C++? Thanks.
Just read the error:
project2.cpp: In function ‘int main(int, char**)’: project2.cpp:22:2:
error: ‘filename’ was not declared in this scope filename = argv[1];
^
Here it says that filename is not declared. i.e. You have to declare it or something wrong with the declaration
Looking at the code you have
string filename1;
One assumes you meant
string filename;
Fix this error - then try again
The first error:change filename1 to filename
The second error: you should set a open()functions in the class info.then you can use it

C++ Scrubbing Windows New Line Elements in a String on a Unix Compiler

I'm using a Unix shell compiler and need to import a Windows .dat file for input. Unfortunately this means there exists native '\r\n' components for carriage returns in the input file.
I'm hoping to scrub these out with something along the lines of the following:
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream inputFile;
inputFile.open("myFile.dat");
string array[100];
int i = 0;
while(getline(dataIn, str))
{
str.erase(remove(str.begin(), str.end(), '\n'), str.end());
str.erase(remove(str.begin(), str.end(), '\r'), str.end());
array[0] = str;
i++;
}
return 1;
}
However this is providing the following error:
error: cannot convert ‘__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >’ to ‘const char*’ for argument ‘1’ to ‘int remove(const char*)’
for the first erase(), followed by
error: request for member ‘erase’ in ‘temp.std::basic_string<_CharT, _Traits, _Alloc>::c_str [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]()’, which is of non-class type ‘const char*’
for the second.
I've attempted str.c_str().erase but this has resulted in duplicates of the second error. Any suggestions would be greatly appreciated...
Two problems in the code:
You if you want to use the algorithm function remove, you need to add #include <algorithm>.
To ensure the ::remove (which is a function that removes the file named by the char * argument) isn't picked up, use std::remove.

‘virtual char std::ctype<wchar_t>::do_narrow(wchar_t, char) const’ is protected

I'm trying to convert wstring to string with use of locale facets but I got stuck on following error:
test_facet.cpp: In function ‘int main()’:
test_facet.cpp:14: error: invalid initialization of reference of type ‘std::ctype<wchar_t>&’ from expression of type ‘const std::ctype<wchar_t>’
/usr/include/c++/4.4/bits/locale_facets.h:1430: error: ‘virtual char std::ctype<wchar_t>::do_narrow(wchar_t, char) const’ is protected
test_facet.cpp:16: error: within this context
Source:
#include <iostream>
#include <string>
#include <locale>
#include <algorithm>
using namespace std;
int main()
{
locale loc("");
std::wstring Str = L"ěščřžýáíé";
std::string Str2;
ctype<wchar_t> &ct = std::use_facet<std::ctype<wchar_t> >(loc);
for(std::wstring::const_iterator It = Str.begin(); It < Str.end(); ++It)
ct.do_narrow(*It, 'X' );
std::cout << Str2 <<std::endl;
}
Could someone tell me, what I am dooing wrong?
Thanks
2 things:
1) use_facet returns reference to const, so you can't assign it to a non-const one. So declare ct as:
const ctype<wchar_t> &ct = ....
2) As the second error message states, do_narrow is protected, making it unaccessible to external callers. Use narrowinstead, which is public.
You cannot invoke do_narrow from this context. Only member methods of class ctype (and deriveds) are allowed to call do_narrow.