c++ getline() function - c++

I dont' quite understand how this function works.
I wrote a simple programming reading one line with getline().
for example:
ifstream in;
in.open("example.txt");
string line;
getline(in, line);
cout << line << endl;
When I tried to run this program I received an error message like this.
`assign1_2.cpp:33:20: error: cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*' for argument '1' to 'int atoi(const char*)'
I simply don't understand what went wrong here. Please help!. I am a newbie to c++.

You didn't show the code with the error, but the error says you tried to call atoi with an argument of type std::string. atoi takes a C string (man atoi), so you need to call it like:
atoi( line.c_str() );

Which function are you trying to call? The gnu 'C' getline function or istream::getline?
istream::getline has the following signature
istream& istream::getline( char* str, streamsize count)
istream& istream::getline( char* str, streamsize count, char delim )
So you call should be something like:
char* buf[1000]
in.getline( buf, 1000 );

Change string line to char line[2000]
like so:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char line[2000];
fstream in;
in.open("example.txt",ios::in);
while(!in.eof())
{
in.getline(line,2000);
}
in.close();
cout <<line;
cout <<endl;
return 0;
}

Related

Why can't I provide a string argument to printw in ncurses? [duplicate]

This question already has answers here:
How to convert a std::string to const char* or char*
(11 answers)
Closed 3 years ago.
For an application that I'm writing, I have a string type variable that I want to display within an ncurses window:
#include <iostream>
#include <ncurses.h>
#include <string>
int main(){
std::string mystring = "A sample string\n";
// Entering the ncurses window
initscr();
printw(mystring);
getch();
endwin();
}
which throws the following error at compilation:
test_app.cpp: In function ‘int main()’:
test_app.cpp:12:18: error: cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const char*’ for argument ‘1’ to ‘int printw(const char*, ...)’
printw(mystring);
Where am I going wrong? How can I rectify this?
Some key concepts in c++:
A string literal declaration (aka "this is a string literal") has a type const char[N], where N is the size of the string, including the null terminator.
std::string != const char[]
However, a std::string can be constructed with a const char[] using this constructor (found here):
basic_string( const CharT* s,
const Allocator& alloc = Allocator() );
Where CharT is your implementation specific char equivalent.
Now, notice how printw takes a const char*. You aren't passing a const char * to printw, you're passing a std::string, and they aren't implicitly convertible to a const char *.
We have two options to solve your problem...
1) Store the string as a char[] (aka char *):
#include <iostream>
#include <ncurses.h>
#include <string>
int main(){
char mystring[] = "A sample string\n"; // Can decay to a char * implicitly.
// Entering the ncurses window
initscr();
printw(mystring);
getch();
endwin();
}
2) Get a representation of the std::string as a char *:
#include <iostream>
#include <ncurses.h>
#include <string>
int main(){
std::string mystring = "A sample string\n";
// Entering the ncurses window
initscr();
// Since c++ 11, mystring.data() is required to return a null-terminated char *.
// If c++ version < c++11, use mystring.c_str().
printw(mystring.data());
getch();
endwin();
}

Error invalid user define conversion

#include <iostream>
#include <sstream>
#include <fstream>
#include <string.h>
using namespace std;
int main(int argc, char* argv[])
{
if(argc != 3)
cout<< "Error! Not enough file!"<<endl;
char** words = new char* [10];
char** page = new char* [10];
string line;
char* key = "<-1>";
ifstream input (argv[1]);
while(strcmp(std::getline(input, line), key) != 0)
{
}
return 0;
}
So when I tried to run this(of course it is not finished). The compiler keeps giving me the error that says
/home/ds/DataStructuresRepo/Project2/untitled/main.cpp:17: error: invalid user-defined conversion from 'std::basic_istream<char>' to 'const char*' [-fpermissive]
while(strcmp(std::getline(input, line), key) != 0)
^
What am I doing wrong?
std::getline returns a std::basic_istream&. It writes what it reads into the line you're passing in. strcmp takes two const char*s. You cannot just pass the result of the first into the second - those types aren't convertible (hence the error about no conversion from std::basic_istream<char> to const char*).
Since you're getting a std::string anyway, you can just use it's operator== directly:
while (std::getline(input, line) && line != key)
{
}
What you're doing wrong is that you're passing an istream (the return value of getline) to strcmp which expects a char*.

fstream .open and appending .txt or .dat to filename

This has worked fine on some compilers... Is there a way of doing this were it will just work without it being a problem with different compilers on c++11 or c++14?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void save_file() {
string file;
ofstream os;
cout << "Save As: ";
getline(cin, file, '\n');
os.open(file + ".dat");
//rest of code
}
error: no viable conversion from 'basic_string, std::allocator >' to 'const char *'
So I google it, found some answers, or in this case, canswers (cancers), tried
os.open(file.c_str() + ".dat");
error: invalid operands to binary expression ('const char *' and 'const char *')
Accoding to the C++11 standard 27.9.1.10 one of the constructors for a basic_ofstream is:
explicit basic_ofstream(const string& s, ios_base::openmode mode = ios_base::out);
This means that any standard compliant compiler should be able to compile:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string file = "temp";
ofstream os;
os.open(file + ".dat");
}
Live Example
Don't forget that you need to use the -std=c++11 or higher flag when compiling.
"+" operator cannot be used for the C-style strings. Try this:
string name = file+".dat";
os.open(name.c_str());
You create the std::string type as a concatenation in c++ style and then pass it to open as a c string.
In C++11, os.open( file + ".dat" ) works just fine. Pre C++11, there was no std::ofstream::open which took a string, so you had to write os.open( (file + ".dat").c_str() ). Note the parentheses and where the .c_str() goes---you have to concatenate with the std::string first, and only call .c_str() on the results.

no matching function for call to 'fscanf'

I'm trying to read a time from a file for example (12:00 A)
I need to read in all three parts. Here is what I have.
#include <iostream>
#include <fstream>
#include <stdio.h>
using namespace std;
int main()
{
string name, filename;
ifstream inputFile;
cout << "What is the name of the file to be provessed ";
cin >> filename;
inputFile.open(filename.c_str());
getline(inputFile, name);
fscanf (inputFile, "%d:%d %c", &startH, &startM, &startAP);
fscanf (inputFile, "%d:%d %c", &endH, &endM, &endAP);
inputFile >> payRate;
I'm getting the error from the title and I'm not sure what I'm doing wrong.
Function fscanf is a standard C function that is declared in header <cstdio> the following way (I will show how the function is declared in header <stdio.h> in C. in fact the same declaration except the keyword restrict is used in C++)
int fscanf(FILE * restrict stream,
const char * restrict format, ...);
As you can see there is no parameter of type std::ifstream
So the compiler issues the error because it is unable to find a function with name fscanf that has the first parameter of type std::ifstream and at the same time it can not implicitly convert an object of type std::ifstream to a pointer of type FILE *
You should not mix C++ stream functions with C stream functions.

Using Strncmp with a string from a file

Goodnight to everyone, I'm trying to parse an .h file so I can have a small console frontend to change its values, but when I try to use strncmp with a string read from a file and a string defined in code to compare with the file string I get a strange error from the compiler that I cant resolve, here is my source code:
//Test to basic file operations
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;
int main (void){
string line;
ifstream myfile("PIDconfig.h");
if(myfile.is_open()){ //if file is open
while(myfile.good()){
getline(myfile, line);
if(strncmp(line, "static float", 12) == 0){
cout << line << endl;
}
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
And the error that I get:
tiago#tiago-laptop:~$ g++ file.cpp
file.cpp: In function ‘int main()’:
file.cpp:17: error: cannot convert ‘std::string’ to ‘const char*’ for argument ‘1’ to ‘int strncmp(const char*, const char*, size_t)’
If some one could help me I would be very glad, I have already searched StackOverflow but I didnt found anyone with the same problem, almost all strncmp problems use arrays to store their strings and as far as I went, no one was having a problem using it and file I/O.
std::string overloads operator==. You can simply compare two std::string object using ==.
Also, your input loop is incorrect.
the problem is that strncmp() function overloaded for strncmp(const char*, const char*, int)
but you want to call it by strncmp(string, string, size_t)
you must convert string to const char* with
c_str()
for example
string str = "Hello";
char * arr = str.c_str().
you get it?
if(strncmp(line.c_str(), "static float", 12) == 0){
should work
The problem is that you're reading data from the file as a C++ string, and the strncmp function works on C style strings. To fix this, you can either extract a raw C style string from the C++ string using .c_str(), or you can use the C++ string's .compare function:
line.compare(0, 12, "static float")