int fd[2];
void write_to_pipe(char* str)
{
int file = fd[1];
FILE *stream;
//printf("writing to pipe : %s\n", str);
stream = fdopen(file, "w");
//printf("fdopen returned : %d\n",(int)stream);
fprintf(stream, "%s", str);
fclose(stream);
}
At main() : pipe(fd);
If I call write_to_pipe first then it works perfectly fine.
If the function is called second time then fdopen fails(returns 0).
I assumed the stream/pipe/somthing is closed
What is the safe way to "not close the pipe" and call the function multiple times
Compiler : gcc 6.3.1
p.s.
This read function could have similar problem too.
char* read_from_pipe()
{
int file = fd[0];
static char buf[100];
FILE *stream;
stream = fdopen(file, "r");
read(file,buf,100);
fclose(stream);
return buf;
}
Standard C doesn't know POSIX file descriptors, only FILE * is standard, and fclose() closes the file. This of course implies to do whatever is necessary on the platform to close the file, so in this case, calling close() on the underlying descriptor.
What you should do is just use FILE * wherever appropriate. So if you need a pipe as a backend for your FILE *, fdopen() the file right after creating the pipe. This way, you have your platform-specific code in a single place.
If you happen to need the file descriptor for anything else than closing the pipe, you can use fileno() on the FILE *, but then you have another platform-dependent part in your code.
What is the safe way to "not close the pipe" and call the function multiple times
Don't use fdopen() on the file descriptor:
void write_to_pipe(char* str)
{
write( fd[ 1 ], str, strlen( str ) );
}
or use fdopen() at the same scope as the pipe itself:
int fd[2];
.
.
.
FILE *stream = fdopen( fd[ 1 ] );
.
.
.
void write_to_pipe(char* str)
{
fprintf(stream, "%s", str);
}
You could dup the file descriptor and perform the fdopen on the duplicate.
int write_to_pipe(char* str)
{
int file = dup(fd[1]);
if(0>file)
return -1;
FILE *stream;
//...
}
In any case, your function should probably return an integer so that it could signal possible errors that might occur inside the function.
You are closing the stdout file descriptor, which closes the pipe. Open it once and keep it around until you are finished.
this function:
char* read_from_pipe()
{
int file = fd[0];
static char buf[100];
FILE *stream;
stream = fdopen(file, "r");
read(file,buf,100);
fclose(stream);
return buf;
}
contains several problems.
Suggest writing it similar to:
#define MAX_BUF_LEN 100
char* read_from_pipe()
{
static char buf[ MAX_BUF_LEN +1 ];
ssize_t byteCount = read( fd[0], buf, MAX_BUF_LEN );
if( 0 > byteCount )
{ // an error occurred
perror( "read from pipe failed" );
buf[0] = '\0';
}
else if( 0 == byteCount )
{
fprintf( stderr, "no bytes read\n" );
buf[0] = '\0';
}
else
{
buf[byteCount] = '\0';
}
return buf;
} // end function: read_from_pipe
Note: read() does not terminate the char array, so the code has to do that And the array has to be 1 char longer than the max number of characters ask for in the read() statement.
Note: the syntax for read() wants a int, not FILE* for its' first parameter. Here is the proper syntax:
ssize_t read(int fd, void *buf, size_t count);
this function:
int fd[2];
void write_to_pipe(char* str)
{
int file = fd[1];
FILE *stream;
//printf("writing to pipe : %s\n", str);
stream = fdopen(file, "w");
//printf("fdopen returned : %d\n",(int)stream);
fprintf(stream, "%s", str);
fclose(stream);
}
leaves a lot to be desired.
Suggest something similar to:
int fd[2]; << in file scope, so visible from functions
void write_to_pipe(char* str)
{
//printf("writing to pipe : %s\n", str);
ssize_t bytesWritten = write( fd[1], str, strlen(str) );
if( strlen(str) != bytesWritten )
{
fprintf( stderr, "write to pipe failed to write all bytes\n" );
}
else if( 0 > bytesWritten )
{
perror( "write to pipe failed" );
}
} // end function: write_to_pipe
Duplicate the descriptor and use the duplicate in the fdopen call.
Related
I'm writing code that's supposed to verify that a .txt file is a certain format.
I wrote my code as I saw in a tutorial and in the website
and for some reason my program doesn't even print my file.
Can you tell me what I'm doing wrong?
The code will do something far more complex, but I'm still trying to work on my basics.
Here's my code so far:
int main(int argc, char *argv[]) {
/* argv[0] = name of my running file
* argv[1] = the first file that i receive
*/
define MAXBUFLEN 4096
char source[MAXBUFLEN + 1];
int badReturnValue = 1;
char *error = "Error! trying to open the file ";
if (argc != 2) {
printf("please supply a file \n");
return badReturnValue;
}
char *fileName = argv[1];
FILE *fp = fopen(argv[1], "r"); /* "r" = open for reading */
if (fp != NULL) {
size_t newLen = fread(&source, sizeof(char), MAXBUFLEN, fp);
if (ferror(fp) != 0) {
printf("%s %s", error, fileName);
return badReturnValue;
}
int symbol;
while ((symbol = getc(fp)) != EOF) {
putchar(symbol);
}
printf("finish");
fclose(fp);
}
else {
printf("%s %s", error, fileName);
return badReturnValue;
}
}
I think you need a bit more explanations:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// there might be a macro BUFLEN defined in stdio
// which size is optimized for reading in chunks.
// Test if avaiable otherwise define it
#ifndef BUFLEN
# define BUFLEN 4096
#endif
int main(int argc, char *argv[])
{
char source[BUFLEN];
char *filename;
FILE *fp;
size_t fpread, written;
char c;
int ret_fclose;
if (argc != 2) {
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(EXIT_FAILURE);
}
// reset errno, just in case
errno = 0;
// work on copy
filename = malloc(strlen(argv[1]) + 1);
if (filename == NULL) {
fprintf(stderr, "Allocating %zu bytes failed\n", strlen(argv[1]) + 1);
exit(EXIT_FAILURE);
}
filename = strcpy(filename, argv[1]);
// try to open the file at 'filename'
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Opening file \"%s\" filename failed\n", filename);
// errno might got set to something usable, check and print
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
// You have two options here. One is to read in chunks of MAXBUFLEN
while ((fpread = fread(&source, 1, BUFLEN, fp)) > 0) {
// Do something with the stuff we read into "source"
// we do nothing with it here, we just write to stdout
written = fwrite(&source, 1, fpread, stdout);
// you can use 'written' for error check when writing to an actual file
// but it is unlikely (but not impossible!) with stdout
// test if we wrote what we read
if ((fpread - written) != 0) {
fprintf(stderr, "We did not write what we read. Diff: %d\n",
(int) (fpread - written));
}
}
// fread() does not distinguish between EOF and error, we have to check by hand
if (feof(fp)) {
// we have read all, exit
puts("\n\n\tfinish\n");
// No, wait, we want to do it again in a different way, so: no exit
// exit(EXIT_SUCCESS);
} else {
// some error may have occured, check
if (ferror(fp)) {
fprintf(stderr, "Something bad happend while reading \"%s\"\n", filename);
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
}
// the other way is to read it byte by byte
// reset the filepointers/errors et al.
rewind(fp);
// rewind() should have reseted errno, but better be safe than sorry
errno = 0;
printf("\n\n\tread and print \"%s\" again\n\n\n\n", filename);
// read one byte and print it until end of file
while ((c = fgetc(fp)) != EOF) {
// just print. Gathering them into "source" is left as an exercise
fputc(c, stdout);
}
// clean up
errno = 0;
ret_fclose = fclose(fp);
// even fclose() might fail
if (ret_fclose == EOF) {
fprintf(stderr, "Something bad happend while closing \"%s\"\n", filename);
if (errno != 0) {
fprintf(stderr, "Error: %s\n", strerror(errno));
}
exit(EXIT_FAILURE);
}
// The macros EXIT_FAILURE and EXIT_SUCCESS are set to the correct values for
// the OS to tell it if we had an eror or not.
// Using exit() is noot necessary here but there exits teh function atexit()
// that runs a given function (e.g: clean up, safe content etc.) when called
exit(EXIT_SUCCESS);
}
You read from the file twice but only print once.
If the file is to small the first reading will read all of the contents, and the second reading will not produce anything so you don't print anything.
I believe you have to reset the pointer after using fread.
Try fseek(fp, SEEK_SET, 0) to reset the pointer to the beginning of the file. Then print the file.
I need to open a file located on Desktop(Linux). If i write the location as a string inside the fopen() function it works, but if i pass it as a variable, it doesn't work. Here is my code :
fp = fopen(readPathToFile, "r");
if (!fp){
printf("Failed to open text file\n");
exit(1);
}
else{
fscanf(fp,"%s",line);
printf("File read: %s",line);
}
If i write it like this, it shows me the content of file :
fp = fopen("home/user/Desktop/test.txt", "r");
if (!fp){
printf("Failed to open text file\n");
exit(1);
}
else{
fscanf(fp,"%s",line);
printf("File read: %s",line);
}
The child process opens the file. Here is my full code
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
int main ()
{
pid_t pid;
int mypipefd[2];
id_t child_pid;
char line[100];
char *pathToFile[100];
FILE *fp;
char buff[255];
/* create the pipe */
if (pipe(mypipefd) == -1) {
fprintf(stderr,"Pipe failed");
return 1;
}
child_pid = fork () ;
if (child_pid > 0) {
printf("Introduceti locatia catre fisier:");
fgets(pathToFile, 100, stdin);
close(mypipefd[READ]);
write(mypipefd[WRITE], &pathToFile, sizeof(pathToFile));
close(mypipefd[WRITE]);
printf("parent: write value : %s",pathToFile);
}
else if (child_pid < 0) {
fprintf(stderr, "Fork failed");
return 1;
}
else{
char *readPathToFile[100];
close(mypipefd[WRITE]);
read(mypipefd[READ], &readPathToFile, sizeof(readPathToFile));
close(mypipefd[READ]);
printf("child: read value : %s",readPathToFile);
fp = fopen(readPathToFile, "r");
if (!fp)
{
printf("Failed to open text file\n");
exit(1);
}
else{
fscanf(fp,"%s",line);
printf("File read: %s",line);
}
}
return 0;
}
Your compiler did not warn you about the type mismatch in
char *pathToFile[100];
fgets(pathToFile, 100, stdin);
(array of 100 pointers-to-char versus array of 100 chars)? Did you turn warnings off?
Also note that fgets retains the newline. Your file name probably does not end with a newline. You should replace it with a NUL (zero) byte.
Typically you don't need a debugger to track these down. A little bit of printf debugging can do wonders. :-)
Okay, so this is the root of your problem:
char *pathToFile[100];
This declares pathToFile as a 100-element array of pointers to char, not a 100-element array of char. The first thing you need to do is change that declaration to
char pathToFile[100];
Secondly, fgets will save the trailing newline from your input to the target buffer if there's room, so you'll need to remove that newline from the input:
char *newline = strchr( pathToFile, '\n' );
if ( newline )
*newline = 0;
I'm new to C file management . My teacher wanted as a homework to create a functon that copy from a source file to destination file . I created but it gives me errors all the time : Segmentation Fault .
void source_to_destination(FILE *source , FILE *destination)
{
char name_source[10], name_destination[10],line[100];
memset(line,0,sizeof(line));
memset(name_source,0,sizeof(name_source));
memset(name_destination,0,sizeof(name_destination));
read_name_file(name_source);
read_name_file(name_destination);
source = fopen(name_source,"r");
destination = fopen(name_destination,"w");
while(fgets(line,sizeof(line),source) != NULL)
{
fputs(line,destination);
}
}
When copying data from one file to another, reading and writing in binary is preferred. There are a number of reasons that reading with line-oriented input functions such as fgets or getline will fail to properly read all characters in a file. Text output functions suffer similar shortcomings (e.g. attempting to write characters outside the printable range or characters that have alternate meaning as ASCII)
Reading and writing from a file in binary mode using fread and fwrite is not any more difficult than using fgets and fputs. However, using fread and fwrite you are guaranteed a correct and accurate copy of your data by avoiding the pitfalls inherent in attempting a general file copy in text mode.
If you know there is nothing but text contained in your source file, then there is nothing wrong with copying it in text mode. That just means you will have to write another function to handle files that are not text. (and generally you don't see different copy routines based on file contents). Reading and writing in binary eliminates all of these considerations.
The following is a short example of a filecopy function that will read all bytes in a file into a buffer and then write the contents of the buffer to your destination file. (a buffered read/write is generally much more efficient and you can easily adjust the buffer size by adjusting MAXS) The function returns the number of bytes copied on success, -1 otherwise. Look it over and let me know if you have any questions:
#include <stdio.h>
#include <stdlib.h>
#define MAXS 256
int filecopy (char *source, char *dest);
int main (int argc, char **argv) {
if (argc < 3) { /* validate 2 arguments given */
fprintf (stderr, "usage: %s file1 file2\n", argv[0]);
return 1;
}
int filesize = 0;
if ((filesize = filecopy (argv[1], argv[2])) == -1) {
fprintf (stderr, "error: filecopy failed.\n");
return 1;
}
printf ("\n copied '%s' -> '%s' ('%d' bytes)\n\n",
argv[1], argv[2], filesize);
return 0;
}
int filecopy (char *source, char *dest)
{
char *buf = NULL; /* buffer used to read MAXS bytes from file */
size_t nbytes = 0; /* number of bytes read from file */
size_t idx = 0; /* file index (length) */
FILE *fp = fopen (source, "r"); /* stream pointer */
if (!fp) { /* open source for reading */
fprintf (stderr, "error: file open failed '%s'.\n", source);
return -1;
}
/* allocate MAXS size read buf initially */
if (!(buf = calloc (MAXS, sizeof *buf))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
return -1;
}
/* while data read MAXS *buf from file - realloc for next read */
while ((nbytes = fread (buf+idx, sizeof *buf, MAXS, fp)))
{
idx += nbytes; /* update total bytes read */
if (nbytes < MAXS) break; /* end-of-file reached */
/* full read - realloc for next */
void *tmp;
if (!(tmp = realloc (buf, (idx + nbytes) * sizeof *buf))) {
fprintf (stderr, "error: virtual memory exhausted.\n");
exit (EXIT_FAILURE);
}
buf = tmp;
}
fclose (fp); /* close input stream */
if (!(fp = fopen (dest, "w+b"))) { /* open output stream */
fprintf (stderr, "error: file open failed '%s'.\n", dest);
exit (EXIT_FAILURE);
}
fwrite (buf, sizeof *buf, idx, fp);
fclose (fp); /* close output stream */
free (buf);
return (int)idx;
}
Compile
gcc -Wall -Wextra -O3 -o bin/filecopy_simple filecopy_simple.c
Input File (binary)
-rw-r--r-- 1 david david 66672 Nov 19 13:17 acarsout2.bin
Use/Output
$ ./bin/filecopy_simple dat/acarsout2.bin dat/acarsout3.bin
copied 'dat/acarsout2.bin' -> 'dat/acarsout3.bin' ('66672' bytes)
Verification
$ ls -al acarsout[23]*
-rw-r--r-- 1 david david 66672 Nov 19 13:17 acarsout2.bin
-rw-r--r-- 1 david david 66672 Dec 13 14:51 acarsout3.bin
$ diff dat/acarsout2.bin dat/acarsout3.bin
$
The following code
compiles cleanly
performs the desire operation (copy a file)
perform appropriate error checking
is getting the file names from the command line
You will need to modify this to get the file names via your existing functions
always cleans up after itself including closing open files
demonstrates how to pass the FILE* variables --into-- the function
the sub function prototype, etc will need to be modified
if you want to open the files in the sub function
then have main() close them.
Here is a suggested method of performing the desired operation
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define MAX_LINE_LENGTH (256)
// prototypes
void source_to_destination(FILE *source , FILE *destination);
int main( int argc, char * argv[] )
{
if( 3 != argc )
{ // not correct number of command line parameters
fprintf( stderr, "USAGE: %s <sourceFili> <destinationFile>\n", argv[0]);
exit( EXIT_FAILURE );
}
// implied else, correct number of arguments
FILE *fp_in = NULL;
if( NULL == (fp_in = fopen( argv[1], "r") ) )
{ // then fopen failed
fprintf( stderr, "fopen for input file: %s failed due to %s\n", argv[1], strerror(errno) );
exit( EXIT_FAILURE );
}
// implied else, fopen input file successful
FILE *fp_out = NULL;
if( NULL == (fp_out = fopen( argv[2], "w") ) )
{ // then fopen failed
fprintf( stderr, "fopen for output file: %s failed due to %s\n", argv[2], strerror(errno) );
fclose( fp_in ); // cleanup
exit( EXIT_FAILURE );
}
// implied else, fopen output file successful
source_to_destination( fp_in, fp_out );
fclose( fp_in );
fclose( fp_out );
return 0;
} // end function: main
void source_to_destination(FILE *source , FILE *destination)
{
char line[ MAX_LINE_LENGTH ];
while(fgets(line,sizeof(line),source) )
{
if( EOF == fputs(line,destination) )
{ // then fputs failed
fprintf( stderr, "fputs to output file failed due to %s\n", strerror(errno) );
fclose( source );
fclose( destination );
exit( EXIT_FAILURE );
}
}
} // end function: source_to_destination
I am currently working on a ssh program and I want to be able to have full control over the terminal via networking. My question is, if I send a command to the server to run in the terminal, how do I get the output that the terminal prints? I have seen many posts saying to use the popen() command but from what I have tried I can't change directories and do other commands using this, only simple things such as ls. Is there any other way to get output from terminal besides sending it to a file like command > filetoholdcommand. Thanks in advance!
I would put this as a comment, but I dont have enough rep as I'm new. cd is a built in shell command so you want to use system(). But cd will have no effect on your process (you have to use chdir(), for that),so what you really want to do is start a shell as a subprocess via fork/exec, connect pipes to it stdin and stdout,then pipe it commands for the duration of the user session or connection.
Following code give the general idea. Basic, and flawed - use select() not usleep() for one.
int argc2;
printf( "Server started - %d\n", getpid() );
char buf[1024] = {0};
int pid;
int pipe_fd_1[2];
int pipe_fd_2[2];
pipe( pipe_fd_1 );
pipe( pipe_fd_2 );
switch ( pid = fork() )
{
case -1:
exit(1);
case 0: /* child */
close(pipe_fd_1[1]);
close(pipe_fd_2[0]);
dup2( pipe_fd_1[0], STDIN_FILENO );
dup2( pipe_fd_2[1], STDOUT_FILENO );
execlp("/bin/bash", "bash", NULL);
default: /* parent */
close(pipe_fd_1[0]);
close(pipe_fd_2[1]);
fcntl(pipe_fd_2[0], F_SETFL, fcntl(pipe_fd_2[0], F_GETFL, NULL ) | O_NONBLOCK );
while(true)
{
int r = 0;
printf( "Enter cmd:\n" );
r = read( STDIN_FILENO, &buf, 1024 );
if( r > 1 )
{
buf[r] = '\0';
write(pipe_fd_1[1], &buf, r);
}
usleep(100000);
while( ( r = read( pipe_fd_2[0], &buf, 1024 ) ) > 0 )
{
buf[r-1] = '\0';
printf("%s", buf );
}
printf("\n");
}
}
You want the "popen" function. Here's an example of running the command ls /etc and outputting to the console.
#include <stdio.h>
#include <stdlib.h>
int main( int argc, char *argv[] )
{
FILE *fp;
int status;
char path[1035];
/* Open the command for reading. */
fp = popen("/bin/ls /etc/", "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit;
}
/* Read the output a line at a time - output it. */
while (fgets(path, sizeof(path), fp) != NULL) {
printf("%s", path);
}
/* close */
pclose(fp);
return 0;
}
I have some gzipped files that I want to read in C via fopen and fscanf. Is there anyway to do this without having to gunzip the files to temporary files?
Thanks.
You can use libzlib to open the gzipped files directly.
It also offers a "gzopen" function that behaves similar to fopen but operates on gzipped files. However, fscanf would probably not work on such a handle, since it expects normal FILE pointers.
If popen is fair game, you can do it with fopen and fscanf:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
const char prefix[] = "zcat ";
const char *arg;
char *cmd;
FILE *in;
char buf[4096];
if (argc != 2) {
fprintf(stderr, "Usage: %s file\n", argv[0]);
return 1;
}
arg = argv[1];
cmd = malloc(sizeof(prefix) + strlen(arg) + 1);
if (!cmd) {
fprintf(stderr, "%s: malloc: %s\n", argv[0], strerror(errno));
return 1;
}
sprintf(cmd, "%s%s", prefix, arg);
in = popen(cmd, "r");
if (!in) {
fprintf(stderr, "%s: popen: %s\n", argv[0], strerror(errno));
return 1;
}
while (fscanf(in, "%s", buf) == 1)
printf("%s: got [%s]\n", argv[0], buf);
if (ferror(in)) {
fprintf(stderr, "%s: fread: %s\n", argv[0], strerror(errno));
return 1;
}
else if (!feof(in)) {
fprintf(stderr, "%s: %s: unconsumed input\n", argv[0], argv[1]);
return 1;
}
return 0;
}
For example:
$ zcat file.gz
Every good boy does fine.
$ ./gzread file.gz
./gzread: got [Every]
./gzread: got [good]
./gzread: got [boy]
./gzread: got [does]
./gzread: got [fine.]
Do not use
sprintf(cmd, "zcat %s", argv[1]);
popen(cmd,"r");
to open .gz files. Properly escape argv[1] instead. You may otherwise end up with a vulnerability, especially when some injects an argument argv[1] such as
123;rm -rf /
It already helps to change the above instruction into
sprintf(cmd, "zcat \'%s\'",argv[1]);
You may also want to escape characters such as '\0', '\'', '\;' etc.
Newbie attempt at gzscanf():
#include <stdio.h>
#include <stdarg.h>
#include <zlib.h>
#define MAXLEN 256
int gzscanf(gzFile *stream, const char *fmt, ...) {
/* read one line from stream (up to newline) and parse with sscanf */
va_list args;
va_start(args, fmt);
int n;
static char buf[MAXLEN];
if (NULL == gzgets(stream, buf, MAXLEN)) {
printf("gzscanf: Failed to read line from gz file.\n");
exit(EXIT_FAILURE);
}
n = vsscanf(buf, fmt, args);
va_end(args);
return n;
}
You can use zlib and wrap it to a regular file pointer, this way you can use fscanf,fread,etc. transparently.
FILE *myfopen(const char *path, const char *mode)
{
#ifdef WITH_ZLIB
gzFile *zfp;
/* try gzopen */
zfp = gzopen(path,mode);
if (zfp == NULL)
return fopen(path,mode);
/* open file pointer */
return funopen(zfp,
(int(*)(void*,char*,int))gzread,
(int(*)(void*,const char*,int))gzwrite,
(fpos_t(*)(void*,fpos_t,int))gzseek,
(int(*)(void*))gzclose);
#else
return fopen(path,mode);
#endif
}
You can use zlib, but it will require you to replace your I/O calls to be zlib-specific.
you have to open a pipe to do this. The basic flow in pseudo code is:
create pipe // man pipe
fork // man fork
if (parent) {
close the writing end of the pipe // man 2 close
read from the pipe // man 2 read
} else if (child) {
close the reading end of the pipe // man 2 close
overwrite the file descriptor for stdout with the writing end of the pipe // man dup2
call exec() with gzip and the relevant parameters // man 3 exec
}
You can use the man pages in the comments for more details on how to do this.
It's quite simple to use zlib to open .gz files. There's a reasonable manual over at zlib.net.
Here's a quick example to get you started:
#include <stdio.h>
#include <zlib.h>
int main( int argc, char **argv )
{
// we're reading 2 text lines, and a binary blob from the given file
char line1[1024];
char line2[1024];
int blob[64];
if (argc > 1)
{
const char *filename = argv[1];
gzFile gz_in = gzopen( filename, "rb" ); // same as fopen()
if (gz_in != NULL)
{
if ( gzgets( gz_in, line1, sizeof(line1) ) != NULL ) // same as fgets()
{
if ( gzgets( gz_in, line2, sizeof(line2) ) != NULL )
{
if ( gzfread( blob, sizeof(int), 64, gz_in ) == 64 ) // same as fread()
{
printf("Line1: %s", line1);
printf("Line2: %s", line2);
// ...etc
}
}
}
gzclose(gz_in); // same as fclose()
}
else
{
printf( "Failed to GZ-open [%s]\n", filename );
}
}
return 0;
}
Remember to link with zlib, under UNIX gcc ... -lz