stream .pdf error [duplicate] - c++

This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
convert a file (.txt,.pdf..) into a stream file
std::string fil= "/home/sensor.pdf";
std::ifstream t(fil.c_str());
if (t)
{
string res;
string line;
while (getline(t, line, '\n'))
{
res=res+line;
}
std::string p;
p=(((reinterpret_cast<const unsigned char *> (res.c_str())),res.size()));
std::string f_data=p;
char *token = strtok( const_cast<char*>(fil.c_str() ), "/" );
std::string name;
std::vector<int> values;
while ( token != NULL )
{
name=token;
token = strtok( NULL, "/" );
}
std::strig f_name=name;
}
When I try to load the .pdf file I have an error "unable to read. PDF IS DAMAGED". WHY? This code works for .txt files and .cpp files. I've tested it. I am currently working in ubuntu c++ code. I've also used the base_64 encode/decode because this was the request.

Try this: http://sourceforge.net/projects/libharu/
I saw it recommended in a few different places, including a couple different SO questions - but all they gave was the link.
It's a free, open-souce library for PDF reading. It probably isn't as easy as you want, but I think its as easy as you're gonna get and its free.
It's also multi-platform so should work on UNIX and windows.

Try opening with:
ifstream file ("/home/sensor.pdf", ios::in|ios::binary);

Related

Clear CSV-file from non-specified symbols using C++ [duplicate]

This question already has answers here:
Why can Windows not read beyond the 0x1A (EOF) character but Unix can? [duplicate]
(2 answers)
Closed 3 years ago.
I'm trying to convert CSV-file to TXT-file using simple C++-code like this:
std::ofstream txtFile(strFileName, std::ofstream::out | std::ofstream::app);
std::string strLine;
std::ifstream csvFile(strCSVDir);
while (std::getline(csvFile, strLine))
{
std::string subString;
std::stringstream s(strLine);
while (std::getline(s, subString, ';'))
{
txtFile << subString << "\t";
}
txtFile << "\n";
}
txtFile.close();
csvFile.close();
It works fine, but only if the CSV-file doesn't contain any non-specified symbols, like arrow on this picture:
In this case my code can read only part of CSV-file until it meet this arrow symbol. How can I get around this situation?
Update: if I look at this CSV-file in byte-representation (for example in Far Hex-view), than I see code of arrow-symbol is "1A". The table of Unicode-characters points that it is Substitute symbol. How does it get in this CSV-file I don't know.
It might be easier to just read the entire file - then replacing and finally saving.
Going from your snippet:
std::stringstream sstr;
sstr << csvFile.rdbuf();
std::string buffer = sstr.str();
boost::replace_all(buffer, ";", "");
txtFile << buffer;
Update: if you don't have boost it should be easy to replace with something else like a for loop (since it is just a single char replacement)
Update 2: The reason why reading might not read the entire file in this case is because it is being read as a text file and probably contains a terminating character somewhere due to the way it is being read - see https://en.cppreference.com/w/cpp/io/c#Binary_and_text_modes for explaination.

How to delete a specific line in a text file in C++? [duplicate]

This question already has answers here:
Deleting specific line from file
(3 answers)
Closed 4 years ago.
I want to search for a string in a text file and delete the whole line when it's found. I want to write this in C++.
I've tried solutions in C#, and I've tried creating temporary files. Nothing works for me.
Here's my code so far:
void MainForm::WriteToTextFile(){
ifstream stream("text.txt");
string line;
bool found = false;
while (std::getline(stream, line) && !found)
{
if (line.find("Delete_This_Line") != string::npos){ // WILL SEARCH "Delete_This_Line" in file
found = true;
line.replace(line.begin(), line.end(), "\n");
stream.close();
}
I expected that the text file would be modified but nothing has changed.
You don't write anything to the file.
And for text files, you can't simply "replace" text, not unless the replacement is the exact same length as the old text you want replaced.
One common way to solve your problem is to read from the original file, writing to a temporary file. When you find the text you want to be replaced then you write the new text to the temporary file. Once you're done then you close both files, and rename the temporary file as the original file, replacing it with your new modified content.
You modify only a string in the memory, how can you expect that change the content of the read file ?
Note also to continue to try to read into the file while you closed it, you test found too late after the getline(), and is more simple to just add a break
std::getline duplicates the line to another string object inside memory. Modifying that string will not change the contents of the file.
A possible solution is to recreate the file using input and output file streams and avoid copying just the desired line. Here is an untested example:
#include <fstream>
#include <cstdio>
#include <string>
#include <iostream>
using namespace std;
bool replace_line(string filename, string key, string new_content)
{
{
ifstream stream(filename);
ofstream ofs(filename + ".out");
string line;
bool found = false;
while (std::getline(stream, line))
{
if (line.find(key) != string::npos){
found = true;
ofs << new_content;
} else {
ofs << line;
}
}
}
remove(file);
rename(file + ".out", filename);
return found;
}

How to read files which has a prefix and a timestamp as a file name in c++ [duplicate]

This question already has answers here:
How can I get the list of files in a directory using C or C++?
(33 answers)
Closed 5 years ago.
Usually when the file name is "example.txt", I can use the following code to read from the file.
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
else cout << "Unable to open file";
But how can I use the same program to read a file, When the file name is example_201703031140.txt or example_201703031142.txt. (Let's just say this file is the only file in the location with that prefix. In other words, the location can have either example_201703031140.txt OR example_201703031142.txt, not the both )
To clarify the question more, how can I write a program to which can read dynamically changing file names?
For example imagine a scenario that I have to write to file which is named example_timestamp and read that file from a separate module (which do not have access to the full file name, but knows that it has a prefix "example" followed by a timestamp)
Update: You do not know what the timestamp is, you just know that it is a timestamp.
I guess you would like something like this:
DIR* dirp = opendir("the dir name");
while(struct dirent* e = readdir(dirp)){
if e->d_name matches the pattern you wanted{
do whatever you want with this file.
}
}
First, you need to create the prefix or postfix of the file name, for example creating a date time format:
char buffer[128];
time(&rawtime);
timeinfo = localtime(&rawtime);
strftime(buffer, 80, format.c_str(), timeinfo);
out << buffer;
After that you build the file name to validate and use it.
In the link link a show you how i create a library to create logs with dynamic names and reuse them:
https://github.com/jorgemedra/APILogCpp/blob/master/APILogCpp/UIPILog/LogManager.cpp

Analyzing a string for file name format [duplicate]

This question already has answers here:
How to check if string ends with .txt
(12 answers)
Closed 8 years ago.
A file name is being passed down into a function. The string needs to be checked to make sure it ends with ".bmp"
How do i check for that to later open the file?
For example: if a string contains "picture.txt" it will tell the user the string is not in the correct format. If a string contain "picture.bmp" it should accept it for later use of opening the file.
Thanks in advance!
What OS are you using? If it's Windows / Visual C++, you have functions that properly give you the extension given a file name (for example _spiitpath). If you want something portable, you have boost::filesystem to parse out the name.
The reason why you should use these functions instead of trying to cook something up yourself is that there could be corner or edge cases that you didn't consider, thus causing your code to give wrong results.
You can do something like this:
bool hasExtension(const string& filename, const string& extension)
{
size_t fnlen = filename.length();
size_t exlen = extension.length();
if (fnlen < exlen)
return false;
return memcmp(filename.c_str() + fnlen - exlen, extension.c_str(), exlen) == 0;
}
int main()
{
cout << hasExtension("file.txt", ".txt") << endl;
}

Reading a file - won't open

I am trying to open a file in C++ but it seems to be giving me a bit of hassle, here is the code that deals with opening the file so far:
void CreateHistogram(string str_file, vector<HistogramWord> &result) {
string line;
long location;
HistogramWord newWord;
const char * filename = str_file.c_str();
//ifstream myfile (str_file.c_str());
ifstream myfile (filename);
//myfile.open(filename);
if (myfile.is_open()) {
while (myfile.good()) {
getline(myfile, line);
line = clarifyWord(line);
Okay, just for a bit of explanation, HistogramWord is a struct that is defined in the header and from what I have read in the online documentation, the filename has to be of type const char *, so that is what I have done. Converted str_file to be a const char *.
Now, I have tried a few different things which is why some of the code is commented out. When it gets to the line if (myfile.is_open()), it always evaluates to false. Anyone seem to know why?
Thanks,
Brandon
OK IO 101
If you don't give the complete filepath but only the filename then the current working directory will be appended to the filename.
So if your .exe is in C:\temp and you call your program from this directory and your filename is test.txt then the complete filename in this case will be C:\temp\test.txt
This will only work if the .exe and the test.txt are both under C:\temp.
In all other cases it will fail. You could create the absolute path by using win API or the linux equivalent - I don't know what platform you are on.
Now in order to read a succsfully opened file this will suffice :
void CreateHistogram(string str_file, vector<HistogramWord> &result) {
string line;
long location;
HistogramWord newWord;
ifstream myfile (str_file.c_str());
if (myfile.is_open()) {
while (getline(myfile, line)) {
line = clarifyWord(line);
}
else{
//throw exception, print error message etc
throw std::exception(std::string("Couldn't open file : " + str_file).c_str());
}
}
edit : Thanks # Shahbaz
My best guess is that Windows is "hiding extensions for known file types" so the name of the file is actually different than what you have put in windows. For example if it's a .txt file, and you name it test.txt, the actual name would be test.txt.txt which is quite a stupid thing windows does.
To change this, go to My Computer -> Toold -> Folder Options -> And uncheck the box that says "Hide extensions for Known File Types". This is for XP. If you have another windows it should be more or less the same path. If you don't see the toolbar, try ALT+t (tools) or ALT+f (file) to make it appear.
This problem give quite many of us a trouble in the first semester of college.
What fixed it for me was using forward slashes instead of double backslashes in my filepath.
e.g.
inFile.open("path/to/file.txt")
instead of
inFile.open("path\\to\\file.txt")