image size

Pages: 12
Hi,

I'm trying to obtain the size in bytes of a picture,
this is my code, but I keep getting the following error:

error: expected constructor, destructor, or type conversion before ‘(’ token
fseek(fp, 0L, SEEK_END);

I am not sure how to fix this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <fstream>
#include<stdio.h>

using namespace std;


char file_name[] ={"picture.jpeg"};

FILE* fp = fopen(file_name, "rb"); 

fseek(fp, 0L, SEEK_END); 

long int res = ftell(fp); //file size

fclose(fp); 

printf( res); 
Last edited on
The above code is a mixture of C++ headers followed by C functions and code.

Here is the same code in C and C++

First C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

int main()
{
    char file_name[] ="picture.jpeg";
    
    FILE* fp = fopen(file_name, "rb"); 
    
    fseek(fp, 0L, SEEK_END); 
    
    long int res = ftell(fp); //file size
    
    fclose(fp); 
    
    printf("%ld", res); 
}


Now C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    char file_name[] = "picture.jpeg";
    
    ifstream fin(file_name, ios::binary); 
    
    fin.seekg(0, ios_base::end);

    streampos res = fin.tellg(); // file size
    
    fin.close(); 
    
    cout << res;
}


Though it is possible to mix the two languages, it might be better to learn one or the other, to avoid confusion.
@chervil,
a few questions for you:

is your C code supposed to work with a c++ compiler?
Because I have exactly the same code and the abovementioned error keeps showing.

Is there a way to implement this line: FILE* fp = fopen(file_name, "rb");
in your c++ code?

I can see that you wrote both programs within a function. Is it necessary?
For some reasons I would like all the lines to be "global".

Thank you.
See other thread for more of this: http://www.cplusplus.com/forum/general/267803

I suggest
auto fileSize = filesystem::file_size(filesystem::path("C:/picture.jpeg"));
to get the file size in bytes.

I can see that you wrote both programs within a function. Is it necessary?
For some reasons I would like all the lines to be "global".

If you don't have a main function, your code will never be run. Where would it start executing from?
Last edited on

is your C code supposed to work with a c++ compiler?
Because I have exactly the same code and the abovementioned error keeps showing.

I used the same C++ compiler for both, though I did save the pure C version with the file extension of ".c" rather than ".cpp". Usually the compiler automatically chooses to compile as C that way.

Is there a way to implement this line: FILE* fp = fopen(file_name, "rb");
in your c++ code?

You would need the C header file #include <cstdio> . Your original code didn't have that line.

I can see that you wrote both programs within a function. Is it necessary?

Every program in C or C++ must always have a main() function. That is where execution begins. Any other functions are optional, but they often help to keep things manageable.

For some reasons I would like all the lines to be "global".

You can declare variables such as file_name or res to be global. However, usually global variables are kept to a minimum, it helps avoid unexpected interactions between different parts of the code.
Last edited on
what if instead of a single picture, I would like to get access to all the pictures inside a folder ?

I have implemented this line of code, but it returns -1.

"/home/Desktop/pics/*.jpeg"
That's definitely a non-starter; to C++, that is just a string with a * in it.

You would need to iterate over all the files in the folder. That is, however, a pretty simple thing to do. We just create a "directory_iterator" pointed at the directory, and use it to get each entry in that directory in turn. Something like this would do it:


1
2
3
4
5
6
7
8
9
for (const auto& entry : fs::directory_iterator(filesystem::path("/home/Desktop/pics/"))) 
{
  // HERE, entry  is an entry from that directory
  if ((entry.is_regular_file())  // just files, please. Not other directories
  {
      const auto filenameString = entry.path().filename().string();
      // filenameString  is now the name of the file, to be checked
     // check that it ends with jpeg or some some, and then just do exactly what you do with a single file
    
Last edited on
I believe that for this code, I'd have to include <filesystem>, which has been giving me some problems.
Is there perhaps another way?
There is, but until C++17, C++ had no conception of any kind of underlying filesystem whatsoever; all such functionality is instead provided by the operating system on which it runs (which is, of course, still the case; C++17 simply added a layer of abstraction with the <filesystem> library calling on the OS for you).

Your options are to use the OS API directly, or to identify a third-party library which would do that for you (and leave you to call on that thrid-party library).

If you identify your OS, you will be able to look up the API and see what headers and what functions are provided.

if you need a simple fix to get it done, call dir or ls with the correct parameters eg "dir /b c:\foo\*.jpg > file.txt" and read that file for the list of files to open. If that is too crude for you, you can use the APIs etc. Alternately you can handle 1 file in your program and call it with for each on all the files.
Last edited on
@ jonnin,
I am not sure what you mean.
May you kindly provide an example?

@repeater,
what I mean is: is there a way to do so without using <filestream> at all ?
on windows, something like...

system("dir /b > filelist.txt");
ifstream ifs.open("filelist.txt");

while( getline(ifs, filename) )
{
... open filename and do what you want to do to a single file.
}

Its crude, but its short & sweet too. Ive learned to embrace crude when I just want to get something small done.
Last edited on
@repeater,
what I mean is: is there a way to do so without using <filestream> at all ?


I assume (guess) you mean "filesystem"?

This suggests to me that you don't quite understand what <filesystem> is.

<filesystem> is a header (and as the meaning is often intended, a library behind that header).

If you do NOT have this in your code anywhere:
#include <filesystem>
then you are NOT using <filesystem>

So when you say
is there a way to do so without using <filestream> at all ?
I have to wonder what you mean; what I told you about using your OS API is a way to do it without using <filesystem>, so what do you mean?
Last edited on
OS libraries and the crude code I gave, none require filesystem. I also lack filesystem; it seems to not be fully supported. I recommend, if you are doing something serious, getting a compiler that supports it. Its cleaner. Window's microsoft gui tools have a nice folder iteration set of tools.
Last edited on
@ repeater,

I mistakenly wrote "filestream" but you correctly guessed that I meant "filesystem".
Of course I know that filesystem is an header, but since I'm having an hard time installing it, I asked you for another way without it.
My operative system is Linux, but I am quite unfamiliar with the concept of API.

@ jonnin
Since I am on linux, does it make a difference?
On Linux, the typical directory traversing header is dirent.h ; functions like opendir, readdir and so on.

Here's a link that would get you started: http://www.manpagez.com/man/3/opendir/

Shame you can't get a C++17 compatible compiler; filesystem takes away a lot of the awkwardness of doing it yourself.

Although if it's a fairly mainstream Linux, I'd expect an up-to-date GCC collection to be available.

if your linux does not support M$ dir commands (some have scripts to make ls act like dir to be cross platform friendly) then you need ls -A1 *.jpg or whatever instead of dir \b
** you really should have been able to figure that out; linux is hard to use without knowing the basic console commands. I had to look up the naked format option, but you should have known ls - something would do it and gotten it from there...

and, I came in late and missed your goal. if you just want the file sizes, instead of making a list and getting each one, make a list with the size on it.
that would be something like this (there are many ways to do it in unix, none of them clean)
C:\c>ls x -lt | cut -d" " -f6-
21 Sep 27 15:51 x

(x is 21 bytes here). you would have to dig out the size with a simple parse of the line or play with the command to get it down to name and size only.

at some point my approach will have you give in and use the library though, if you want anything the OS can't hand you on a platter it starts becoming too much work.
Last edited on
@jonnin
you really should have been able to figure that out.
you should have known

I am very new to linux, therefore I have to start somewhere.
If I already knew these things, I wouldn't be asking, would I?

@repeater
Shame you can't get a C++17 compatible compiler;

Maybe I can, but as I am a beginner, I am not sure how to find out.
If you have any tips, feel free to share.
I am very new to linux, therefore I have to start somewhere.
If I already knew these things, I wouldn't be asking, would I?

That is fair. Again, I encourage you in the strongest way possible, if this is the case, to put the c++ down for a couple of days and get familiar with the unix command prompt. You don't need to know every tool it offers, but you should be able to do a few things...
- copy a file (cp)
- list the files (ls)
- search files for things (grep)
- compile a program by hand (g++ with options)
- execute your program (you may need ./programname to do this, you can hack the ./ away in .profile for your account)
- redirect your program's output and input to/from text files (program > file and program < file)
- make a folder
- delete a file (rm)
- make a simple shell script, eg to compile a program using g++ and options...
- chmod a file (so you can make the above script executable and give yourself read permissions on things etc)
- pipe one command into another to string together several tools at once
- check out the other stuff like awk, just poke around see what seems useful to know

Just the above will make working with linux and c++ much more tolerable for you. You can do most of that with their guis but not all of it, and I can't stress enough how powerful basic competence at the console is and how much more you can do quickly with a few tools.

You compiler may already be c++17 capable. g++ and options...
g++ filename.cpp filename2.cpp ... -Wall -Wextra -std=c++17 -pedantic-errors -O3 -s

I was not trying to be mean. But, my opinion only, if you do not even know ls console command, you have major gaps in your skills that will make trying to use linux like pulling teeth. Tend to this gap, and the c++ efforts will become much easier -- you will see :)

All I have at work is a toy compiler and notepad. You can do a ton with very little.
Last edited on
@jonnin
thank you.
As I mentioned, I started really recently with linux, so I haven't had a chance yet to explore the terminal in its full potential, although I use it to install and run programs/libraries and I can do a few small things like searching for files and so on. As right now, I only need the terminal to run the programs.
Thanks for the tips.

@everybody:
after using dirent.h to get access to a specific directory, I wanted to know what type of variable did I get.
The outcome is "A256_c", which is something that I cannot find anywhere online.
Can anyone tell me what kind of variable this is?

Pages: 12