I started having C++ classes at university last week. At the moment I just know some C language which makes me a little confused when learning C++. I have this exercise that says:
"Write and use the fstream library to read a text file. The function should write on the screen each text line read of the file (with spaces)."
I wrote the code below that can write the line but without spaces. I've also heard about getline, but I don't know how to use it, the compiler allways says "no matching function for call to getline".
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
file_read(){
ifstream origem;
origem.open("ficheiro.txt");
if (!origem) {
cerr << "Error" << endl;
return -1;
}
char outp[100];
while(!origem.eof() ){
origem >> outp;
cout << outp;
}
return 0;
}
For example: If i have in the ficcheiro.txt"My dog has a bone", the programm will write it like "Mydoghasabone"
So with the getline I tried this:
...
ifstream origem;
origem.open("ficheiro.txt");
if (!origem) {
cerr << "Error" << endl;
return -1;
}
char outp[100];
getline(origem, outp);
origem >> outp;
cout << outp;
return 0;
}
The compiler said:[Error] no matching function for call to 'getline(std::ifstream&, std::char [100])'
My problem is just to read the file including the spaces!
I'm also having some trouble learning C++, I started learning 'Classes' and using the CMD and I don't even know what I'm learning. Do you know where can I learn C++ in a more understandable way?
Try this
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int file_read()
{
ifstream origem;
origem.open("ficheiro.txt");
if (!origem) {
cerr << "Error" << endl;
return -1;
}
char outp[100];
while( origem.getline(outp,100) )
cout << outp;
return 0;
}
int main()
{
file_read();
}
The compiler said:[Error] no matching function for call to 'getline(std::ifstream&, std::char [100])'
if you want to use getline() change outp from char to string like
string outp;
while( getline(origem,outp))
cout << outp;
Because getline() is for string.
Related
I want to skip blank line when readhing a file.
I've tried if(buffer == "\n") and if(buffer.empty()), but it not work. I did like this:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream file_pointer;
file_pointer.open("rules.txt", ios::in);
if(!file_pointer.is_open())
{
cout << "failed to read rule file." << endl;
return 0;
}
string buffer;
while(getline(file_pointer, buffer))
{
if(buffer.empty())
{
continue;
}
if(buffer == "\n")
{
continue;
}
cout << buffer << endl;
}
file_pointer.close();
return 0;
}
The problem is that a “blank” line need not be “empty”.
#include <algorithm> // std::any_of
#include <cctype> // std::isspace
#include <fstream>
#include <iostream>
//using namespace std;
bool is_blank( const std::string & s )
{
return std::all_of( s.begin(), s.end(), []( unsigned char c )
{
return std::isspace( c );
} );
}
int main()
{
std::ifstream rules_file("rules.txt");
if(!rules_file)
{
std::cerr << "failed to read rule file." << endl;
return 1;
}
std::string line;
while(getline(rules_file, line))
{
if(is_blank(line))
{
continue;
}
std::cout << line << "\n";
}
return 0;
}
A few notes.
Get used to writing std:: infront of things from the Standard Library. Importing everything en masse with using namespace std is almost always a bad idea.
C++ file streams are not pointers. Moreover, be descriptive with your names! It makes reading your code easier for your future self. Honest!
Open a file at the file stream object creation. Let it close at object destruction (which you did).
Report errors to standard error and signal program failure by returning 1 from main().
Print normal output to standard output and signal program success by returing 0 from main().
It is likely that std::any_of() and lambdas are probably not something you have studied yet. There are all kinds of ways that is_blank() could have been written:
bool is_blank( const std::string & s )
{
for (char c : s)
if (!std::isspace( (unsigned char)c ))
return false;
return true;
}
Or:
bool is_blank( const std::string & s )
{
return s.find_first_not_of( " \f\n\r\t\v" ) == s.npos;
}
Etc.
The reason that the checking for newline didn’t work is that getline() removes the newline character(s) from the input stream but does not store it/them in the target string. (Unlike fgets(), which does store the newline so that you know that you got an entire line of text from the user.) C++ is much more convenient in this respect.
Overall, you look to be off to a good start. I really recommend you make yourself familiar with a good reference and look up the functions you wish to use. Even now, after 30+ years of this, I still look them up when I use them.
One way to find good stuff is to just type the name of the function in at Google: “cppreference.com getline” will take you to the ur-reference site.
https://en.cppreference.com — “the” C and C++ reference site
https://cplusplus.com/reference/ — also good, often an easier read for beginners than cppreference.com
https://www.learncpp.com/ — a good site to learn how to do things in C++
You can skip blank lines when reading a file in C++ by using the getline() function and checking the length of the resulting string. Here is an example of how you can do this:
#include <fstream>
#include <string>
int main() {
std::ifstream file("myfile.txt");
std::string line;
while (std::getline(file, line)) {
if (line.length() == 0) { // check if the line is empty
continue; // skip the iteration
}
// process the non-empty line
}
file.close();
return 0;
}
You can also use the std::stringstream class to skip blank lines, here is an example:
#include <fstream>
#include <sstream>
#include <string>
int main() {
std::ifstream file("myfile.txt");
std::string line;
while (std::getline(file, line)) {
std::stringstream ss(line);
if (ss >> line) { // check if the line is empty
// process the non-empty line
}
}
file.close();
return 0;
}
(1) Here's a solution using the ws manipulator in conjunction with the getline function to ignore leading white-space while reading lines of input from the stream. ws is a manipulator that skips whitespace characters (demo).
#include <iostream>
#include <string>
int main()
{
using namespace std;
string line;
while (getline(cin >> ws, line))
cout << "got: " << line << endl;
return 0;
}
Note that the spaces are removed even if the line is not empty (" abc " becomes "abc ".
(2) If this is a problem, you could use:
while (getline(cin, line))
if (line.find_first_not_of(" \t") != string::npos)
cout << "got: " << line << endl;
Here is what I got so far:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int characterList = 0;
char* dynamo = new char[1000];
char* buffer = dynamo;
ifstream input("wordlist.txt");
if (input.is_open())
{
input >> dynamo[characterList];
while (input.eof())
{
characterList++;
input >> dynamo[characterList];
cout << dynamo[characterList];
}
}
else
{
cout << "File not opened" << endl;
}
return;
}
I'm a beginner so I do apologize if this looks like terrible coding practice. I created a text file with a quote from Bill Cosby that I'm trying to read one word at a time. The quote is "I don't know the key to success, but the key to failure is trying to please everybody." I'm trying to read one word at a time from a text document ignoring punctuation. I know there are a lot of questions similar to this, but they are using code that I have not learned so I'm sorry for having a repeating question. I have not learned getline (I used cin.getline) and #include <string>.
Edit: I forgot to mention, so I'm sorry for not doing so earlier, but I'm studying dynamic memory allocation which is why I'm using the new char[1000].
I'd suggest you to use std::string instead of manually allocating buffers on the heap with new[] and trying to read text manually from the file into those buffers (and don't forget to free the buffer with proper delete[] calls!).
C++ input stream classes like std::ifstream can simply read text into std::string instances thanks to a proper overload of operator<<.
The syntax is as simple as:
string word;
while (inFile >> word)
{
cout << word << endl;
}
Here's a complete compilable sample code for you to experiment and learn:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream inFile("test.txt");
if (inFile.is_open())
{
string word;
while (inFile >> word)
{
cout << word << endl;
}
}
else
{
cout << "Can't open file." << endl;
}
}
This is the output I got on a test text file having the content specified in your question:
I
don't
know
the
key
to
success,
but
the
key
to
failure
is
trying
to
please
everybody.
NOTE
Of course, once you have your words read into a std::string instance, you can store them in a container like std::vector<std::string>, using its push_back() method.
I would do something like this:
#include <iostream>
#include <string>
#include <fstream>
int main() {
std::string array[6];
std::ifstream infile("Team.txt");
std::string line;
int i = 0;
while (std::getline(infile, line)) {
array[i++] = line;
}
return 0;
}
based on this answer.
Here, we assume we have to read 6 lines from the file "Team.txt". We use std:::getline() and we put inside a while so that we read all the file.
At every iteration, line holds the current line of the file read. Inside the body we store it in array[i].
I am trying to bind input stream with a file stream , I hope that input something from input stream and then automatic flush to the file stream
It does not work...I enter something from keyboard , outfile is still empty
#include <iostream>
#include <fstream>
#include <stdexcept>
using namespace std;
int main(int argc, char const *argv[])
{
ofstream outfile("outfile" , ofstream::app | ofstream::out);
if(!outfile)
throw runtime_error("Open the file error");
ostream * old_tie = cin.tie();//get old tie
cin.tie(0);//unbind from old tie
cin.tie(&outfile);//bind new ostream
string temp;
while(cin >> temp)
{
if(temp == ".")//stop input
break;
}
cin.tie(0);
cin.tie(old_tie);// recovery old tie
return 0;
}
Your program is too complicated and is misusing tie(). Try the following:
#include <iostream>
#include <fstream>
int main() {
using namespace std;
ofstream outfile("outfile" , ofstream::app | ofstream::out);
if(!outfile) {
cerr << "Open the file error";
return 1;
}
char data(0);
while(data != '.') {
cin.get(data);
cin.clear(); // Prevents EOF errors;
outfile << data;
}
return 0;
}
It reads char by char until it finds a .
Errors:
why make throw exception if you don't catch it...
close file please
do you put data from file to temp and go through it to find "." and
end program?
Why do you use pointer for old_tie use it for the first ofstream file
like this ofstream * file.
fix if statement and break
include string library -- //This might solve your problem
what is filename??
is tie(0) function to unbind?
//EDIT
Explanation:
once you find first period with find_first_of function you create a substr and copy it into outfile. The Solution is so efficent and works every time. The logic is as simple as it can get. Don't use unnecessary functions and initialize unnecessary variables because it is more complex and more prone to errors when you have too many variables.
Solution: - No need for cin.tie()
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char const *argv[])
{
ofstream outfile("outfile" , ofstream::app | ofstream::out);
string s;
getline(cin, s);
int i = s.find_first_of(".");
if(i!=std::string::npos)
{
s = s.substr(0, i);
outfile << s;
}
else
{
cout << "No periods found" << endl;
}
}
Compiled code - http://ideone.com/ooj1ej
If this needs explanation please ask questions in comments below.
#include <iostream>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <string>
#include <iomanip>
#include <fstream>
#include <stdio.h>
using namespace std;
int main()
{
ifstream file;
string filename;
char character;
int letters[153] = {};
cout << "Enter text file name: ";
cin >> filename;
file.open(filename.c_str());
if (! file.is_open())
{
cout << "Error opening file. Check file name. Exiting program." << endl;
exit(0);
}
while (file.peek() != EOF)
{
file >> character;
if(!file.fail())
{
letters[static_cast<int>(character)]++;
}
}
for (int i = 0; i <= 153; i++)
{
if (letters[i] > 0)
{
cout << static_cast<char>(i) << " " << letters[i] << endl;
}
}
exit(0);
}
#endif
Hi everyone, my current code counts the frequency of each letter from a text file. However, it does not count the number of blank spaces. Is there a simple way to printout the number of blank spaces in a .txt file?
Also, how come when I'm trying to access a vector item, I run into a seg fault?
For example, if I use:
cout << " " + letters[i] << endl;, it displays a segfault. Any ideas?
Thank you so much.
By default, iostreams formatted input extraction operations (those using >>) skip past all whitespace characters to get to the first non-whitespace character. Perhaps surprisingly, this includes the extraction operator for char. In order to consider whitespace characters as characters to be processed as usual, you should alter use the noskipws manipulator before processing:
file << std::noskipws;
Don't forget to set it back on later:
file << std::skipws;
What if you're one of those crazy people who wants to make a function that leaves this aspect (or in even all aspects) of the stream state as it was before it exits? Naturally, C++ provides a discouragingly ugly way to achieve this:
std::ios_base::fmtflags old_fmt = file.flags();
file << std::noskipws;
... // Do your thang
file.flags(old_fmt);
I'm only posting this as an alternative way of doing what you're apparently trying. This uses the same lookup table approach you use in your code, but uses an istreambuf_iterator for slurping unformatted (and unfiltered) raw characters out of the stream buffer directly.
#include <iostream>
#include <fstream>
#include <iterator>
#include <climits>
int main(int argc, char *argv[])
{
if (argc < 2)
return EXIT_FAILURE;
std::ifstream inf(argv[1]);
std::istreambuf_iterator<char> it_inf(inf), it_eof;
unsigned int arr[1 << CHAR_BIT] = {};
std::for_each(it_inf, it_eof,
[&arr](char c){ ++arr[static_cast<unsigned int>(c)];});
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
{
if (std::isprint(i) && arr[i])
std::cout << static_cast<char>(i) << ':' << arr[i] << std::endl;
}
return 0;
}
Executing this on the very source code file itself, (i.e. the code above) generates the following:
:124
#:4
&:3
':2
(:13
):13
*:1
+:4
,:4
/:1
0:3
1:2
2:1
::13
;:10
<:19
=:2
>:7
A:2
B:1
C:1
E:2
F:1
H:1
I:3
L:1
R:2
T:2
U:1
X:1
[:8
]:8
_:10
a:27
b:1
c:19
d:13
e:20
f:15
g:6
h:5
i:42
l:6
m:6
n:22
o:10
p:1
r:37
s:20
t:34
u:10
v:2
z:2
{:4
}:4
Just a different way to do it, but hopefully it is clear that usually the C++ standard library offers up elegant ways to do what you desire if you dig deep enough to find whats in there. Wishing you good luck.
I need to do this:
$ ./compiledprog.x < inputValues > outputFile
so that I read from the file inputValues which for our case might just be \n separated int values or whatever. Then anything printf()'d goes into outputFile. But what's this called, technically speaking, and where can I find a demo of doing this.
As noted by others, it's input/output redirection.
Here's an example program that would copy the standard input to the standard output, in your example copy the contents from inputValues to outputFile. Implement whatever logic you want in the program.
#include <unistd.h>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::cerr;
#include <string>
using std::string;
int main(int argc, char** argv) {
string str;
// If cin is a terminal, print program usage
if (isatty(fileno(stdin))) {
cerr << "Usage: " << argv[0] << " < inputValues > outputFile" << endl;
return 1;
}
while( getline(cin, str) ) // As noted by Seth Carnegie, could also use cin >> str;
cout << str << endl;
return 0;
}
Note: this is quick and dirty code, which expects a well behaved file as input. A more detailed error checking could be added.
This is called I/O redirection.