I am reading in files from a repo and I am having trouble compiling the code. My github partner(using a mac) has no issue with the code but when I clone his repo, I get this issue.
Background info:
I recently moved into the Linux world and am running Elementary. Not sure if there could be an issue here since my other coding projects work, but it is background info.
error: no matching function for call to ‘std::basic_ifstream<char>::open(std::__cxx11::string&)’
infile.open(fullPath); // Open it up!
In file included from AVL.cpp:6:0:
/usr/include/c++/5/fstream:595:7: note: candidate: void std::basic_ifstream<_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, ios_base::openmode __mode = ios_base::in)
^
/usr/include/c++/5/fstream:595:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’
Makefile:4: recipe for target 'main' failed
make: *** [main] Error 1
Here's my function:
void AVL::parseFileInsert(string fullPath) {
ifstream infile;
infile.open(fullPath); // Open it up!
std::string line;
char c;
string word = "";
//int jerry = 0;
while (getline(infile, line))
{
// Iterate through the string one letter at a time.
for (int i = 0; i < line.length(); i++) {
c = line.at(i); // Get a char from string
tolower(c);
// if it's NOT within these bounds, then it's not a character
if (! ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) ) ) {
//if word is NOT an empty string, insert word into bst
if ( word != "" ) {
insert(word);
//jerry += 1;
//cout << jerry << endl;
//reset word string
word = "";
}
}
else {
word += string(1, c);
}
}
}
};
Anything is greatly appreciated!
The std::basic_fstream::open overload taking a const std::string & argument has been introduced in C++11. If the code compiles with one compiler but not another, it stands to reason that one compiler supports C++11 and the other doesn't (either by virtue of being too old, or by not specifying the C++ standard on the command line).
If you cannot switch to a C++11 compiler (or change the command line to enable C++11 support), you could simply change the line of code
infile.open(fullPath); // Open it up!
to
infile.open(fullPath.c_str()); // Open it up!
That doesn't change the semantics, with one exception: std::string supports embedded NUL characters, while the C-style string returned by c_str() does not. I'm not aware of a filesystem that allows embedded NUL characters in file/directory names, so that difference is of theoretical nature.
Related
I have this basic multi tool program which goal is to complete four functions on a file that contains some strings.. take a string, for example, take a line and put it in uppercase.
I get that it's not perfect yet, but i need to understand why my char* and char** are doing some mess.
thanks a lot for your time
#include <iostream> //to use enter and exit
#include <cstring>
#include <string>
#include <fstream> //to use files
using namespace std;
/*--------------------------FONCTION PART-----------------------------------*/
//define one fonction for each transformation
//FONCTION 1
void fonctionu (char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern);
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
if(line[i] >= 'a' && line[i] <= 'z') {
line[i] = line[i] - (32);// (ASCII)
cout<<line[i];
}} }
if (found == string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<<line[i];
}}}}}
//FONCTION 2
void fonctiond( char* argv){ //remove line with xyz
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern); //as a reminder argv[2] is the pattern (warning : it need to be an unsigned to compare two unsigned)
if (found != string::npos) {
//delete the line of the file when there is the pattern
cout<<'\0'; }
if (found == string::npos){
for (int i = 0; line[i]!='\0'; i++) {
cout<< line[i];
}}}}}
//FONCTION 3
void fonctionc( char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data ){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern); //as a reminder argv[2] is the pattern
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<< "\033[31m"<< line[i]; //the line will be red
}
}
if (found == string::npos){
for (int i = 0; line[i]!='\0'; i++) {
cout<< line[i];
}}}}}
//FONCTION 4
//replace the pattern xyz by abc
void fonctions ( char* argv){
char pattern = argv[2];
char file = argv[3];
fstream data(file, ios::in);
if (data ){
string line;
while (getline (data ,line)){
unsigned found = line.find(pattern);
if (found != string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
if(line[i] >= 'a' && line[i] <= 'z') {
line[i] = line[i] - (97); // (ASCII) //we creat a shift that allow to make the x became a 'a' and the y a 'b'...etc
cout<<line[i];}}
}
if (found == string::npos) {
for (int i = 0; line[i]!='\0'; i++) {
cout<<line[i];
}}}}}
/*--------------------------MAIN PART---------------------------------------*/
int main(char* argv){
// ipsacs : argv[0]
//option :
string a = argv[1]; //string ! to compare line 103,108 and 112
// pattern : argv[2];
//file : argv[3];
if (argv[1]=='\0' || argv[2]=='\0'){
cout <<"ERROR"<<'\n';}
if (a == "u"){
char fonctionu (argv);}
if (a== "d"){
char fonctiond(argv);}
if (a == "c"){
char fonctionc(argv);}
if (a == "s"){
char fonctions(argv);}
return 0;
}
/*--------------------------TEST PART--------------------------------------*/
/*
pour compiler : g++ -Wall ipsacs.cpp -o ipsacs
./ipsacs u xyz foo //how the program would receive arguments, basically
Le programme ne renvoie rien.
*/
here is the compiling log:
main.cpp:22:30: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctiond(char*)’:
main.cpp:46:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctionc(char*)’:
main.cpp:66:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: In function ‘void fonctions(char*)’:
main.cpp:88:29: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
fstream data(file, ios::in);
^
In file included from main.cpp:8:0:
/usr/include/c++/6/fstream:902:7: note: initializing argument 1 of ‘std::basic_fstream<_CharT, _Traits>::basic_fstream(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits; std::ios_base::openmode = std::_Ios_Openmode]’
basic_fstream(const char* __s,
^~~~~~~~~~~~~
main.cpp: At global scope:
main.cpp:109:5: warning: first argument of ‘int main(char*)’ should be ‘int’ [-Wmain]
int main(char* argv){
^~~~
main.cpp:109:5: warning: ‘int main(char*)’ takes only zero or two arguments [-Wmain]
main.cpp: In function ‘int main(char*)’:
main.cpp:113:20: error: conversion from ‘char’ to non-scalar type ‘std::string {aka std::basic_string}’ requested
string a = argv[1]; //string ! to compare line 103,108 and 112
~~~~~~^
main.cpp:121:26: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctionu (argv);}
^
main.cpp:123:25: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctiond(argv);}
^
main.cpp:125:27: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctionc(argv);}
^
main.cpp:127:27: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
char fonctions(argv);}
^
A char * is a pointer to a memory address holding a character, and is often used for c-strings.
A char ** is a pointer to a memory address holding a pointer to a memory address holding a character, and is often used for arrays of c-strings.
Your main signature if not a valid form, since there's no form of main which takes in only a character pointer. The form you are most likely looking for is int main( int argc, int **argv ). This takes in two parameters: argc being the number of arguments passed to the program, and argv containing the parameters, as c-strings, passed to the program.
In the main method, you would generally ensure that argc is correct, i.e. you have the correct number of parameters passed into your function (note: it's always at least 1 will argv[0] being the program name).
std::string a = argv[1] is fine, and it will cause the string pointed to by argv to be converted to a string. When calling your functions, you have char functionu(argv);. You will want to remove the char from that line; effectively, the way it is written, you are trying to create a char variable named functionu which has an initial value of argv.
Each of your functions, instead of taking in a char * should take in a char ** instead, then when you have something like char file = argv[3];, you would want to change this to char *file = argv[3];, or std::string file = argv[3];
So I have a function that takes in a file input character by character and forms the characters into sentences to be modified. One of the modifications to be done is to make a run on sentence in this instance. It will take two sentences and form a run-on sentences by removing the punctuation between them and concatenating them.
Here is my code:
void runOn(char sentence, ifstream & fin, int counter)
{
char ch;
int sentCounter = 0;
bool sentenceEnd = false;
while(sentCounter<=2)
{
char tempSent[SENT_LENGTH];;
do
{
fin.get(ch);
for(int i = 0; i<SENT_LENGTH;i++)
{
tempSent[i] = ch;
}
if(ch == '.' || ch == '?' || ch == '!')
{
sentCounter++;
sentenceEnd = true;
}
}while(sentenceEnd == false);
strcat(sentence,tempSent);
}
}
The counter passed is only used because the function should only run for the first two sentences.
When I attempt to compile, I get this error:
function.cpp:36:29: error: invalid conversion from 'char' to 'char*' [-fpermissive]
strcat(sentence,tempSent);
Edit: I should add, I'm only allowed to use C style null terminated character arrays
The error is very clear, strcat is declared as char * strcat ( char * destination, const char * source );, however, sentence is not char*, you must convert sentence from char to char*.
Since I don't know where sentence comes from, I can't give further advice, may be you should post the function which called the runOn.
Maybe you can simply change void runOn(char sentence, ifstream & fin, int counter) to void runOn(char* sentence, ifstream & fin, int counter)
See declaration of strcat here
http://www.cplusplus.com/reference/cstring/strcat/ as you can see strcat accepts char * not char in your function you need to take sentence as char* then your function will work.
The following Objective C++ routine, if I run it enough in XCode 7.1 on OS X 10.11, eventually crashes on the string append. The debugger shows me that it stops every time at the number 23 (trying to append the number 23). I imagine this has to do with memory allocation. What am I doing wrong?
The debugger opens the string class and jams on the return statement below. In the other debugger window it says (lldb), whatever that means.
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>&
basic_string<_CharT, _Traits, _Allocator>::append(const basic_string& __str)
{
return append(__str.data(), __str.size());
}
Here's my code I'm running that seems to cause the crash if I run the routine enough times. (This was only present during monkey testing, where I clicked on my Settings menu in my Objective C/C++ application enough times that it triggered the following function enough times to crash.)
std::string Minutes[] = {};
std::string s = "";
for (int i = 1; i<= 59; i++) {
s = std::to_string(i);
if (s.length() < 2) {
s = "0" + s;
}
s = ":" + s;
Minutes->append(s);
}
This might be a plain old C++ question, perhaps not an Objective C++ question. Or, perhaps this is an Apple bug?
Note that I ran an experiment with the following change, and it never crashed after 3 attempts of 100 times:
std::string Minutes[] = {};
std::string s = "";
for (int i = 1; i<= 59; i++) {
//s = std::to_string(i);
/*
if (s.length() < 2) {
s = "0" + s;
}
s = ":" + s;
*/
//[Minutes->append(s);
Minutes->append("01");
}
Also, the following patch of code also runs 3 times, up to 100 times, without an issue:
const std::string Days[] = {"Su","M","T","W","Th","F","Sa"};
std::string Hours[] = {};
for (int i = 1; i <= 12; i++) {
Hours->append(std::to_string(i));
}
If you intend to keep null string in Minutes, do as follows
std::string Minutes[] = {""};
Then Minutes->append(s);will append s to first null string inside the Minutes[] array.
UPdate:
First you have to create a dynamic array( std::vector) of string, in case if you don't know the size of the array as follows and use index to access the string from std::vector.
// implies that you used #include <string> and #include <vector>
std::vector<std::string> Minutes;
Minutes.push_back(s)
Here is my code:
#include<stdio.h>
#define MAXLINE 100
/*print the reverse of the input*/
int getline1(char line[], int maxline);
char *reverse(char);
main(){
int len;
char line[MAXLINE];
char *rp;
while ((len = getline1(line, MAXLINE)) > 0)
rp = reverse(line);
printf("%s", *rp);
return 0;
}
int getline1(char s[], int lim){
int c, i;
for (i = 0; (c=getchar()) != EOF && c != '\n'; i++)
if (i > lim-1)
continue;
else
s[i] = c;
if (c == '\n'){
s[i] = c;
i++;
}
s[i] = '\0';
return i;
}
char *reverse(char ca[]){
int i;
int i1 = 0;
char *rp;
char reversed[MAXLINE];
for (i = MAXLINE-1; i >= 0; i--){
reversed[i1] = ca[i];
i1++;
}
rp = reversed;
return rp;
}
But when I try to compile it, I get the following errors:
reverse.cpp: In function ‘int main()’:
reverse.cpp:14:20: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
reverse.cpp:7:7: error: initializing argument 1 of ‘char* reverse(char)’ [-fpermissive]
reverse.cpp:15:19: warning: format ‘%s’ expects argument of type ‘char*’, but argument 2 has type ‘int’ [-Wformat]
I don't have much experience with C++. What am I doing wrong? I just want to make a pointer to a char array and return it.
I just want to make a pointer to a char array and return it.
You appear to want to return a string. That is not a pointer to a char array. Even if your program compiled, you would invoke UB, as you return a pointer to an automatic object- and there are quite a few other runtime errors in your code as well. You got lucky that you also made a compile-time error so the compiler did not accept your program. This C++ program achieves what you intend:
#include <string>
#include <iostream>
std::string reverse(std::string val) {
return std::string(val.rbegin(), val.rend());
}
int main() {
std::string str;
while(std::getline(std::cout, str))
std::cout << reverse(str);
}
What am I doing wrong?
You're learning C89 intead of C++11. They're really different things.
If you wish to learn to code C++, you must learn std::string, and the rest of the Standard library. You will not get anywhere with char*, char[], and MAGIC_BUFFER_SIZE.
You first declare the function prototype
char *reverse(char);
But the actual function is declared as
char *reverse(char ca[])
That's your problem.
What are you trying to achieve ? There are logical errors in the code ...
while ((len = getline1(line, MAXLINE)) > 0)
rp = reverse(line);
printf("%s", *rp);
this part will call reverse on every /n character but printf will never be called...
Also you have string of 100 chars and your reverse will put leading char on end of reverse string.. so if you have string of 5 chars you will have garbage on first 95 positions and then 5 chars you need ...
I was trying for the first time to read data from a file, a .txt file. Below is my code:
Level::ReadStream(std::fstream data)
{
bool write = false;
char* p = data.tellg();
while(!data.eof())
{
int i = 0, j = 0;
if(&p == '[')
{
write == true;
}
if(write == true)
{
mapX[i] = p;
mapY[j] = p;
}
if(&p == '/n')
{
i++;
j++;
}
else
{
i++;
}
*p++
}
};
void Level::SetMapSize(std::fstream data)
{
int* p = data.tellg();
int sizeX = 0;
int sizeY = 0;
while(!data.eof())
{
if(&p != '[' && &p != ']' && &p != '\n')
{
sizeX++;
}
else if(&p != '\n')
{
sizeY++;
}
}
mapX.resize(sizeX);
mapY.resize(sizeY);
std::cout << sizeX << '\n' << sizeY;
};
The goal of these two functions are to:
1- read all the chars in the file and, if the current character is not a bracket, add it to an index map(X, Y), then increase the counter so the next non-bracket value will be put in the correct index.
2- read all the file and, as before, count the non-bracket values, so it can make mapX and mapY the correct size.
However, it's not working, and I got these errors:
C:\...\Level.cpp|58|warning: multi-character character constant|
c:\...\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\bits\ios_base.h|790|error: 'std::ios_base::ios_base(const std::ios_base&)' is private|
c:\...\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\iosfwd|47|error: within this context|
c:...\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\iosfwd|87|note: synthesized method 'std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)' first required here |
c:...\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\streambuf|770|error: 'std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]' is private|
c:...\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\iosfwd|78|error: within this context|
c:...\mingw\bin\..\lib\gcc\mingw32\4.4.1\include\c++\iosfwd|87|note: synthesized method 'std::basic_filebuf<char, std::char_traits<char> >::basic_filebuf(const std::basic_filebuf<char, std::char_traits<char> >&)' first required here |
C:...\Level.cpp||In constructor 'Level::Level()':|
C:...\Level.cpp|24|note: synthesized method 'std::basic_fstream<char, std::char_traits<char> >::basic_fstream(const std::basic_fstream<char, std::char_traits<char> >&)' first required here |
C:...\Level.cpp|24|error: initializing argument 1 of 'void Level::SetMapSize(std::fstream)'|
C:...\Level.cpp|29|error: 'cout' was not declared in this scope|
C:...\Level.cpp|38|error: ISO C++ forbids declaration of 'ReadStream' with no type|
C:...\Level.cpp|38|error: prototype for 'int Level::ReadStream(std::fstream)' does not match any in class 'Level'|
C :...\Level.cpp|17|error: candidate is: void Level::ReadStream(std::fstream)|
C:...\Level.cpp||In member function 'void Level::SetMapSize(std::fstream)':|
C:...\Level.cpp|75|error: invalid conversion from 'std::streamoff' to 'int*'|
C:...\Level.cpp|81|error: ISO C++ forbids comparison between pointer and integer|
C:...\Level.cpp|81|error: ISO C++ forbids comparison between pointer and integer|
C:...\Level.cpp|81|error: ISO C++ forbids comparison between pointer and integer|
C:...\Level.cpp|86|error: ISO C++ forbids comparison between pointer and integer|
C:...\Level.cpp|95|error: 'cout' is not a member of 'std'|
||=== Build finished: 15 errors, 1 warnings ===|
Can anyone help?
EDIT: Ok, I changed everything. My new code is:
void Level::ReadStream()
{
long p = textData.tellg();
int counter = 0;
int i = 0;
int j = 0;
char ch;
while(p != textData.eof())
{
textData.seekg(counter);
textData >> ch;
if(ch != '[' && ch != ']')
{
mapX[i] = ch;
mapY[j] = ch;
i++;
if(ch == '\n')
{
i = 0;
j++;
}
}
counter++;
p = textData.tellg();
}
};
with mapX and mapY being 5 int long. Now it compiles, but hangs and crashes. I don't see why... Is there anyone that can help me?
It's \n not /n! That should clear some errors.
Also, you can't just take the pointer from tellg -- it returns the position, not the pointer to the position!
Basically try to read up on IO in C++, maybe start with this question:
How to read from a file char by char in C++?