c++ error compiling when trying to unlink files - c++

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

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).

Error using string::erase in C++

I'm having an error while compiling my C++ program. Below is my code!
#include <pthread.h>
#include "Path.h"
#include "Maze.h"
#include "SubmitMazeSoln.h"
#include "Assignm3_Utils.h"
#include "Assignm3.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
srand(time(NULL));
string random = "0123";
for (int i = 0; i < 4; i++)
{
int x = (rand () % random.size());
char y = random[x];
random.erase(remove(random.begin(), random.end() + y), random.end());
int temp;
if (threadData.threadIDArrayIndex == 0)
{
temp = i;
}
else
{
temp = y - '0';
}
}
The error when I compile my program.
myprog.cpp: In function ‘void* exploreMaze(void*)’:
myprog.cpp:108:56: error: cannot convert ‘std::basic_string<char>::iterator {aka __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >}’ to ‘const char*’ for argument ‘1’ to ‘int remove(const char*)’
random.erase(remove(random.begin(), random.end() + y), random.end());
Sorry guys help is deeply appreciated! Thanks!
As DaveB says,
remove(random.begin(), random.end() + y)
should be
remove(random.begin(), random.end(), y)
The error message is confusing because random.end() + y is a valid expression, although it produces an iterator that's way off the end of the container. So the compiler sees a call to the function remove with two arguments, and tries to make sense of it. The compiler sees a function with the signature remove(const char*), and guesses that that's what you meant, then complains that it can't convert the first argument to type const char*.
This confusion wouldn't have happened if you used proper C++ standard library names such as std::remove. using namespace std; strikes again!

Removing duplicates string array 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';
}

Unordered_map<string, int> works but Unordered_map<string, string> does not

I don't understand why the second block of code in this short example does not compile correctly. It is my understanding that the second parameter in the <> represents the value, which doesn't need to be unique. Why is the second block of code throwing a compiler error, and what do I need to do to remedy it?
// Unordered Map example .cpp
#include <stdio.h>
#include <string>
#include <cstring>
#include <unordered_map>
using namespace std;
int main(void) {
// This works as expected
unordered_map<std::string, int> m;
m["foo"] = 42;
printf("%i\n", m["foo"]);
// This this doesn't compile
unordered_map<std::string, std::string> m1;
m1["foo"] = "42";
printf("%s\n", m1["foo"]);
return 0;
}
I am compiling this code on CentOS 5.8 using
g++44 -c -Wall -std=c++0x -g map_example.cpp
and these are the errors I am getting
map_example.cpp: In function ‘int main()’:
map_example.cpp:20: warning: cannot pass objects of non-POD type ‘struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ through ‘...’; call will abort at runtime
map_example.cpp:20: warning: format ‘%s’ expects type ‘char*’, but argument 2 has type ‘int’
If I am having trouble with a basic c++ class such a std:string what do I need to do to have a custom class as a value, where can I find a fully implemented minimal example?
printf does not work with std::string. Either use cout << m1["foo"] or printf("%s", m1["foo"].c_str())
printf("%s\n", m1["foo"]); is C.
For c++ you should use std::cout to have both the string and the int map's values printed out as expected.
The compiler cannot do a translation for a std::string object automatically to const char* (there is no conversion to const char* by default: Why does std::string not provide a conversion to const char*?)

‘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.