getline() returns an error - c++

I'm attempting to read from a file and use strtok() to break up the strings I get in from the file. The problem is, I keep getting this error whenever I compile the program.
source.cpp: In function ‘int main(int, char**)’:
source.cpp:39:32: error: no matching function for call to ‘getline(char [1000], int, char)’
source.cpp:39:32: note: candidates are:
/usr/include/stdio.h:675:20: note: __ssize_t getline(char**, size_t*, FILE*)
/usr/include/stdio.h:675:20: note: no known conversion for argument 1 from ‘char [1000]’ to ‘char**’
/usr/include/c++/4.6/bits/basic_string.h:2734:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.tcc:1070:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&, _CharT)
Here is the portion of my code that is causing the problem.
char *p, line[1000], opcode[9], arg1[256], arg2[256];
int i = 0;
while(getline(line, 1000, '\n') != NULL)
{
line[strlen(line)-1] = '\0';
cout << "Line = " << line << endl;
if (strchr(line, '#'))
{
*p = '\0';
}
if (p = strtok(line, "\t"))
strcpy(opcode,p);
if (p = strtok(NULL, "\t"))
strcpy(arg1,p);
if (p = strtok(NULL, "\t"))
strcpy(arg2,p);
printf("opcode=:%s: arg1=:%s: arg2=:%s:\n",opcode,arg1,arg2);
}
I'd appreciate any help I can get. Thank you.

You call the getline() function completely wrong. See the manual for getline() on how to use it. You get a hint:
candidates are:
__ssize_t getline(char**, size_t*, FILE*)
In your case it would be something like this:
getline(&line, 1000, your_file_pointer)

You need to open a stream to the file before you can start writing to it.
Here is a tutorial on how to do it.

Related

header file doesn't seem to be recognizing variables from main function

First of all, I am aware it is not good practice to do anything other then declare your functions etc... in the header file, but my teacher wanted us to follow this format so I am.
The goal of this particular function is to store user input into the various arrays in 'int main'.
The issue im getting with this function, as well as some others is that the compiler is throwing various errors I think are related to it not being able to recognize the arrays from 'int main'. (Just my guess).
Disclaimer: I have been working on this program since 4 pm till the time of posting this at 2 am so if im doing something really stupid I apologize, im honestly just going through the motions at this point.
//header file
void getVisitorInfo(int* age[], double* hours[], string* country[]) {
cout<<"Enter your country: ";
getline(cin, country[vCount]);
cout<<endl;
cout<<"Enter your age: ";
cin>>age[vCount];
cout<<endl;
cout<<"Enter the number of hours you explored: ";
cin>>hours[vCount];
cout<<endl;
vCount++;
}
//main file
const int max = 100;
int main() {
int age[max], vOldest, vYoungest, vAverage, userChoice;
double hours[max], vShortest, vLongest, vAverage;
string country[max];
bool pass;
//etc...
}
//a few of many errors
test.cpp: In function ‘void getVisitorInfo(int**, double**, std::string**)’:
test.cpp:84:31: error: no matching function for call to ‘getline(std::istream&, std::string*&)’
getline(cin, country[vCount]);
^
test.cpp:84:31: note: candidates are:
In file included from /usr/include/c++/4.8.2/string:53:0,
from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
from /usr/include/c++/4.8.2/bits/ios_base.h:41,
from /usr/include/c++/4.8.2/ios:42,
from /usr/include/c++/4.8.2/ostream:38,
from /usr/include/c++/4.8.2/iostream:39,
from test.cpp:1:
/usr/include/c++/4.8.2/bits/basic_string.tcc:1068:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&, _CharT)
getline(basic_istream<_CharT, _Traits>& __in,
^
/usr/include/c++/4.8.2/bits/basic_string.tcc:1068:5: note: template argument deduction/substitution failed:
test.cpp:84:31: note: mismatched types ‘std::basic_string<_CharT, _Traits, _Alloc>’ and ‘std::string* {aka std::basic_string<char>*}’
getline(cin, country[vCount]);
^
In file included from /usr/include/c++/4.8.2/string:52:0,
from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
from /usr/include/c++/4.8.2/bits/ios_base.h:41,
from /usr/include/c++/4.8.2/ios:42,
from /usr/include/c++/4.8.2/ostream:38,
from /usr/include/c++/4.8.2/iostream:39,
from test.cpp:1:
/usr/include/c++/4.8.2/bits/basic_string.h:2793:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&)
getline(basic_istream<_CharT, _Traits>& __is,
^
/usr/include/c++/4.8.2/bits/basic_string.h:2793:5: note: template argument deduction/substitution failed:
test.cpp:84:31: note: mismatched types ‘std::basic_string<_CharT, _Traits, _Alloc>’ and ‘std::string* {aka std::basic_string<char>*}’
getline(cin, country[vCount]);
^
test.cpp:89:6: error: no match for ‘operator>>’ (operand types are ‘std::istream {aka std::basic_istream<char>}’ and ‘int*’)
cin>>age[vCount];
^

std::ofstream not able to write std::string to file

Solved the problem already when checking a last time before posting this, but it looked somewhat evil to debug (at least for a newbie), so I'll post it anyway - feel free to delete.
The problem was that in the marked line below, ofstream seemed unable to write a simple string; the templating appeared to be the problem:
template <typename T>
void appendVectorToCSV(const std::string& header, std::vector<T> row,
const std::string& outfilename){
std::ofstream fout(outfilename);
fout << header;// << ","; /* The error line 80 */
...
This gives the error:
varUtils.hpp: In function ‘void appendVectorToCSV(std::string&, const std::vector<_RealType>&, const string&)’:
varUtils.hpp:80:10: error: no match for ‘operator<<’ (operand types are ‘std::ofstream {aka std::basic_ofstream<char>}’ and ‘std::string {aka std::basic_string<char>}’)
fout << header;// << ",";
^
varUtils.hpp:80:10: note: candidates are:
...
/usr/include/c++/4.8/complex:524:5: note: template<class _Tp, class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::complex<_Tp>&)
operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x)
^
/usr/include/c++/4.8/complex:524:5: note: template argument deduction/substitution failed:
...
varUtils.hpp:80:13: note: ‘std::ofstream {aka std::basic_ofstream<char>}’ is not derived from ‘std::basic_ostream<_CharT, _Traits>’
fout << header;// << ",";
^
So, solution:
A missing header.
#include <iostream>
was already there, but not
#include <fstream>

String::copy error

I have the following code and get the error later described how do i correct this?
The objective behind is to parse the following sentence into variables :
temp1+temp2=10
Code:
int main()
{
string line,var1;
int limit,len;
//some code here
// parse function declarartion :string parse(string ,char ,int &)
f1>>line;
len=line.length();
var1=parse(line,'+',limit);
line.copy(line,len-limit,limit);
//some code here
}
Error:
alice.cpp: In function ‘int main()’:
alice.cpp:65:40: error: no matching function for call to ‘std::basic_string<char>::copy(std::string&, int, int&)’
alicebob.cpp:65:40: note: candidate is:
/usr/include/c++/4.6/bits/basic_string.tcc:724:5: note: std::basic_string<_CharT, _Traits, _Alloc>::size_type std::basic_string<_CharT, _Traits, _Alloc>::copy(_CharT*, std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type) const [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc>::size_type = unsigned int]
/usr/include/c++/4.6/bits/basic_string.tcc:724:5: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘char*’
If you just want to copy a substring into another string, why don't you use substr() instead?
int main()
{
std::string line("ceva5");
std::string var1;
int limit = 1,len;
//some code here
// parse function declarartion :string parse(string ,char ,int &)
// f1>>line;
len=line.length();
//
// var1=parse(line,'+',limit);
line = line.substr(limit, len-limit);
//some code here
std::cout << line << std::endl;
}
This should do what you want.
EDIT: I have not implemented your function but changed the code to work as string's copy().
Here is the explain: http://www.cplusplus.com/reference/string/string/copy/ ,The first arg is char*, So,Accroding to your question,I think your code should be
line.copy((char *)line.c_str(),len-limit,limit); // wrong code, lost the const
but this code is dangerous,Because std::copy()'s first arg is an array of characters to store the string 's substring, So,I think you code has something wrong.
Here is simple code:
std::string test1 = "test1";
char buffer[10] = {0};
test1.copy(buffer,2,3);
std::cout << "buffer is: " << buffer << std::endl;
and the output is :"buffer is: t1".

Formatting CSV files in C++

I am trying to take a simple CSV file, split it line-by-line, and print it to the console. Currently I am getting an error when compiling and want to know if I am missing something obvious.
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
int main(int argc , char** argv) {
std::string line;
std::ifstream infile(argv[1]);
if (infile) {
while (getline(infile, line)) {
std::istringstream ss(line);
std::string token;
while(std::getline(ss, token, ",")) {
std::cout << token << "\n";
}
}
}
infile.close();
return 0;
}
The error I am getting is as follows.
csv.cpp: In function 'int main(int, char**)':
csv.cpp:41:46: error: no matching function for call to 'getline(std::istringstream&,
std::string&, const char [2])'
csv.cpp:41:46: note: candidates are:
In file included from /usr/include/c++/4.7/string:55:0,
from /usr/include/c++/4.7/bits/locale_classes.h:42,
from /usr/include/c++/4.7/bits/ios_base.h:43,
from /usr/include/c++/4.7/ios:43,
from /usr/include/c++/4.7/istream:40,
from /usr/include/c++/4.7/fstream:40,
from csv.cpp:21:
/usr/include/c++/4.7/bits/basic_string.tcc:1070:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&, _CharT)
/usr/include/c++/4.7/bits/basic_string.tcc:1070:5: note: template argument deduction/substitution failed:
csv.cpp:41:46: note: deduced conflicting types for parameter '_CharT' ('char' and 'const char*')
In file included from /usr/include/c++/4.7/string:54:0,
from /usr/include/c++/4.7/bits/locale_classes.h:42,
from /usr/include/c++/4.7/bits/ios_base.h:43,
from /usr/include/c++/4.7/ios:43,
from /usr/include/c++/4.7/istream:40,
from /usr/include/c++/4.7/fstream:40,
from csv.cpp:21:
/usr/include/c++/4.7/bits/basic_string.h:2792:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::getline(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.7/bits/basic_string.h:2792:5: note: template argument deduction/substitution failed:
csv.cpp:41:46: note: candidate expects 2 arguments, 3 provided
The third parameter of getline is a char, not a char*. Make it getline(ss, token, ',') - note single quotes.
Oh, and beware CSV fields "like"",""this" (in case you wonder, this is a single field with the value of like","this). There's more to CSV syntax than meets the eye.
Perhaps you should use a library for CSV munging... perhaps this question is useful.

Why does istream_iterator<string>(ifstream("test.txt")) cause an error?

I have tried to write a code to read strings from file named "test.txt" and write the strings to standard output. The code below works well:
int main()
{
using namespace std;
ifstream file("test.txt");
copy(istream_iterator<string>(file),
istream_iterator<string>(),
ostream_iterator<string>(cout, " "));
}
However, with this modification, the code no longer compiles:
int main()
{
using namespace std;
copy(istream_iterator<string>(ifstream("test.txt")), // <-- Error here
istream_iterator<string>(),
ostream_iterator<string>(cout, " "));
}
Why doesn't this version compile?
The compiler I used is g++4.6.2, and the error as below:
ex11-16.cpp:16:65: error: no matching function for call to 'std::istream_iterator<std::basic_string<char> >::istream_iterator(std::ifstream)'
ex11-16.cpp:16:65: note: candidates are:
.../bits/stream_iterator.h:72:7: note: std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(const std::istream_iterator<_Tp, _CharT, _Traits, _Dist>&) [with _Tp = std::basic_string<char>, _CharT = char, _Traits = std::char_traits<char>, _Dist = int, std::istream_iterator<_Tp, _CharT, _Traits, _Dist> = std::istream_iterator<std::basic_string<char> >]
.../bits/stream_iterator.h:72:7: note: no known conversion for argument 1 from 'std::ifstream {aka std::basic_ifstream<char>}' to 'const std::istream_iterator<std::basic_string<char> >&'
.../bits/stream_iterator.h:68:7: note: std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type&) [with _Tp = std::basic_string<char>, _CharT = char, _Traits = std::char_traits<char>, _Dist = int, std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type = std::basic_istream<char>]
.../bits/stream_iterator.h:68:7: note: no known conversion for argument 1 from 'std::ifstream {aka std::basic_ifstream<char>}' to 'std::istream_iterator<std::basic_string<char> >::istream_type& {aka std::basic_istream<char>&}'
.../bits/stream_iterator.h:64:26: note: std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator() [with _Tp = std::basic_string<char>, _CharT = char, _Traits = std::char_traits<char>, _Dist = int]
.../bits/stream_iterator.h:64:26: note: candidate expects 0 arguments, 1 provided
There are (I believe) two errors here:
(1) You need to put quotations around test.txt:
istream_iterator<string>(ifstream("test.txt"), ... );
(2) istream_iterator's constructor takes in an istream& (that is, an lvalue reference to a stream). Consequently, the stream that you pass in has to be an lvalue. However, passing in ifstream("test.txt") passes in a temporary object of type ifstream, which is an rvalue rather than an lvalue. This is the same reason that you can't do this:
int function(int& x) {
x++;
}
int main() {
function(137); // Error - 137 is an rvalue, but lvalue is needed.
}
Hope this helps!