LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   C: loading a file with files to open using other program (https://www.linuxquestions.org/questions/programming-9/c-loading-a-file-with-files-to-open-using-other-program-4175627793/)

BW-userx 04-16-2018 02:49 PM

C: loading a file with files to open using other program
 
Let me see if I can explain this well enough. This is C programming. I have a link List that I use to put path/filename into. It works fine. I just used it for this function that opens and reads a file with the path/filename in the file and put them into the link list instead. It works too.

It is when I am reading the files out of the lest after it has been populated by the file that it is causing me issues. I am getting a bad image return on the file when it uses the file to populate it.

the kicker is. When I only put one path/filename into the file then load that it works fine. It loads the image and displays it without issue, yet, anything more than that it goes back to giving me errors bad image.

Code:

filename /home/userx/Pictures/slack-wallpapers-0.446/images/slack-orange-1600x1200.jpg

Bad Image: /home/userx/Pictures/slack-wallpapers-0.446/images/slack-orange-1600x1200.jpg

it's the same output from the link list if loaded directly from the directory. Just a string that holds the path/filename.

so being that it works with just one path/filename within a file but no more, then logic states it has to be the file itself. But what could be doing that?
end line off every line within the file, if yes, then how to fix that, if no, then what?

Code:

void read_file(FILE *ptr, char *file)
{
    char * line = NULL;
    size_t len = 0;

    ptr = fopen(file, "r");
    if (ptr == NULL)
    {
        printf("Cannot Open File %s\n",file);
        exit(1);
    }
    while ((getline(&line, &len, ptr)) != -1)
    {
        //printf("%s", line);
        add_2_front(&filelist ,line);
    }
    fclose(ptr);
}


BW-userx 04-16-2018 02:58 PM

HAHAHA
Sometimes It helps to write it out. :D
ANSWER:
added
Code:

len = strlen(line);
line[len - 1] = '\0';

Code:

void read_file(FILE *ptr, char *file)
{
    char * line = NULL;
    size_t len = 0;

    ptr = fopen(file, "r");
    if (ptr == NULL)
    {
        printf("Cannot Open File %s\n",file);
        exit(1);
    }
    while ((getline(&line, &len, ptr)) != -1)
    {
        //printf("%s", line);
        len = strlen(line);
        line[len - 1] = '\0';
        add_2_front(&filelist ,line);
    }
    fclose(ptr);
}

Now it's working. Thank you all that participated in this. :D

rtmistler 04-16-2018 03:05 PM

I've done the same to truncate things like the \r\n in a string where I didn't need that component.

Stylistically I've just done it differently:
Code:

line[strlen(line) - 1] = 0x00;

BW-userx 04-16-2018 03:10 PM

Quote:

Originally Posted by rtmistler (Post 5843891)
I've done the same to truncate things like the \r\n in a string where I didn't need that component.

Stylistically I've just done it differently:
Code:

line[strlen(line) - 1] = 0x00;

nice one liner, let me toss that in the mix and see how if it works.
Yep that work too. I'll keep it!
thanks! :hattip:

keefaz 04-16-2018 05:35 PM

Don't forget to free(line) after the loop

man getline
Code:

...
      If *lineptr is set to NULL and *n is set 0 before the call, then getline()
      will allocate a buffer for storing the line.  This buffer should be  freed
      by the user program even if getline() failed.
...

Edit: also getline() returns the number of characters read, it's possible to avoid the strlen() call

BW-userx 04-16-2018 06:08 PM

Quote:

Originally Posted by keefaz (Post 5843938)
Don't forget to free(line) after the loop

man getline
Code:

...
      If *lineptr is set to NULL and *n is set 0 before the call, then getline()
      will allocate a buffer for storing the line.  This buffer should be  freed
      by the user program even if getline() failed.
...

Edit: also getline() returns the number of characters read, it's possible to avoid the strlen() call

sweet, got it!!
Code:


void read_file(FILE *ptr, char *file)
{
    char * line = NULL;
    size_t len = 0;
    size_t big = 0;

    ptr = fopen(file, "r");
    if (ptr == NULL)
    {
        printf("Cannot Open File %s\n",file);
        exit(1);
    }
    while ((big = getline(&line, &len, ptr)) != -1)
    {
      //clean up end line
        //line[strlen(line) - 1] = 0x00;
        line[big - 1] = 0x00;
        add_2_front(&filelist ,line);
    }
    fclose(ptr);
    free(line);
}

Now I got a re-tar it then upload it to Sourceforge again .. :p

Thanks ...

NevemTeve 04-16-2018 11:08 PM

A variant:
Code:

if (len>0 && line[len-1]=='\n')
    line[--len]= '\0';
if (len>0 && line[len-1]=='\r')
    line[--len]= '\0';
if (len==0) skip-empty-line;


keefaz 04-17-2018 04:58 AM

An empty line has to contain at least one char, no? (newline)

NevemTeve 04-17-2018 05:10 AM

When the new-line (LF) and the optional carriage-return (CR) have been stripped, it has no characters.

rtmistler 04-17-2018 07:14 AM

Quote:

Originally Posted by keefaz (Post 5843938)
Don't forget to free(line) after the loop

man getline
Code:

...
      If *lineptr is set to NULL and *n is set 0 before the call, then getline()
      will allocate a buffer for storing the line.  This buffer should be  freed
      by the user program even if getline() failed.
...

Edit: also getline() returns the number of characters read, it's possible to avoid the strlen() call

At first I thought "interesting catch", and then thought "this is why I use gets() or fgets()", but then decided to look up the man page and confirm my bearings. The difference is that fgets() expects a pre-allocated, or even a static buffer to be handed to it, and that is what I do. And since I typically would do a file read, (or serial port read) repeatedly, I'd rather not deal with the complications of alloc/free all the time and instead have the buffer ready for the functions use.

I do realize this can cause hassles with unexpected strings that are too long, however the functions will not give you more than you have specified for the length of your buffer they will give you one byte less than your buffer length and terminate it with a NULL. For me, in the unexpected case, there really is a problem somewhere that needs to be dealt with.

BW-userx 04-17-2018 09:39 AM

Quote:

Originally Posted by keefaz (Post 5844097)
An empty line has to contain at least one char, no? (newline)

end line or null, new line forces a carriage return on ones out put. say if you added a new line to the end of every line in your file then it defeats the '\n' on printf. if added in your printf then you'll be getting two new lines printed out each time.

length -1 due to the array effect then adds the null on the end;
Code:

line[len - 1] = 0x00;
in I think that is hexi notation, complements of @rtmistler

keefaz 04-17-2018 09:59 AM

Quote:

Originally Posted by NevemTeve (Post 5844100)
When the new-line (LF) and the optional carriage-return (CR) have been stripped, it has no characters.

Yes, sorry it was late and I read your code as if / else statements, which is not the case in your successive trim jobs.

keefaz 04-17-2018 10:02 AM

Quote:

Originally Posted by BW-userx (Post 5844204)
end line or null, new line forces a carriage return on ones out put. say if you added a new line to the end of every line in your file then it defeats the '\n' on printf. if added in your printf then you'll be getting two new lines printed out each time.

length -1 due to the array effect then adds the null on the end;
Code:

line[len - 1] = 0x00;
in I think that is hexi notation, complements of @rtmistler

I misread the NevemTeve suggested code. By the way check it, it deals with string ends variations that you may (or not) meet

BW-userx 04-17-2018 10:03 AM

Quote:

Originally Posted by NevemTeve (Post 5844015)
A variant:
Code:

if (len>0 && line[len-1]=='\n')
    line[--len]= '\0';
if (len>0 && line[len-1]=='\r')
    line[--len]= '\0';
if (len==0) skip-empty-line;


Oh yeah, now that I look at it closer, I see what's going on here. check, remove and replace as needed tactics. good job. thinking ahead of the turtle. ;)

Modifed
Code:

//add null to end
if (big>0 && line[big-1]=='\n')
  line[--big]= 0x00;
if (big>0 && line[big-1]=='\r')
  line[--big]= 0x00;
if (big==0) /*skip-empty-line*/; //left here just cuz, slows it down a millisecond or so I do suppose.

if the file is badly formed I already have error handling on the imlib2 side that discards the file name then gets the next one in line, and keeps repeating until it gets a successful image.

BW-userx 04-17-2018 10:24 AM

Quote:

Originally Posted by keefaz (Post 5844211)
I misread the NevemTeve suggested code. By the way check it, it deals with string ends variations that you may (or not) meet

it is running right now with out any issues, due to that notation 0x00 and I just added NevemTeve snippet and put the two together and its running fine so far, I loaded up a bunch of image paths in the file. I do think I should maybe make up some other various types of image formats to check it to see what all it can load, ImLib2 is suppose to handle a hand full of types.

this 0x00 is just saying this '\0' in a different language.

This too works BTW
Code:

if ( (big>0 && line[big-1]=='\n') || (big>0 && line[big-1]=='\r') )
  line[--big]= 0x00;



All times are GMT -5. The time now is 03:06 AM.