How to read a certain range of lines using systems calls - c++

I am up a wall on an assignment that I have been hacking at for several days. Basically I need to make an executable program using C/C++ to take 3 queries from the user m,n and a file name.
The program will then output the text on those lines to the terminal. I must use read(), write(), open() and close() system calls to do it.
My approach is to go char by char (slow I know but everything else I tried seems to give segementation faults).
But it doesn't seem to work properly. When I use smaller parameters it just prints the whole thing, but if I use bigger parameters it doesn't print anything at all.
Can anyone tell me where I'm going wrong?
// Task 2 of Lab 3
#include<unistd.h> // required library for the system calls
#include<fcntl.h> // required for system calls usage
#include <stdlib.h> // required for the use of exit statement, and atoi
#include<stdio.h> // required for the use of perror
#include<string>
using namespace std;
int main(int argc,char *argv[]){
int m = atoi(argv[1]);
int n = atoi(argv[2]); // taking commmand line args by conversion with atoi
int file; // integer value for holding the file descriptor
ssize_t display;
char *buff[1];
int currentLine = 0;
// open the first file for reading
file = open(argv[3],O_RDONLY);
if(file == -1 ){ // error handler for system call 1: open()
perror("Did not open, exiting...");
exit (1);
}
while(((display = read(file,buff,1)) > 0)){
if(*buff[0] == '\n'){
currentLine++;
}
if((currentLine >= m) && (currentLine <= n)){
if(write(STDOUT_FILENO, buff,display) != display){ // if statement doubles as error handling for read()
perror("Problem with writing..."); // errror handling for write()
exit(-1);
}
}
else{
}
}
file = close(file); // Final system call close()
return 0;
}
Sample testfile:
I have some information in here.
Each line should print to the screen
3 lines total
make that 4
Wait? WHAT! I need 12 minimum???
Hm....
Wellp better start typing then. Let's see what can I write about?
Midterms are coming
They scare me
I hate exams, but I love code
woah i also need numbers in here uh 23
19 and lets do 100 and 400 just to add a couple more
maybe i should go ahead and add a 903 here
300
and that previous 300 got it's own line
with this file ...
I have a good mix of chars,numbers, and symbols
that's good enough
time to test!

Related

Magick++ API: Get PDF page count?

I'm struggling to write a function to get the number of pages from a PDF without using external/additional (ie, other-than-Magick++) libraries for this purpose -- yet, when I execute something like this:
#include <Magick++.h>
using namespace Magick;
int main(int argc,char **argv)
{
InitializeMagick(*argv);
Image master;
master.ping("a-66-page-pdf.pdf[999999]");
return 0;
}
(Where [999999] refers to the page requested)
It dumps an error like this:
Requested FirstPage is greater than the number of pages in the file: 66
No pages will be processed (FirstPage > LastPage).
terminate called after throwing an instance of 'Magick::ErrorDelegate'
what(): Magick: Postscript delegate failed (a-66-page-pdf.pdf) reported by coders/pdf.c:434 (ReadPDFImage)
Magick: abort due to signal 6 (SIGABRT) "Abort"...
Aborted (core dumped)
ie, It knows that the pdf has 66 pages -- yet I can't figure out how to get that information from it except by making it crash like this?
Is there a way?
If you're using ImageMagick-7, use the STL method.
std::list<Magick::Image> master;
Magick::pingImages(&master, "a-66-page-pdf.pdf");
std::cout << master.size() << std::endl;
The pingImages method is not available with ImageMagick-6, so you'll need to read all the images.
Magick::ReadOptions opts;
// Set dpi & depth, if needed
// opts.depth(8);
// opts.density(72);
std::list<Magick::Image> master;
Magick::readImages(&master, "a-66-page-pdf.pdf", opts);
std::cout << master.size() << std::endl;
You can try to initialize a counter and create that string with counter as the index. As long as you increment the counter in a while loop with your code inside a try-catch block, when the above exception is thown, your counter would indicate the number of pages.
The best I can come up with, if anyone's facing the same problem working with ImageMagick/GraphicsMagick, without including an entire extra library for this one function (PoDoFo, which is unstable, can do this, and poppler can also do it) is to use this based on the code written in the question:
#include <Magick++.h>
#include <cstring>
using namespace Magick;
int main(int argc,char **argv)
{
if (argc < 2) {
return 1;
}
InitializeMagick(*argv);
try {
Image master;
char cmd[4096] = {""};
strcat(cmd, argv[1]);
strcat(cmd, "[99999999999]");
master.ping(cmd);
} catch( Exception &error_ )
{
// do nothing
}
return 0;
}
And call it like this:
./compiled-program any-given-pdf.pdf 2>/dev/null | grep file: | awk {'print $13'}
Maybe with popen() etc. Maybe you could redirect stdout to a string, I haven't tried yet.
It's janky, it feels like a hack, but it's a hell of a lot faster (I mean almost infinitely faster) than trying to load a list/vector/array with ping() or readImages() and count the size of the list.
It's endlessly frustrating that Magick++ offers no accessible method to retrieve a PDF's page count, and yet evidently not only is capable of getting a page count, but does so every time an image is pinged.
If you're alright with including an entire library for just one function, poppler and PoDoFo can do this.
Obviously this will fail on a 100-billion page PDF.

Ubuntu Terminal C++ program being called in other program stuck, even though they separately work fine

Long story short:
I created a program to get the path to a model file, do something with that information and pass on a different set of information, then i tried to create a wrapper for another program that basically catches the command line arguments and funnels some of them to my program to do its thing.
Simplified program flow.
Software --> args[all] --> Wrapper --> args[some] --> Program --> Output
The problem i now have is, calling my program on its own with hard-coded information or command line arguments equal to what the Wrapper would pass on works both flawlessly. The same goes for the Wrapper it works independently.
It also works to have the Wrapper pass on arguments and call the Program if the model information is wrong, which results in a simple string warning. But if the path to the model is correct it gets stuck in an endless loop and i don't know why. Separate runtimes are 8-11s for the Program and maybe 2s for the Wrapper, but i let it run for about 10min and nothing happened after some dummy print code.
Wrapper:
int main(int argc, char* argv[]){
if(argc > 1){
string tmp0 = argv[1];
string tmp1 = "./program " + tmp0;
const char* model = tmp1.c_str();
int status = system(model);
}
else{
cout << "No Model Information.\n";
}
return 0;
}
Parameters would be: Path to a model file and some other stuff, but only the path to the model would be passed on to the program in this case.
Program:
#include "program.hpp"
int main(int argc, char* argv[]){
if(argc > 1){
string tmp = argv[1];
const char* model = tmp.c_str();
cout << program(model);
}
else{
cout << "At least one defined Argument for the Model needs to be given.\n";
}
return 0;
}
Program Function Pseudo Code:
#include <stdio.h>
string program(const char* model){
string tmp
read(model);
if(model has variables) do
tmp = "has variables";
return tmp
}
--- Edit ---
The program function code is in pseudo code because its too complex and specific to list here without a load of libraries and other stuff being listed. If thats necessary i can try to provide it, but as it is i dont have a small or simple example i can give.
--- End edit ---
I don't understand enough about command line arguments to write sophisticated code, so i know this is more or less shitty, but i only need to be able to execute the program from the wrapper somehow and need to be able to read and pass on specific command line arguments. This is just the best i came up with.
Executing the Program code alone, with correct model information: ~10s execution time
Executing the Program code alone, with wrong model information: ~2s execution time
Executing the Wrapper code alone: ~2s execution time
Executing the Wrapper code, calling the Program code with wrong model information: ~2s execution time
Executing the Wrapper code, calling the Program code with correct model information: endless wait
I just dont get why it doesnt progress even though each works separately.
You can use fork() and execvp() in the unistd.h API. Depending on the return of fork() you can have the wrapper wait or end after launching the command.
Save the source file as args.cpp and compile it with the following command:
$ g++ args.cpp -o args && ./args -l -h -a
#include <cstdio>
#include <unistd.h>
#define SPAWNCMD "ls"
int main(int argc, char* argv[])
{
if(argc > 1)
{
printf("Command to spawn: %s ", SPAWNCMD);
for (unsigned i = 1; i < argc; i++)
printf("%s ", argv[i]);
printf("\n");
if (fork())
if (execvp(SPAWNCMD, argv) == -1)
{
printf("Incorrect termination of SPAWNCMD\n");
return 1;
}
}
else
{
printf("No Model Information.\n");
}
printf("Wrapper program end\n");
return 0;
}

fprintf() / std::cout doesn't print part of the string to stdout/stderr

I have this strange problem with stdout/stderr.
I want to apologize for not being able to put here the original code, it's too long / too many libraries dependent etc...
So please let me know if you ever encountered anything like it, or what may cause this issue without getting the original code, only the idea and examples of the simple things I tried to do:
I'm using g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4) on RHEL 6.3
I couldn't isolate the problem for putting it here, I'll give code examples of what I did.
fprintf() / printf() / std::cout stops working after a while.
I'm using boost::asio::io_service with deadline_timer in order to call a my_print() function.
This my_print() function prints to screen every 1 second some information.
In order to print, I use alignments, like the following:
fprintf(stdout, "%*s\n", -printWidth, someEnumToStr[i]);
fprintf(stdout, "%s\n", aString);
fprintf(stdout, "%u\n", num);
While aString is a std::string. Sometimes I construct aString from std::ostringstream.
Sometimes I construct it with snprintf().
I have an std::map with information, exactly 16 elements inside the map. I iterate over it, and for each element I try to print data with the example of fprintf() above.
For an unknown reason, the line of element 16 isn't printed.
If I call the executable, and redirect stdout to a file (./a.out > aaa.txt) the line of element 16 is getting printed.
If I open a new FILE* and fprintf() to this file, again, everything is getting printed (all lines, including line of element 16)
Before using fprintf() I tried to use std::cout (and alignments with std::cout.width(printWidth) << std::left...), The same behavior happened, but when line 16 wasn't drawn, stdout got stuck (I mean, the program still worked, but nothing was printed to stdout never again. I had to call std::cout.clear() for it to work again). Since a point in the code, which I couldn't lay my hands on, std::cout.failbit and badbit were 1.
If I run the code with valgrind this behavior doesn't happen. valgrind doesn't say anything wrong.
If I run it with gdb it happens, but gdb doesn't say anything wrong.
If I run it in an IDE (clion) in debug mode, it doesn't happen.
If I run it in IDE, without debug, it happens.
I figure it depends on the printWidth I give for the alignment in fprintf() - When printWidth is bigger, it happens sooner (when it's smaller, line 16 is randomly getting printed).
Another important thing: it happens more frequently when there is more to print.
I tried to give std::cout a bigger buffer (not his default) and it didn't work.
I tried to buffer all of the output into a buffer (instead of printing each line), then to only fprintf() once. Same behavior happens.
I didn't find anywhere in the code I try to print a NULL pointer.
I print with \n every couple of fprintf()s, and do fflush() in the end of my_print()
Please let me know if you know anything.
Illustration:
deadline_timer..... every 1 sec... my_print()
boost::asio::io_service.run
my_print() {
for(std::map<>::iterator... begin, end, ++it....) {
fprintf()s....
}
}
Non printable characters may be breaking terminal.
fprintf(stdout,"%s", astdstring.cstr() );
Is how to print std::string
I use boost::asio, I have a callback to read from stdin. this read is nonblocking - happens with async_read_some().
The problem was stdin was turned to be nonblocking, and it also caused stdout to be nonblocking as well because they point to the same file description (explanation).
It caused the fprintf() calls to fail (returned -1 with errno 11) and not all of the output got printed out on the screen.
It has no relation to boost.
I succeeded isolating the problem, the following code creates this problem:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[]) {
const int problem = 8000;
const int myBuffSize = 32000;
char *myBuff = new char[myBuffSize];
int myoffset = 0;
memset(myBuff, '-', myBuffSize);
int flags;
bool toogle = true;
bool running = true;
// Comment from here
if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) {
printf("error fcntl()\n");
return 0;
}
if (fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK) < 0) {
printf("error fcntl()\n");
return 0;
}
// Comment until here
while(running) {
toogle = toogle ? false : true;
if (toogle) {
snprintf(myBuff + problem, myBuffSize - problem, "fin\n\n");
} else {
snprintf(myBuff + problem, myBuffSize - problem, "end\n\n");
}
fprintf(stdout, "%s", myBuff);
sleep(1);
}
delete[] myBuff;
return 0;
}
If you'll comment the // Comment from here to // Comment untill here, it will print all of the output (fin and end will be printed).
One solution to this problem is to open another fd to the current tty using fopen(ttyname(STDOUT_FILENO), "w") and to print into it.
I believe another solution is to async_write() into screen.
The output might be stuck in a buffer, and not flushed before program termination.
Try adding exit(0) at the end of the program, and see if it helps.
http://www.cplusplus.com/reference/cstdlib/exit/
All C streams (open with functions in <cstdio>) are closed (and flushed, if buffered), and all files created with tmpfile are removed.

Execute .exe file from c++ code + enter values

I'm relatively new to c++, and I'm just making some simple programs.
One of my programs will need to open up a different .exe file. This .exe file will ask for 2 or 3 file names, then run and exit.
Just to test this out, I created a simple_calc.exe file, that ask for value1, then value2 then multiply them.
So let's say I want to create a "call_other_file.exe" and automatically run "simple_calc.exe" with value1 and value2 taken from "call_other_file.exe"s file.
How can I proceed to do that?
After searching a bit, i see something like:
system("simple_calc.exe -val1 -val2").
But that doesn't work for me. Or I'm not sure how to define val1 and val2...
edit: the program I want to access (simple_calc.exe in the example), I can not change the code there, I don't have access to it's .cpp file.
Any suggestions?
i see something like: system("simple_calc.exe -val1 -val2")
It should work. The reason why that didn't work might be that you didn't put int argc, char* argv[] in your "simple_calc"'s main function.
//simple_calc.cpp
int main(int argc, char* argv[])
{
if (argc == 2)
{
cout << "Error: At least two argument must be exist.";
return -1;
}
return 0;
// After that, you can use 'argv' arguments to calculate what you want to calculate. Also, in order to calculate them, you also need to convert 'argv' to integer or double, since they are string or char array.
}
For more information on C++ comand-line arguments see this site below:
http://www.tutorialspoint.com/cprogramming/c_command_line_arguments.htm
When you add the command-line arguments to your simple_calc.cpp, you can use this simple_calc.exe val1 val2. To call another program from your C++ program, you need system calls. In your main function;
system('simple_calc.exe')
You also need to know about how windows console work, if you are using windows. If you are using linux, its console commands are also different.
My suggestion is that you must first learn how consoles work different operating systems.
There are various ways to have two separate programs communicate with one another, but the system() function is probably the simplest; it just runs a string of text as though it were entered in a console window.
Basic example
The main program simply runs the other program with two arguments: hello and world.
/* main.c */
#include <stdlib.h>
int main() { return system("./other hello world"); }
The two arguments will be passed to the other program as C-style strings via the argv[] array. Note that they will be stored as the second and third elements, since the first item (argv[0]) will be the path to the program itself.
/* other.c */
#include <stdio.h>
int main(int argc, char *argv[])
{
int i = 0;
for (i = 1; i < argc; ++i) { printf("%s\n", argv[i]); }
return 0;
}
The output of the above programs will look like this:
hello
world
Process returned 0 (0x0) execution time : 0.004 s
Press ENTER to continue.
Arguments with spaces
As you may have noticed, arguments are space-separated. If you need to pass a string with spaces as a single parameter, you'll need to enclose it in quotes:
/* main.c */
#include <stdlib.h>
int main() { return system("./other \"this is all one string\" \"and so is this\" bye"); }
This would produce the following result:
this is all one string
and so is this
bye
Process returned 0 (0x0) execution time : 0.004 s
Press ENTER to continue.
Non-string arguments
Since the arguments are given as strings, you'll need to convert them into numbers (using conversion functions such as strtod(), atoi(), or atof()) if necessary. Here's an updated version of main.c:
/* main.c */
#include <stdlib.h>
int main() { return system("./other 4 6"); }
...and here's the corresponding other.c file:
/* other.c */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int total, i;
for (total = 0, i = 1; i < argc; ++i) { total += atoi(argv[i]); }
printf("TOTAL: %d\n", total);
return 0;
}
This produces the following output:
TOTAL: 10
Process returned 0 (0x0) execution time : 0.005 s
Press ENTER to continue.

Error handling in std::ofstream while writing data

I have a small program where i initialize a string and write to a file stream:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
std::ofstream ofs(file.c_str());
string s="Hello how are you";
if(ofs)
ofs<<s;
if(!ofs)
{
cout<<"Writing to file failed"<<endl;
}
return 0;
}
My diskspace is very less, and the statement "ofs<" fails. So I know that this is an error logically.
The statement "if(!ofs)" does not encounter the above issue, hence I am unable to know why it failed.
Please tell me, by which other options I would be able to know that "ofs< has failed.
Thanks in advance.
In principle, if there is a write error, badbit should be set. The
error will only be set when the stream actually tries to write, however,
so because of buffering, it may be set on a later write than when the error occurs, or even after
close. And the bit is “sticky”, so once set, it will stay
set.
Given the above, the usual procedure is to just verify the status of the
output after close; when outputting to std::cout or std::cerr, after
the final flush. Something like:
std::ofstream f(...);
// all sorts of output (usually to the `std::ostream&` in a
// function).
f.close();
if ( ! f ) {
// Error handling. Most important, do _not_ return 0 from
// main, but EXIT_FAILUREl.
}
When outputting to std::cout, replace the f.close() with
std::cout.flush() (and of course, if ( ! std::cout )).
AND: this is standard procedure. A program which has a return code of 0
(or EXIT_SUCCESS) when there is a write error is incorrect.
I found a solution like
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
std::ofstream ofs(file.c_str());
string s="Hello how are you";
if(ofs)
ofs<<s;
if(ofs.bad()) //bad() function will check for badbit
{
cout<<"Writing to file failed"<<endl;
}
return 0;
}
You can also refer to the below links here and thereto check for the correctness.