Reading a text file into a 2d vector. C++ - c++

I have a 9x8 textfile with no spaces in between the characters. How can I open this text and read it and put it into a 2d vector with characters? What i have so far is this...
#include <iostream>
#include <fstream>
std::ifstream in_str("inputtxt.txt");
std::string line;
while (std::getline(in_str,line))
{}
std::vector<std::vector<std::string>> replacements;
I'm still trying to figure out how to set it up still and adding the file into the vector

How about something like this:
std::array<std::array<char, 8>, 9> characters;
std::string line;
size_t pos = 0;
while (std::getline(in_str, line))
{
std::copy(std::begin(line), std::end(line),
std::begin(characters[pos++]);
}
This will read lines from the input file, and copy all characters into the array.
Note: The above code have no error handling, no checks for the input actually being valid, and most importantly of all there's no checks for going out of bounds of the arrays. If there are more lines of input than expected, or more characters per line than expected, you will get undefined behavior.
Another possible solution, if you're happy to store strings (which of course can be accessed using array-indexing syntax like arrays/vectors), you could do e.g.
std::array<std::string, 9> characters;
std::copy(std::istream_iterator<std::string>(in_str),
std::istream_iterator<std::string>(),
std::begin(characters));
Same disclaimer as for the first code sample applies here too.

Related

How to read integers from a line in C++?

I want to read integers in a line from a file.
For example the line is : 3/2+5-5
I think I need to use >>, but it stopped because of the characters;
I also try to use other functions, but they are all for characters.
As the #Fang already pointed out, there's no easy way to do it. You can read the whole line and tokenize it via the following code:
std::ifstream f("file.txt");
std::string line;
std::getline(f, line);
std::vector<std::string> integers;
boost::split(integers, line, boost::algorithm::is_any_of("+-*/"), boost::token_compress_on);
// Then convert strings from the integers container to ints

storing text to string from a file that contains spaces

So I've been doing algorithms in C++ for about 3 months now as a hobby. I've never had a problem I couldn't solve by googleing up until now. I'm trying to read from a text file that will be converted into a hash table, but when i try and capture the data from a file it ends at a space. here's the code
#include <iostream>
#include <fstream>
int main()
{
using namespace std;
ifstream file("this.hash");
file >> noskipws;
string thing;
file >> thing;
cout << thing << endl;
return 0;
}
I'm aware of the noskipws flag i just don't know how to properly implement it
When using the formatted input operator for std::string it always stops at what the stream considers to be whitespace. Using the std::locale's character classification facet std::ctype<char> you can redefine what space means. It's a bit involved, though.
If you want to read up to a specific separator, you can use std::getline(), possibly specifying the separator you are interested in, e.g.:
std::string value;
if (std::getline(in, value, ',')) { ... }
reads character until it finds a comma or the end of the file is reached and stores the characters up to the separator in value.
If you just want to read the entire file, one way to do is to use
std::ifstream in(file.c_str());
std::string all((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
I think the best tool for what you're trying to do is get, getline or read. Now those all use char buffers rather than std::strings, so need a bit more thought, but they're quite straightforward really. (edit: std::getline( file, string ), as pointed out by Dietmar Kühl, uses c++ strings rather than character buffers, so I would actually recommend that. Then you won't need to worry about maximum line lengths)
Here's an example which will loop through the entire file:
#include <iostream>
int main () {
char buffer[1024]; // line length is limited to 1023 bytes
std::ifstream file( "this.hash" );
while( file.good( ) ) {
file.getline( buffer, sizeof( buffer ) );
std::string line( buffer ); // convert to c++ string for convenience
// do something with the line
}
return 0;
}
(note that line length is limited to 1023 bytes, and if a line is longer it will be broken into 2 reads. When it's a true newline, you'll see a \n character at the end of the string)
Of course, if you a maximum length for your file in advance, you can just set the buffer accordingly and do away with the loop. If the buffer needs to be very big (more than a couple of kilobytes), you should probably use new char[size] and delete[] instead of the static array, to avoid stack overflows.
and here's a reference page: http://www.cplusplus.com/reference/fstream/ifstream/

Having trouble reading file into vector

I have a file that has three ints on three rows. It looks like this:
000
001
010
And I'm trying to read each integer into the vector positions but I don't know if I'm doing it right. Here is my code:
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> numbers;
std::fstream out("out.txt");
std::copy(std::ostreambuf_iterator<int>(out.rdbuf()),
std::ostreambuf_iterator<int>(), std::back_inserter(numbers));
}
What am I doing wrong here? I'm getting a "no matching function call" error on the line where I do the copy.
You're using wrong iterator.
You need istreambuf_iterator, not ostreambuf_iterator:
std::copy(std::istreambuf_iterator<int>(out.rdbuf()),
std::istreambuf_iterator<int>(), std::back_inserter(numbers));
Note that ostreambuf_iterator is an output iterator. It is used to write, not read. What you want to do is, read for which you need istreambuf_iterator.
But wait! The above code is not going to work either, Why?
Because you're using istreambuf_iterator and passing int to it. The istreambuf_iterator reads data as unformatted buffer of type either char* or wchar_t*. The template argument to istreambuf_iterator could be either char or wchar_t.
What you actually need is called istream_iterator which reads formatted data of given type:
std::copy(std::istream_iterator<int>(out), //changed here also!
std::istream_iterator<int>(), std::back_inserter(numbers));
This will work great now.
Note that you could just avoid using std::copy, and use the constructor of std::vector itself as:
std::fstream in("out.txt");
std::vector<int> numbers((std::istream_iterator<int>(in)), //extra braces
std::istream_iterator<int>());
Note the extra braces around first argument which is used to avoid vexing parse in C+++.
If the vector object is already created (and optionally it has some elements in it), then you can still avoid std::copy as:
numbers.insert(numbers.end(),
std::istream_iterator<int>(in), //no extra braces
std::istream_iterator<int>());
No extra braces needed in this case.
Hope that helps.
Read the Book 'C++ How To Program' by Dietal & Dietal, The chapter on Vectors. I assure you, all your problems will be solved. You have opened the text file for output instead of input. Instead of using this function I would suggest that you should read-in strings and copy them into your vector using iterators until EOF is encountered in the file. EDIT: This way is more natural and easy to read and understand if you are new to Vectors.

Length of a char array

I have the code like this:
#include <iostream.h>
#include <fstream.h>
void main()
{
char dir[25], output[10],temp[10];
cout<<"Enter file: ";
cin.getline(dir,25); //like C:\input.txt
ifstream input(dir,ios::in);
input.getline(output,'\eof');
int num = sizeof(output);
ofstream out("D:\\size.txt",ios::out);
out<<num;
}
I want to print the length of the output. But it always returns the number 10 (the given length) even if the input file has only 2 letters ( Like just "ab"). I've also used strlen(output) but nothing changed. How do I only get the used length of array?
I'm using VS C++ 6.0
sizeof operator on array gives you size allocated for the array, which is 10.
You need to use strlen() to know length occupied inside the array, but you need to make sure the array is null terminated.
With C++ better alternative is to simple use: std::string instead of the character array. Then you can simply use std::string::size() to get the size.
sizeof always prints the defined size of an object based on its type, not anything like the length of a string.
At least by current standards, your code has some pretty serious problems. It looks like it was written for a 1993 compiler running on MS-DOS, or something on that order. With a current compiler, the C++ headers shouldn't have .h on the end, among other things.
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string dir, output, temp;
std::cout<<"Enter file: ";
std::getline(cin, dir); //like C:\input.txt
std::ifstream input(dir.c_str());
std::getline(input, output);
std::ofstream out("D:\\size.txt");
out<<output.size();
}
The getline that you are using is an unformatted input function so you can retrieve the number of characters extracted with input.gcount().
Note that \e is not a standard escape sequence and the character constant \eof almost certainly doesn't do what you think it does. If you don't want to recognise any delimiter you should use read, not getline, passing the size of your buffer so that you don't overflow it.

C++ - Find and replace in text file (standard system libraries)

I am looking for some advice.
My situation:
Application works with text local file.
In file are somewhere tags like this: correct = "TEXT". Unfortunatelly, there can be unlimited spaces between correct, = and "TEXT".
Obtained text is testing in function and may be replaced (the change must be stored in the file). correct = "CORRECT_TEXT"
My current theoretical approach:
With ofstream -- read by line to string.
Find tag and make change in string.
Save strings as lines to the file.
Is there some simplify way (with iterators?) in C++ with using standard system libraries only (unix).
Thank you for your ideas.
Here is a possible solution that uses:
std::getline()
std::copy()
istream_iterator
ostream_iterator
vector
Example:
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <string>
#include <vector>
struct modified_line
{
std::string value;
operator std::string() const { return value; }
};
std::istream& operator>>(std::istream& a_in, modified_line& a_line)
{
std::string local_line;
if (std::getline(a_in, local_line))
{
// Modify 'local_line' if necessary
// and then assign to argument.
//
a_line.value = local_line;
}
return a_in;
}
int main()
{
std::ifstream in("file.txt");
if (in.is_open())
{
// Load into a vector, modifying as they are read.
//
std::vector<std::string> modified_lines;
std::copy(std::istream_iterator<modified_line>(in),
std::istream_iterator<modified_line>(),
std::back_inserter(modified_lines));
in.close();
// Overwrite.
std::ofstream out("file.txt");
if (out.is_open())
{
std::copy(modified_lines.begin(),
modified_lines.end(),
std::ostream_iterator<std::string>(out, "\n"));
}
}
return 0;
}
I am not sure exactly what the manipulation of the lines should be but you could use:
std::string::find() and std::string::substr()
boost::split()
EDIT:
To avoid storing every line in memory at once the initial copy() can changed to write to an alternative file, followed by a file rename():
std::ifstream in("file.txt");
std::ofstream out("file.txt.tmp");
if (in.is_open() && out.open())
{
std::copy(std::istream_iterator<modified_line>(in),
std::istream_iterator<modified_line>(),
std::ostream_iterator<std::string>(out, "\n"));
// close for rename.
in.close();
out.close();
// #include <cstdio>
if (0 != std::rename("file.txt.tmp", "file.txt"))
{
// Handle failure.
}
}
You can split the task into tiny pieces and figure out how to do each in C++:
open a file as an input stream
open temporary file as an output stream
read a line from a stream
write a line to a stream
match a line to given pattern
replace text in a line
rename a file
Note: you don't need to store in memory more than one line at a time in this case.
It looks a lot like an 'INI file' syntax. You can search for it and you'll have a big load of examples. However, few of them will actually use C++ stdlib.
Here's some advices. (n.b. I assume that every lines you'll need to replace are using the syntax: <parameter> = "<value_text>")
Use the std::string::find method to locate the '=' character.
Use the std::string::substr method to split the string into different chunks.
You'll need to create a trim algorithm to remove every blank characters in front or back of a string. (It can be done with std functions)
With all that you'll then be able to split the string and isolate the parts to compare them do the needed modifications.
have fun !
Are you sure you need to do this within C++? Since you are on Unix, you can call sed which would do this easily with a command such as:
cat oldfile | sed 's/\(correct *= *\)\"TEXT\"/\1\"CORRECT_TEXT\"/' > newfile
You can call unix commands from within C++ if you have to (for example with system("command") from <cstdlib>.