reallybadprogrammer
reallybadprogrammer

Reputation: 27

Reading from a file indicated by a file

I'm trying to do a program that opens files in a directory that are included in another. Simply put: Open file -> Read which files to open -> open and show their contents.

Here's the directory:

-rwxrwx--- btag_test.c
-rwxrwx--- file.txt
drwxrwxr-x samples

The "file.txt" is just a list of files to open:

sample0001.mp3
sample0002.mp3
etc.

I'm trying to get their hexdump in plaintext to get header with:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void show(char *filename) {
    char aux[60] = "sample/";
    strcat(aux, filename);
    printf(">>>>%s>>>>\n", aux);
    FILE *ptf = fopen(aux, "rb");
    unsigned long long byte;
    while (byte=fgetc(ptf) != EOF) {
        printf("%llx",byte);
    }
}

int main(int argc, char **argv) {

    FILE *f = fopen(argv[1], "r");
    if (f==NULL) printf("Erro");
    else printf("OK");

    char tmp[50];
    char files[1000][50];
    int i=0;
    while( fscanf(f, "%s", tmp) == 1) {
        printf("%s\n", tmp);
        strcpy(files[i++], tmp);
    } 
    printf(">>%s\n", files[3]);
    show(files[3]);

    return 0;
}

I'm not being able to open file, since I get a "core dumped" message everytime. I'm assuming it's because I'm not really opening the file.

The usage is:

./a.out file.txt

I know the program is relatively stupid, but my goal is to later analyse the output of thing with fseek to get it's header - but I have to open the damned thing first...

Would appreciate help with this and pointers on how to extract a string of bytes within a certain offset with fseek after opening the file.

Upvotes: 0

Views: 61

Answers (1)

user3629249
user3629249

Reputation: 16540

regarding:

unsigned long long byte; 
while (byte=fgetc(ptf) != EOF) { 

the type returned from fgetc() is int, not unsigned long long.

after:

FILE *ptf = fopen(aux, "rb"); 

should be:

if( ! ptf ) 
{ 
    perror( "fopen failed" ); 
    exit( EXIT_FAILURE ); 
} 

which will output both the fopen failed message and the text reason the system thinks the failure occurred to stderr

regarding:

while( fscanf(f, "%s", tmp) == 1) { 

since tmp[] is 50 characters long and the %s always appends a NUL byte to the input, if the line in the file is greater than 49 characters, a buffer overflow will occur, result in undefined behavior.

Suggest:

while( fscanf(f, "%49s", tmp) == 1) {

regarding:

while (byte=fgetc(ptf) != EOF) {

since byte is unsigned, it will NEVER recognize EOF (which is usually -1). Also, the statement is missing a needed set of parens.

Suggest:

while ( (byte=fgetc(ptf)) != EOF) {

so the assignment is performed before the comparison. Your compiler should have told you about this problem.

regarding:

if (f==NULL) printf("Erro");
  1. please, only one statement per line.
  2. error messages are to be output to stderr, not stdout.
  3. since the call to fopen() failed, should exit the program.

Suggest:

if (f==NULL) 
{ 
    perror( "fopen for the list of files to display failed" );
    exit( EXIT_FAILURE ); 
} 

Note: exit the program on failure. DO not try to read from the file when the call to fopen() failed.

regarding:

drwxrwxr-x samples

and

char aux[60] = "sample/";

Notice the different spelling? So you are not going to be able to open any of the files with that spelling error.

for safety, this statement:

while( fscanf(f, "%s", tmp) == 1) { 

should be:

while( i<1000 && fscanf(f, "%49s", tmp) == 1) {

Note the check for too many files and the limit of each filename to be less than 50.

regarding:

printf(">>%s\n", files[3]); 
show(files[3]); 

What about when the number of files is less than 4? (remembering that array indexes start at 0).

regarding:

while (byte=fgetc(ptf) != EOF) 
{
    printf("%llx",byte); 

the code is only reading 1 8bit char at a time, not a unsigned long long.

when compiling, always enable the warnings, then fix those warnings. for gcc, at a minimum use:

-Wall -Wextra -Wconversion -pedantic -std=gnu11

Note: other compilers use different options to produce the same results.

Upvotes: 1

Related Questions