Plz answer to my C doubts:-

1) Why do prototypes of some predefined functions in ctype.h(ex- tolower(ch)) has 'int' as the data type for formal arguments? How will it matter if the formal arguments r of type 'char'?


2) Is there any command in DOS for viewing the non printable characters stored in a file.

3)

char *p="Hello"      //Where will be this "Hello" stored??????

4)

int *p;
              *p=2;

My old compiler doesnt give any error for this code. But is it realy valid???? Does it give error in ur compiler????? Plz explain where is the value 2 stored.

5) Why is using 'gets' dangerous(as 'C' compiler in UNIX warns)?

6) exp1 = (type_cast) exp2
In 'C' do we have to type cast exp2 to the datatype of exp1 explicitly? Or is it ALWAYS done implicitly by the 'C' compiler?

Is it same with C++ also?


7) Is a buffer always used while writing or reading from a file in 'C'?
If yes, then when do we need to make a call to setvbuf with 'buf=NULL' since the 'C' compiler always assigns a buffer automatically(according to u)?

8) In 'C' we hav 'eof' and 'error' flags for indicating the errors which occur while doing file operations.
Suppose i try to call some file handling function and an error occurs(end of file doesnt occur) , how these 2 flags will be affected? If i m not wrong, error flag will set. But is eof flag affected(or set or reset)?

Will every file handling function in C affect both the flags?
Will every function in C affect both the flags?


I was reading Kernighan & Ritchie and couldnt understand few things can u plz explain them:-

9) For expalnation of getc its written that

int getc(FILE *stream)
getc is equivalent to fgetc except that if it
is a macro, it may evaluate stream more than
once.

Here what is the meaning of 'it may evaluate stream more than once' ? And which one shd we prefer to use- fgetc or getc?

10) For expalnation of setvbuf its written that

"It must be called before reading, writing, or any other operation."

What does this mean? Does it mean if i make a call to setvbuf with 'buf = not NULL' then the buffering will stop after doing one file handling operation?

11) There is one statement:- "fflush must be called between a read and a write or vice versa."

Can u plz give reason for doing so bcoz i think fflush is needed only when some data is left unwritten inside a buffer even after making a call to one of the write operations.


Thanx in advance.
Akshey

Recommended Answers

All 6 Replies

Answers
1.In C character constants are stored as ints
2.Make use of escape sequences
3.Read Only Memory
4.It may not give give compilation errors but it will most propbably crash(Undefined Behaviour)
5.You should never use gets.Instead Use fgets. See This
6.C++ is very strict with regard to type compatibility as compared to C. For example: C++ defines int , short int, and long int as three different types. They must be cast when their values are assigned to one another. Similarly, unsigned char, char and signed char are considered as diffferent types, although each of these has a size of one byte. In C++, the types of values must be same for complete compatibility, or else, a cast must be applied. These restrictions in C++ are neccessary in order to support function overloading where two functions with same name are distinguised using the type of function arguments.
C supports implicit type casting.
7.This will make things clear for you click

8. EOF is a macro whose value is -1 always...functions like(getc, getchar etc) returns an end-of-file marker EOF when end of file is reached. You can also make use of eof function of <io.h> to check the end of file.
prototype:

int eof(int handle);

9.fgetc is equivalent to getc, but implemented only as a function, rather than as a function and a macro. If your expression that you pass to getc has no side effects, it's advisable to use getc. If it does have side effects, you should definitely use fgetc.
10.Same as 7.
11.See This

>1) Why do prototypes of some predefined functions in
>ctype.h(ex- tolower(ch)) has 'int' as the data type for formal arguments?
Because they're allowed to accept EOF as a valid argument. Since char can be either signed or unsigned, and EOF is a negative quantity, if char is unsigned and EOF is passed, then Bad Things(TM) can happen. Also note that just because these functions take an int, it doesn't mean that all of the values representable by int are allowed. In fact, the only values allowed by the ctype functions are the range of an unsigned char, and EOF. That's why you'll see the argument cast to unsigned char occasionally:

c = tolower ( (unsigned char)c );

>2) Is there any command in DOS for viewing the non printable characters stored in a file.
This isn't a C question.

>char *p="Hello" //Where will be this "Hello" stored??????
Somewhere safe, implementation defined, and potentially read-only. But it doesn't matter at all to you as long as you don't try to modify it.

>But is it realy valid???? Does it give error in ur compiler?????
No, it's not valid. You're accessing indeterminate memory because a pointer (assuming it's a local variable) isn't initialized to anything, so it could point anywhere. Whether it breaks or not depends on where it points and if accessing that memory will break something. This is undefined behavior, so it could really do anything, including work perfectly.

>5) Why is using 'gets' dangerous(as 'C' compiler in UNIX warns)?
gets doesn't (and can't) check the boundaries of the buffer you pass to it, so if you give it an array of size 20, but gets reads 5000 characters, you'll be writing well beyond the end of the array. This is called a buffer overflow, and a lot of exploits have been written to take advantage of them.

>In 'C' do we have to type cast exp2 to the datatype of exp1 explicitly?
It depends on the types. Some conversions are implicit if they're deemed compatible (but not necessarily safe, like double to int). Others are not compatible, therefore you have to use an explicit cast if you really want the assignment to be made.

>Is it same with C++ also?
It's even more so with C++ since C++ has much stricter type checking.

>7) Is a buffer always used while writing or reading from a file in 'C'?
No, that's up to the implementation. However, a buffer is a valuable optimization tool, so you're unlikely to find an implementation that doesn't use one.

>If yes, then when do we need to make a call to setvbuf
>with 'buf=NULL' since the 'C' compiler always assigns a buffer automatically(according to u)?
Well, if you want to specify buffering but don't want to manage your own buffer, you would pass a null pointer and allow setvbuf to handle it.

>If i m not wrong, error flag will set. But is eof flag affected(or set or reset)?
The two flags are typically independent. Hitting the end-of-file won't set the error flag and a read/write error won't set the eof flag. However, that's not required behavior, but it doesn't matter anyway because any methods for clearing one flag will clear the other one too. :)

>Will every file handling function in C affect both the flags?
No (for example, remove or rename), but every function that accepts a FILE pointer as an argument will probably touch one or the other at some point.

>Will every function in C affect both the flags?
Most certainly not.

>Here what is the meaning of 'it may evaluate stream more than once' ?
Macros have a nasty problem with side effects. Let's say you have a macro for squares:

#define square(x) ( (x) * (x) )

If you then say square ( x++ ), fully expecting x to be incremented only once, you'll be disappointed to find that the result is actually ( x++ * x++ ). This is a case where x++ is evaluated more than once, and that's more or less what K&R is talking about.

>And which one shd we prefer to use- fgetc or getc?
It's up to you. You're unlikely to run into a case where there would be a difference between the two, and the performance difference isn't that great anymore even if getc is a macro.

>"It must be called before reading, writing, or any other operation."
>What does this mean?
It means that immediately after opening a stream, you call setvbuf or forever hold your peace. If you do anything with the stream after opening it, it's too late to call setvbuf, and if you do, you'll invoke undefined behavior.

>11) There is one statement:- "fflush must be called between a read and a write or vice versa."
You're going to have to give us more context for this question. I don't have my copy of K&R handy right now. Most likely the context is that of two-way streams where you can read and write, but between a read and a write, or a write and a read, you need to call a positioning function. fflush is considered a positioning function, and it serves the purpose of ensuring that you don't have a read immediately after a write or vice versa.

Thanx sunnypalsingh and narue for repling. I was out of station so couldnt reply.
NARUE i think you have got the right context. AND the actual statement is "fflush or file positioning function must be called between a read and a write or vice versa."
If i m not wrong we have to call a positioning function like fseek between read and write(or vice versa) bcoz say if i read first and then i start writing then the data will be written from where i stoppend reading, not at that place where i was writing before doing read operation. M i right?
But i thought fseek and ftell are positioning function bcoz using them we can do something with the file position indicatior, but why do we consider fflush as a positioning function? and why do we need to call it between read and write(or vice versa)?

>bcoz say if i read first and then i start writing then the data will
>be written from where i stoppend reading, not at that place
>where i was writing before doing read operation.
There are a bunch of logical reasons for the restriction. The best explanation is that the standard says so, and the standard is the ultimate authority on the language. :) One of the best reasons the standards committee chose such a restriction is for portability and performance. Some systems have a native file structure that saves all kinds of state information, and constantly checking for which direction data is moving is very expensive. So by forcing reads and writes to be separated by an explicit "refresh" operation, implementations can make assumptions that vastly improve performance and the only hit comes from actually changing direction.

>but why do we consider fflush as a positioning function?
fflush is a buffer control function, but for this purpose it's lumped together with the positioning functions that reset the stream state for changing direction. Why? Because if you flush the output buffer in a two-way stream, chances are pretty darn good that the next operation will be a read. So the standard makes life easier by only requiring a flush and not a positioning as well. :)

>If yes, then when do we need to make a call to setvbuf
>with 'buf=NULL' since the 'C' compiler always assigns a buffer automatically(according to u)?
Well, if you want to specify buffering but don't want to manage your own buffer, you would pass a null pointer and allow setvbuf to handle it.

calling setbuf with buf=NULL makes the i/o UNBUFFERED, which is not the same as allowing setbuf to handle it. The default (not calling setbuf or setvbuf) is buffered i/o.

Except for the lack of a return value, the setbuf() function
is exactly equivalent to the call

setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.