Hi All,

I need help to sort out my C Practical question. I am new to C and looking forward to do programming can some one help for the following.


1. How to write a program in c to calculate file size from KB to Bits?
2. How to write a program to find the estimated time needed to receive a 4000KB file at the rate in ADSL connections range from 256000b/sec to 1500000b/sec.
3. How to write a program to find the estimated time needed to receive a 4000KB file at the rate where 300 KB took 10 Sec to get transfered.

Regards,

Alex

1) limits.h has CHAR_BIT that defines the number of bits in a byte for your machine. Just find the file size and multiply by CHAR_BIT.

2) This wants two answers -- convert KB to bytes by multiplying by 1024, then divide that answer by the number bytes per second to get the answer.

3) simple 4th grade math problem that you should be able to figure out with pencil & paper.

Hi Dragon,

Thanks for the answer. I do understand it easy with a pencil and paper, but I am asking for a program which is return in C language. where it calculate a 44KB file into bits and give the output while compiling.

If you could help that will be great.

Regrads,
Alex

Yes I can help you but not write the program for you. Give it a try yourself and post what you have done.

To find the size of the file first use FILE pointer and call fopen() to open it for reading, then call fseek() to move the file pointer to the end of the file, call ftell() to get current location, which will be the file size. After that call fclose() to close the file handle. Now you have all the information to do the calculations.

You will have to read your textbook to find out how to use each of the functions I mentioned above. You can also find them online by using google.

Comments
Sound advise

I am asking for a program which is return in C language

I'm the giver and you're the receiver. copy it directly into your assignment and hand it in.

then come back and tell me how high your grade was. i'm certain you will get an "A"

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <time.h>
#include <math.h>


#define MAX_FILENAME_LEN    256


int main()
{
   char filename[MAX_FILENAME_LEN], quitstring[5], *ptr;
   struct stat filestats;
   time_t filetime;
   size_t length;
   off_t filesize;
   int stop=0, power, i;

   do
   {
      printf("\nenter filename, or \"quit\" to exit: ");
      if (fgets(filename,MAX_FILENAME_LEN,stdin) == 0)
         continue;

      length=strlen(filename);
      filename[--length] = 0;      // chomp newline

      for (i=0; i<4; i++)         // test for "quit"
         quitstring[i] = tolower(filename[i]);
      quitstring[4]=0;
      if (strcmp(quitstring,"quit") == 0)
      {
         stop = 1;
         continue;
      }

      errno=0;
      if (stat(filename, &filestats) < 0)
      {
         printf(" -- FILE <%s>: %s\n",filename,strerror(errno));
         continue;
      }

      filetime = filestats.st_mtime;
      filesize = filestats.st_size;

      if (filesize/pow(2,20)>1)   //mega
         power=20;
      else                   //kilo
         power=10;

      printf("\n -- FILE: <%s>\n",filename);
      printf("    DATE: last modified %s",
               asctime(localtime(&filetime)));
      printf("    SIZE: %ld Bytes (%5.03f %s, %ld bits)\n",
               filesize,
               (float)filesize/(float)pow(2,power),
               (power>10)?"MB":"KB",
               filesize*8);
      printf("    XMIT: %dh %2dm %2ds <- 30kbps modem\n",
            filesize/10800000,filesize/180000%60,filesize/3000%60);
      printf("          %dh %2dm %2ds <- 1.5Mbps DSL\n",
            filesize/540000000,filesize/9000000%60,filesize/150000%60);
      printf("          %dh %2dm %2ds <- 8.0Mbps Broadband\n",
            filesize/2800000000,filesize/48000000%60,filesize/800000%60);

   } while (!stop);

   return 0;
}

> i'm certain you will get an "A"
Considering that it takes only one key press to cause it to lock up in an infinite loop, that's a rather optimistic opinion.

Not to mention accessing undefined data if the entered filename is shorter than 4 characters.

Unless of course that was your intention ;)

baah.

it was 2am... :P

my point was to try and make it so obviously NOT his own work that he got busted for cheating.

not that anything i did was especially clever or noteworthy --- just that if this kid cant figure out how to programmatically divide by 1024 or multiply by 8... I'd just love to see his face and listen to his stammering when called into the office to explain how "his" program works.

Considering that it takes only one key press to cause it to lock up in an infinite loop, that's a rather optimistic opinion.

Not to mention accessing undefined data if the entered filename is shorter than 4 characters.

wait a minute... i don't believe that's the case. did you find these bugs by running it, or did you just determine this by inspection?

because i can neither cause it to enter an infinite loop, nor does it misbehave for file entry less than 4 chars. it works exactly as it should.

so why ya gotta be a hater? :P


.

*ptr; decoration pointer. Not used at all. if (fgets(filename,MAX_FILENAME_LEN,stdin) == 0) fgets() returns a pointer. if( fgets( filename, MAX_FILENAME_LEN, stdin ) == NULL ) filename[--length] = 0; // chomp newline 0 is not the same than '\0'. The '\n' is not guarantee to be there. quitstring[i] = tolower(filename[i]); tolower requires the ctype.h header file. quitstring[4]=0; quitstring[4] = '\0';

printf("    XMIT: %dh %2dm %2ds <- 30kbps modem\n",
            filesize/10800000,filesize/180000%60,filesize/3000%60);
      printf("          %dh %2dm %2ds <- 1.5Mbps DSL\n",
            filesize/540000000,filesize/9000000%60,filesize/150000%60);
      printf("          %dh %2dm %2ds <- 8.0Mbps Broadband\n",
            filesize/2800000000,filesize/48000000%60,filesize/800000%60);

filesize is a long, therefore either you cast to int or you use the %ld format.

>>if (fgets(filename,MAX_FILENAME_LEN,stdin) == 0) fgets() returns a pointer.
Yes, but 0 is the same as NULL -- NULL is defined as 0

>>0 is not the same than '\0'.
Yes it is.

>>quitstring[4]=0; quitstring[4] = '\0';
The two are equivalent

>>if (fgets(filename,MAX_FILENAME_LEN,stdin) == 0) fgets() returns a pointer.
Yes, but 0 is the same as NULL -- NULL is defined as 0

>>0 is not the same than '\0'.
Yes it is.

>>quitstring[4]=0; quitstring[4] = '\0';
The two are equivalent

I am aware that people use them as equivalent. Still NULL is a pointer defined as NULL ((*void)0)
Concerning 0 and '\0'. I still affirm that they are not the same. 0 is an integer and '\0' is a char.

Ancient Dragon is right. Aia, what you're talking about is an "allowed" definition of NULL. not the required definition.

What is NULL and how is it #defined?

As a matter of style, many programmers prefer not to have unadorned 0's scattered through their programs. Therefore, the preprocessor macro NULL is #defined (by <stdio.h> or <stddef.h>) with the value 0, possibly cast to (void *). A programmer who wishes to make explicit the distinction between 0 the integer and 0 the null pointer constant can then use NULL whenever a null pointer is required.

Using NULL is a stylistic convention only; the preprocessor turns NULL back into 0 which is then recognized by the compiler, in pointer contexts, as before. In particular, a cast may still be necessary before NULL (as before 0) in a function call argument. The table under question 5.2 above applies for NULL as well as 0 (an unadorned NULL is equivalent to an unadorned 0.

References: K&R1 Sec. 5.4 pp. 97-8
K&R2 Sec. 5.4 p. 102
ANSI Sec. 4.1.5, Sec. 3.2.2.3
ISO Sec. 7.1.6, Sec. 6.2.2.3
Rationale Sec. 4.1.5
H&S Sec. 5.3.2 p. 122, Sec. 11.1 p. 292

...

Nevertheless, ANSI C allows the alternate definition #define NULL ((void *)0) for NULL. Besides potentially helping incorrect programs to work (but only on machines with homogeneous pointers, thus questionably valid assistance), this definition may catch programs which use NULL incorrectly (e.g. when the ASCII NUL character was really intended;

--http://sourceware.org/ml/newlib/1998/msg00017.html

Now your criticism of filename[--length] = 0; // chomp newline because

The '\n' is not guarantee to be there.

This is arguable. the likelihood that someone is going to type a filepathname longer than 255 chars is small, but could technically be a gotcha. still, they've exceeded the buffer and it doesnt matter that they lost the newline, the pathname is going to be invalid, and they will get a message saying that.

if that's all you folks can find, then im pretty happy with my 20 minute code knocked out at 2am after bar close :-D

Concerning 0 and '\0'. I still affirm that they are not the same. 0 is an integer and '\0' is a char.

no -- '\0' is the same as 0 -- put another way they are both 0x00. You can easily prove this yourself by using a debugger to view the contents of a character buffer after inserting both a 0 and a '\0'. Or write a hex dump of the buffer.

or simpler yet:

int main()
{
    char buf1[6] = {0,0,0,0,0,0};
    char buf2[6] = {'\0','\0','\0','\0','\0','\0'};
    int x = memcmp(buf1,buf2,6);
   printf("%d\n", x);

return 0;
}
Comments
Sorry, C++ is not C
concise. and definitive. i have much to learn.

> or did you just determine this by inspection?
One by just reading the manual. fgets() returns NULL on EOF. You signal EOF by pressing either ctrl-z or ctrl-d (depending on your OS). In the absense of a call to clearerr() say, then once fgets() returns NULL because of EOF, calling it again will still return NULL because you've done nothing to fix it.

The other by inspection - the for loop I mentioned. Assertions like "works for me" don't carry a lot of weight, and simple tests which don't result in a crash only serve to prove the presense of functionality, not the absense of bugs.
You type in 2 characters, it loops 4 times - that's gotta be bad news at some point even if it seems benign in this case.

okay damn. you got me there...

(*shuffles a bit, kicks at the dirt*)

but at this point, I will insert into the specification document: "NOT INTENDED TO WORK WITH CTRL-D or CTRL-Z"

Stupendous Man flies again!

w00t

no -- '\0' is the same as 0 -- put another way they are both 0x00. You can easily prove this yourself by using a debugger to view the contents of a character buffer after inserting both a 0 and a '\0'. Or write a hex dump of the buffer.

or simpler yet:

int main()
{
    char buf1[6] = {0,0,0,0,0,0};
    char buf2[6] = {'\0','\0','\0','\0','\0','\0'};
    int x = memcmp(buf1,buf2,6);
    cout << x << "\n";

return 0;
}

All that it proves it is how the compiler demotes a literal int to a char. If you are fine with that probably you are fine with char c = 0.0; and with char c = 0L; to which I will respond:
Do not call a snowflake, water, just because it melts down as soon as you hold it in your hand.

if that's all you folks can find, then im pretty happy with my 20 minute code knocked out at 2am after bar close :-D

int main()
{
char buf1[6] = {0,0,0,0,0,0};
char buf2[6] = {'\0','\0','\0','\0','\0','\0'};
int x = memcmp(buf1,buf2,6);
cout << x << "\n";

return 0;
}

Without trying to offend anyone, all this conversation has just triggered a personal observation:
Complacency is that mirror, polished by moments of distraction and coated with unimportant matters; where the face of habit likes to show any wrinkle of sloppiness.

i have a confession to make

im an electrical engineer, not a programmer, so maybe I'm missing the subtleties...

but ASCII 0x00 sure looks like a big fat zero to me.

at any rate, I can almost as easily type 'NULL' as I can '0' ... the extra keystrokes will be worth it if it pleases the aesthetics of the stylistic purists.


for the record:

NATIONAL INSTRUMENTS' CVI
<stdlib.h>

#ifndef NULL
#define NULL 0
#endif

MICROSOFT MSVC
<stdlib.h>

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

GNU C COMPILER (GCC)
<system.h>

/* Define a generic NULL if one hasn't already been defined.  */
#ifndef NULL
#define NULL 0
#endif

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0 // <<< C++ language
#else
#define NULL ((void *)0) // <<< C language
#endif
#endif

In C language NULL is defined as 0 -- the above does nothing more than cast 0 to a pointer . There is no downgrading from int to char involved. 0 is still 0 by any other name. It might be defined somewhat differently by other compilers, such as 16-bit large memory model compiler might define it as NULL (char far *)0 , that that too is just another typecast of 0.

i have a confession to make
im an electrical engineer, not a programmer, [...]

Oh, no! Stupendous man, why did you do that? Don't you know? You never, never, give away your secret identity. Where were you at the super-hero academy when they were showing "The Incredibles"?
Let's hope Miss Wormwood is not monitoring any of these threads. If not, you and your cute tiger are in a real pickle. ;)

I'm with Aia on this topic. Although compilers treat \0 and 0 the same, they are not, since one is a character and the other is an integer. It has to do with human perception, not compiler equivalences.

It's the same as teaching children to dial nine-eleven in case of emergency. Many can't find the 11 button and don't have the knowledge how to correct it.

>>one is a character and the other is an integer
char is a one byte integer. C and C++ does not support pure character data type like VB and some other languages.

It has to do with human perception, not compiler equivalences.

It's the same as teaching children to dial nine-eleven in case of emergency. Many can't find the 11 button and don't have the knowledge how to correct it.

so youre saying the difference between NULL and '0' is meaningful only because people are stupid?

because otherwise, you're admitting it's just a style point. but to be honest, I do like the style... NULL makes code pretty.

In fact, this thread has convinced me to start using it more consistently.


.

>>you admit it's a style point
Yes -- its pure style. They are both correct and we are only arguing about coding styles.

NULL only makes sense when used with pointers. But I've seen some people try to use it with integers, such as int x = NULL; . It works but its a misuse of NULL.

I do have to admit that there may be some obscure compilers that do NOT define NULL as (void *)0. The C standards do not dictate what value it has to be. There could be some operating systems which could define NULL as (void *)1234567. In that case coding 0 for NULL would be an error.

This article has been dead for over six months. Start a new discussion instead.