Using Strncmp with a string from a file - c++

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

Related

Can't write to ostream in gnu linux c++ error: invalid operands of types ofstream and ‘const char [2]’ to binary ‘operator

Can't compile this small code on Linux:
#include <fstream>
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(){
char fileName[512];
sprintf(fileName, "test");
ofstream iriFile(string(fileName));
iriFile<<",";
return 0;
}
I am compiling like this: g++ test.cpp and am getting this:
test.cpp:12:11: error: invalid operands of types
‘std::ofstream(std::__cxx11::string) {aka
std::basic_ofstream(std::__cxx11::basic_string)}’ and
‘const char [2]’ to binary ‘operator<<’ iriFile<<",";
What might be the reason?
Ok, the solution is to remove implicit string() creation:
string sFileName(fileName)
ofstream iriFile(sFileName);
First of all you do not need to explicitly convert const char * to std::string there is std::ifstream constructor for it:
std::ofstream iriFile(fileName);
but if you want to be extra safe and verbose use proper C++ then:
std::ofstream iriFile( static_cast<std::string>(fileName) );
not C style cast.
As you pointed out, removing the explicit string creation fixes it.
It could be worth to add that this can also be fixed for types with explicit constructors by using list initialization, like so:
ofstream iriFile(string{sFileName});

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.

Errors when putting a string variable into system()

I'm having trouble getting system() to run a command in a string variable.
ostringstream convert;
convert << getSeconds(hours);
string seconds = convert.str(); /* converts the output of 'getSeconds()' into
a string and puts it into 'seconds' */
string cmd = "shutdown /s /t " + seconds;
system(cmd);
getSeconds() just takes an int in hours, converts it into seconds and returns an int in seconds. Everything runs fine, no errors, until it reaches system(cmd);. The compiler then spits out this error:
error: cannot convert 'std::string {aka std::basic_string<char>}' to
'const char*' for argument '1' to 'int system(const char*)'
Here are my includes:
#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>
I know this has already been answered by comments, but not really explained:
The system function is a C function. It does not "understand" C++ style strings. For that, you will need to use the c_str() function. In other words, you need system(cmd.c_str());.
This applies to a large number of C style functions that are still available in C++, since one of the main features of C++ is that you can still use traditional C-code (for the most part) in C++. So, the same applies to almost any C style function that takes a string - printf("cmd=%s", cmd.c_str()); would print what your command is.
It would be possibe to write your own wrapper function:
int system(const std::string &cmd)
{
return system(cmd.c_str());
}
Now, the rest of your code can use system with a regular C++ style string.
system takes a C string not a std::string, so you must call the c_str function first.
system(cmd.c_str());

C ++ ifstream I/O?

I'm experimenting with C++ file I/O, specifically fstream. I wrote the following bit of code and as of right now it is telling me that there is no getline member function. I have been told (and insisted still) that there is a member function getline. Anybody know how to use the getline member function for fstream? Or perhaps another way of getting one line at a time from a file? I'm taking in two file arguments on the command line with unique file extensions.
./fileIO foo.code foo.encode
#include <fstream>
#include <iostream>
#include <queue>
#include <iomanip>
#include <map>
#include <string>
#include <cassert>
using namespace std;
int main( int argc, char *argv[] )
{
// convert the C-style command line parameter to a C++-style string,
// so that we can do concatenation on it
assert( argc == 2 );
const string foo = argv[1];
string line;string codeFileName = foo + ".code";
ifstream codeFile( codeFileName.c_str(), ios::in );
if( codeFile.is_open())
{
getline(codeFileName, line);
cout << line << endl;
}
else cout << "Unable to open file" << endl;
return 0;
}
getline(codeFileName, line);
Should be
getline(codeFile, line);
You're passing in the file name, not the stream.
By the way, the getline you're using is a free function, not a member function. In fact, one should avoid the member function getline. It's much harder to use, and harkens back to a day when there was no string in the standard library.
Typo
getline(codeFileName, line);
should be
getline(codeFile, line);
I guess the lesson is you have to learn how to interpret compiler error messages. We all make certain kinds of mistakes and learn the compiler errors they tend to generate.

c++ getline() function

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;
}