reading this text in C/C++ - c++

Hi I am trying to read this text using a file input stream or some sort:
E^#^#<a^R#^##^FÌø<80>è^AÛ<80>è ^F \^DÔVn3Ï^#^#^#^# ^B^VÐXâ^#^#^B^D^E´^D^B^H
IQRÝ^#^#^#^#^A^C^C^GE^#^#<^#^##^##^F.^K<80>è ^F<80>è^AÛ^DÔ \»4³ÕVn3Р^R^V J ^#^#^B^D^E´^D^B^H
^#g<9f><86>IQRÝ^A^C^C^GE^#^#4a^S#^##^FÌÿ<80>è^AÛ<80>è ^F \^DÔVn3л4³Ö<80>^P^#.<8f>F^#^#^A^A^H
IQRÞ^#g<9f><86>E^#^A±,Q#^##^F^#E<80>è ^F<80>è^AÛ^DÔ \»4³ÖVn3Ð<80>^X^#.^NU^#^#^A^A^H
^#g<9f><87>
Here's the code I tried to read it with, but I am getting a bunch of 0s.
#include <stdio.h> /* required for file operations */
int main(int argc, char *argv[]){
int n;
FILE *fr;
unsigned char c;
if (argc != 2) {
perror("Usage: summary <FILE>");
return 1;
}
fr = fopen (argv[1], "rt"); /* open the file for reading */
while (1 == 1){
read(fr, &c, sizeof(c));
printf("<0x%x>\n", c);
}
fclose(fr); /* close the file prior to exiting the routine */
}
What's wrong with my code? I think I am not reading the file correctly.

You're using fopen() to open your file, which returns a FILE *, and read() to read it, which takes an int. You need to either use open() and read() together, or fopen() and fread(). You can't mix these together.
To clarify, fopen() and fread() make use of FILE pointers, which are a different way to access and a different abstraction than straight-up file descriptors. open() and read() make use of "raw" file descriptors, which are a notion understood by the operating system.
While not related to the program's failure here, your fclose() call must also match. In other words, fopen(), fread(), and fclose(), or open(), read(), and close().

Your's didn't compile for me, but I made a few fixes and it's right as rain ;-)
#include <stdio.h> /* required for file operations */
int main(int argc, char *argv[]){
int n;
FILE *fr;
unsigned char c;
if (argc != 2) {
perror("Usage: summary <FILE>");
return 1;
}
fr = fopen (argv[1], "rt"); /* open the file for reading */
while (!feof(fr)){ // can't read forever, need to stop when reading is done
// my ubuntu didn't have read in stdio.h, but it does have fread
fread(&c, sizeof(c),1, fr);
printf("<0x%x>\n", c);
}
fclose(fr); /* close the file prior to exiting the routine */
}

That doesn't look like text to me. So use the "r" mode to fopen, not "rt".
Also, ^# represents '\0', so you probably will read a bunch of zeros in any case. But not ALL zeros.

Related

Reading pcap file to vector/array

I am trying to read pcap file to some data structure like vector or array and later use gathered data (only selected one like packet length, timestamp) in application. I've found some sample application for reading pcap:
#include <stdio.h>
#include <pcap.h>
#define LINE_LEN 16
void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);
int main(int argc, char **argv)
{
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
if(argc != 2)
{
printf("usage: %s filename", argv[0]);
return -1;
}
/* Open the capture file */
if ((fp = pcap_open_offline(argv[1], // name of the device
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\nUnable to open the file %s.\n", argv[1]);
return -1;
}
/* read and dispatch packets until EOF is reached */
pcap_loop(fp, 0, dispatcher_handler, NULL);
pcap_close(fp);
return 0;
}
void dispatcher_handler(u_char *temp1,
const struct pcap_pkthdr *header,
const u_char *pkt_data)
{
u_int i=0;
/*
* unused variable
*/
(VOID*)temp1;
/* print pkt timestamp and pkt len */
printf("%ld:%ld (%ld)\n", header->ts.tv_sec, header->ts.tv_usec, header->len);
printf("\n\n");
}
The problem is with pcap_loop(). I've found documentation for this, but the only information is that this is reading whole file until end of file is reached. I've been trying to treat file as a typical FILE, and in while loop read until EOF, but it doesn't work, because I cannot simply treat fp as FILE.
Also I don't see any possibility to pass pointer to pcap_handler to retrieve it later.
Can someone suggest how I can do it other way?
According to documentation your code looks right. pcap_loop should be doing the FILE reading, you shouldn't try to do it.
One thing the doc mentions is that in older pcap versions 0 for count in pcap_loop is undefined, so it should be safer to use -1 in case you are linking to an older version.
I after further documentation and Internet investigation I've found function: pcap_next_ex()
Thanks to that I can use now while loop and read line by line (or more precisely packet by packet). The general idea is as follows:
struct pcap_pkthdr *header;
const u_char *pkt_data;
int res;
while((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0)
{
//Process packet
}
I've been trying to treat file as a typical FILE, and in while loop read until EOF, but it doesn't work, because I cannot simply treat fp as FILE.
No, because it's not a FILE. (You also get a pcap_t * from pcap_open_live() or from a pcap_create()/pcap_activate() combination, but that gives you a handle for a live capture, not for a file.)
Also I don't see any possibility to pass pointer to pcap_handler to retrieve it later.
The fourth argument to pcap_loop() is passed as the first argument to pcap_handler, so you could do
pcap_loop(fp, 0, dispatcher_handler, pointer);
and then, in dispatcher_handler(), cast temp1 to the appropriate type and use it - it'll point to the same thing that pointer does.

Read and write in c++

I am trying to use the system calls read() and write(). The following program creates a file and writes some data into it. Here is the code..
int main()
{
int fd;
open("student",O_CREAT,(mode_t)0600);
fd=open("student",O_WRONLY);
char data[128]="Hi nikhil, How are u?";
write(fd,data,128);
}
Upon the execution of the above program i got a file with name student created with size as 128 bytes.
int main()
{
int fd=open("student",O_WRONLY);
char data[128];
read(fd,data,128);
cout<<(char*)data<<endl;
}
But the output i get is junk characters....why is this so?
I wrote a small read program to read data from the file. Her is the code.
But the output
Don't read from a file that you've open in O_WRONLY mode!
Do yourself a favor and always check the return values of IO functions.
You should also always close file descriptors you've (successfully) opened. Might not matter for trivial code like this, but if you get into the habit of forgetting that, you'll end up writing code that leaks file descriptors, and that's a bad thing.
You're not checking whether read() returns an error. You should do so, because that's probably the case with the code in your question.
Since you're opening the file write-only in the first place, calling read() on it will result in an error. You should open the file for reading instead:
char data[128];
int fd = open("student", O_RDONLY);
if (fd != -1) {
if (read(fd, data, sizeof(data)) != -1) {
// Process data...
}
close(fd);
}
Well, one of the first things is that your data is not 128 bytes. Your data is the string: "Hi nikhil, How are u?", which is way less than 128 bytes. But you're writing 128 bytes from the array to the file. Everything after the initial string will be random junk from memory as the char array is only initialized with 21 bytes of data. So the next 107 bytes is junk.

Why is calling close() after fopen() not closing?

I ran across the following code in one of our in-house dlls and I am trying to understand the behavior it was showing:
long GetFD(long* fd, const char* fileName, const char* mode)
{
string fileMode;
if (strlen(mode) == 0 || tolower(mode[0]) == 'w' || tolower(mode[0]) == 'o')
fileMode = string("w");
else if (tolower(mode[0]) == 'a')
fileMode = string("a");
else if (tolower(mode[0]) == 'r')
fileMode = string("r");
else
return -1;
FILE* ofp;
ofp = fopen(fileName, fileMode.c_str());
if (! ofp)
return -1;
*fd = (long)_fileno(ofp);
if (*fd < 0)
return -1;
return 0;
}
long CloseFD(long fd)
{
close((int)fd);
return 0;
}
After repeated calling of GetFD with the appropriate CloseFD, the whole dll would no longer be able to do any file IO. I wrote a tester program and found that I could GetFD 509 times, but the 510th time would error.
Using Process Explorer, the number of Handles did not increase.
So it seems that the dll is reaching the limit for the number of open files; setting _setmaxstdio(2048) does increase the amount of times we can call GetFD. Obviously, the close() is working quite right.
After a bit of searching, I replaced the fopen() call with:
long GetFD(long* fd, const char* fileName, const char* mode)
{
*fd = (long)open(fileName, 2);
if (*fd < 0)
return -1;
return 0;
}
Now, repeatedly calling GetFD/CloseFD works.
What is going on here?
If you open a file with fopen, you have to close it with fclose, symmetrically.
The C++ runtime must be given a chance to clean up/deallocate its inner file-related structures.
You need to use fclose with files opened via fopen, or close with files opened via open.
The standard library you are using has a static array of FILE structures. Because you are not calling fclose(), the standard library doesn't know that the underlying files have been closed, so it doesn't know it can reuse the corresponding FILE structures. You get an error after it has run out of entries in the FILE array.
fopen opens it's own file descriptor, so you'd need to do an fclose(ofp) in your original function to prevent running out of file descriptors. Usually, one either uses the lower level file descriptor functions open, close OR the buffered fopen, fclose functions.
you are open the file fopen() function so u have to close the file useing fclose(), if you are using open() function and try to call fclose() function it will not work

Reading from and writing to the middle of a binary file in C/C++

If I have a large binary file (say it has 100,000,000 floats), is there a way in C (or C++) to open the file and read a specific float, without having to load the whole file into memory (i.e. how can I quickly find what the 62,821,214th float is)? A second question, is there a way to change that specific float in the file without having to rewrite the entire file?
I'm envisioning functions like:
float readFloatFromFile(const char* fileName, int idx) {
FILE* f = fopen(fileName,"rb");
// What goes here?
}
void writeFloatToFile(const char* fileName, int idx, float f) {
// How do I open the file? fopen can only append or start a new file, right?
// What goes here?
}
You know the size of a float is sizeof(float), so multiplication can get you to the correct position:
FILE *f = fopen(fileName, "rb");
fseek(f, idx * sizeof(float), SEEK_SET);
float result;
fread(&result, sizeof(float), 1, f);
Similarly, you can write to a specific position using this method.
fopen allows to open a file for modification (not just to append) by using either the rb+ or wb+ mode on fopen. See here: http://www.cplusplus.com/reference/clibrary/cstdio/fopen/
To position the file to a specific float, you can use the fseek by using index*sizeof(float) as the offset ad SEEK_SET as the orign. See here: http://www.cplusplus.com/reference/clibrary/cstdio/fseek/
Here is an example if you would like to use C++ streams:
#include <fstream>
using namespace std;
int main()
{
fstream file("floats.bin", ios::binary);
float number;
file.seekp(62821214*sizeof(float), ios::beg);
file.read(reinterpret_cast<char*>(&number), sizeof(float));
file.seekp(0, ios::beg); // move to the beginning of the file
number = 3.2;
// write number at the beginning of the file
file.write(reinterpret_cast<char*>(&number), sizeof(float));
}
One way would be to call mmap() on the file. Once you've done that, you can read/modify the file as if it was an in-memory array.
Of course that method only works if the file is small enough to fit in your process's address space... if you're running in 64-bit mode, you'll be fine; in 32-bit mode, a file with 100,000,000 floats should fit, but another order or two of magnitude above that and you might run into trouble.
I know this question has been answered already, but Linux/Unix provides easy system calls to read/write(pread/pwrite) in the middle of a file. If you look at the kernel source code for the system calls 'read' & 'pread', both eventually calls the vfs_read().And vfs_read requires a OFFSET, i.e it requires a POSITION to read from the file. In pread,this offset is given by us and in read() the offset is calculated internally in the kernel and maintained for the file descriptor. pread() offers exceptional performance compared to read() and using pread ,you can read/write in the same file descriptor simultaneously in multiple threads in different parts of the file. My Humble opionion, never use read() or other file streams, use pread(). Hope the filestream libraries have wrapped the read() calls, the streams perform well by making fewer system calls.
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{
char* buf; off_t offToStart = id * sizeof(float); size_t sizeToRead = sizeof(float);
int fd = open("fileName", O_RDONLY);
ret = pread(fd, buf, sizeToRead, offToStart);
//processs from the read 'buf'
close(fd);
}

How do I read the results of a system() call in C++?

I'm using the following code to try to read the results of a df command in Linux using popen.
#include <iostream> // file and std I/O functions
int main(int argc, char** argv) {
FILE* fp;
char * buffer;
long bufSize;
size_t ret_code;
fp = popen("df", "r");
if(fp == NULL) { // head off errors reading the results
std::cerr << "Could not execute command: df" << std::endl;
exit(1);
}
// get the size of the results
fseek(fp, 0, SEEK_END);
bufSize = ftell(fp);
rewind(fp);
// allocate the memory to contain the results
buffer = (char*)malloc( sizeof(char) * bufSize );
if(buffer == NULL) {
std::cerr << "Memory error." << std::endl;
exit(2);
}
// read the results into the buffer
ret_code = fread(buffer, 1, sizeof(buffer), fp);
if(ret_code != bufSize) {
std::cerr << "Error reading output." << std::endl;
exit(3);
}
// print the results
std::cout << buffer << std::endl;
// clean up
pclose(fp);
free(buffer);
return (EXIT_SUCCESS);
}
This code is giving me a "Memory error" with an exit status of '2', so I can see where it's failing, I just don't understand why.
I put this together from example code that I found on Ubuntu Forums and C++ Reference, so I'm not married to it. If anyone can suggest a better way to read the results of a system() call, I'm open to new ideas.
EDIT to the original: Okay, bufSize is coming up negative, and now I understand why. You can't randomly access a pipe, as I naively tried to do.
I can't be the first person to try to do this. Can someone give (or point me to) an example of how to read the results of a system() call into a variable in C++?
You're making this all too hard. popen(3) returns a regular old FILE * for a standard pipe file, which is to say, newline terminated records. You can read it with very high efficiency by using fgets(3) like so in C:
#include <stdio.h>
char bfr[BUFSIZ] ;
FILE * fp;
// ...
if((fp=popen("/bin/df", "r")) ==NULL) {
// error processing and return
}
// ...
while(fgets(bfr,BUFSIZ,fp) != NULL){
// process a line
}
In C++ it's even easier --
#include <cstdio>
#include <iostream>
#include <string>
FILE * fp ;
if((fp= popen("/bin/df","r")) == NULL) {
// error processing and exit
}
ifstream ins(fileno(fp)); // ifstream ctor using a file descriptor
string s;
while (! ins.eof()){
getline(ins,s);
// do something
}
There's some more error handling there, but that's the idea. The point is that you treat the FILE * from popen just like any FILE *, and read it line by line.
Why would std::malloc() fail?
The obvious reason is "because std::ftell() returned a negative signed number, which was then treated as a huge unsigned number".
According to the documentation, std::ftell() returns -1 on failure. One obvious reason it would fail is that you cannot seek in a pipe or FIFO.
There is no escape; you cannot know the length of the command output without reading it, and you can only read it once. You have to read it in chunks, either growing your buffer as needed or parsing on the fly.
But, of course, you can simply avoid the whole issue by directly using the system call df probably uses to get its information: statvfs().
(A note on terminology: "system call" in Unix and Linux generally refers to calling a kernel function from user-space code. Referring to it as "the results of a system() call" or "the results of a system(3) call" would be clearer, but it would probably be better to just say "capturing the output of a process.")
Anyway, you can read a process's output just like you can read any other file. Specifically:
You can start the process using pipe(), fork(), and exec(). This gives you a file descriptor, then you can use a loop to read() from the file descriptor into a buffer and close() the file descriptor once you're done. This is the lowest level option and gives you the most control.
You can start the process using popen(), as you're doing. This gives you a file stream. In a loop, you can read using from the stream into a temporary variable or buffer using fread(), fgets(), or fgetc(), as Zarawesome's answer demonstrates, then process that buffer or append it to a C++ string.
You can start the process using popen(), then use the nonstandard __gnu_cxx::stdio_filebuf to wrap that, then create an std::istream from the stdio_filebuf and treat it like any other C++ stream. This is the most C++-like approach. Here's part 1 and part 2 of an example of this approach.
I'm not sure you can fseek/ftell pipe streams like this.
Have you checked the value of bufSize ? One reason malloc be failing is for insanely sized buffers.
Thanks to everyone who took the time to answer. A co-worker pointed me to the ostringstream class. Here's some example code that does essentially what I was attempting to do in the original question.
#include <iostream> // cout
#include <sstream> // ostringstream
int main(int argc, char** argv) {
FILE* stream = popen( "df", "r" );
std::ostringstream output;
while( !feof( stream ) && !ferror( stream ))
{
char buf[128];
int bytesRead = fread( buf, 1, 128, stream );
output.write( buf, bytesRead );
}
std::string result = output.str();
std::cout << "<RESULT>" << std::endl << result << "</RESULT>" << std::endl;
return (0);
}
To answer the question in the update:
char buffer[1024];
char * line = NULL;
while ((line = fgets(buffer, sizeof buffer, fp)) != NULL) {
// parse one line of df's output here.
}
Would this be enough?
First thing to check is the value of bufSize - if that happens to be <= 0, chances are that malloc returns a NULL as you're trying to allocate a buffer of size 0 at that point.
Another workaround would be to ask malloc to provide you with a buffer of the size (bufSize + n) with n >= 1, which should work around this particular problem.
That aside, the code you posted is pure C, not C++, so including is overdoing it a little.
check your bufSize. ftell can return -1 on error, and this can lead to nonallocation by malloc with buffer having a NULL value.
The reason for the ftell to fail is, because of the popen. You cant search pipes.
Pipes are not random access. They're sequential, which means that once you read a byte, the pipe is not going to send it to you again. Which means, obviously, you can't rewind it.
If you just want to output the data back to the user, you can just do something like:
// your file opening code
while (!feof(fp))
{
char c = getc(fp);
std::cout << c;
}
This will pull bytes out of the df pipe, one by one, and pump them straight into the output.
Now if you want to access the df output as a whole, you can either pipe it into a file and read that file, or concatenate the output into a construct such as a C++ String.