arnuld wrote:
Quote:
Quote:
On Mar 14, 6:25 am, Barry Schwarz <schwa...@doezl.netwrote:
>
Quote:
Quote:
>unsigned long int htoi(char input_array);
This tells the compiler (incorrectly) that the function htoi has a
character as its parameter. You call htoi with an array as its
argument. The next two prototypes indicate you know
how to declare a function which accepts an array so why is this one
different.
>
Quote:
Quote:
for(i=0; i < MAXELEMENTS && ((c = getchar()) != EOF || c != '\n'); ++i)
>
>
Quote:
The expression ((c = ... '\n') is always true. If c is not EOF, then
the first part of the or is true. If c is EOF, then it is not '\n'
and the second part is true. In either case, the whole or is
therefore true.
>
:-(
>
>
Quote:
Did you perhaps want && instead of &&.
>
what does that mean ?
He meant to write:
Did you perhaps want && instead of ||.
I corrected it in my earlier post. The logic is simple. You want to
break the loop when getchar returns an EOF _and_ when it returns a
newline character. Therefore you need to use the && operator which
returns true only when *both* it's conditions are true. The logical OR
operator, i.e., an ||, returns true when either one of it's operands
evaluates to true.
Quote:
Quote:
Quote:
{
if( isdigit(c) || c == 'a' || c == 'A' || c == 'b' || c == 'B'
>|| c == 'c' || c == 'C'
c == 'd' || c == 'D' || c == 'e' || c == 'E' || c == 'f' c == 'F' )
>
Quote:
You might want to look up the isxdigit function in your reference.
>
>
"isdigit(c)" tells whether (c >= '0' && c <= '9') , page-43 K&R2
C99 also has a isxdigit function which returns true if the argument is
in the ranges 0... 9, a... f or A... F. It'll do the job of your
complicated if condition above.
Quote:
Quote:
Quote:
>char hexa_without_lead(char arr[])
Which single character do you intend this function to return?
>
i wanted to return an array.
Automatic arrays will go out of scope when execution leaves the parent
function, and thus it'll be destroyed. Consider:
char *ret_spurious_array(char arr[]) {
char local_arr[10];
/* ... */
return local_arr;
}
The array local_arr has block scope. It's block, in this case, is the
entirety of the function ret_spurious_array. It'll be created anew
each time this function is called and destroyed each time this
function returns. Therefore when this function returns the pointer
value local_arr in it's return statement, it's returning a pointer to
an array that'll no longer exist by the time the function's caller
receives the return value, i.e. a wild pointer or a pointer with an
indeterminate value.
There are several ways to fix this. The easiest for you, at this stage
of your learning in C is:
void process_array(char arr[]) {
/* do something with arr */
arr[x] = SOMETHING;
/* ... */
return;
}
Here the process_array function is meant to operate on an array. In C,
you can never pass an array directly to a function. Instead whenever
you pass an array name to a function like this:
process_array(array);
what happens is that the array name 'array' "decays" to a pointer
value to the first element of array. The function process_array
receives this pointer value and, through it, operates *directly* on
the array 'array' in the parent function. Therefore no array needs to
be passed in to the function, (indeed you cannot do so), *and*, no
arrays local to the function are needed. It need not also return a
pointer to a local object which will not exist. This is why the header
for the above function can also be written as:
void process_array(char *arr) { /* ... */ return; }
Since what's passed into the function is actually a pointer value, of
the appropriate type, this form of writing the header is more or less
equivalent to the previous form, except that this form assumes the
student knows about pointers and their representation. The previous
form, i.e., using char arr[] and operating on arr by indexing, like
arr[4] = /* ... */, only assumes knowledge of arrays and indexing
them. It needs no explicit knowledge of pointers, when you're starting
to use them, but the pointer and it's manipulation nevertheless goes
on *behind the scenes*.
On more method to solve your problem is like this:
char *fx(char arr[]) {
char *heap_arr;
/* ... */
heap_arr = malloc(SOME_SIZE);
/* verify allocation has succeeded */
/* do something with the array pointed to by heap_arr */
return heap_arr;
}
Here you're using the malloc function to allocate an array of char *on
the heap*. The heap is best defined as that portion of system memory
from which the functions malloc, calloc and realloc get their memory
from. Most importantly memory allocated on the heap *persists*
throughout the lifetime of the program, or until you explicitly
deallocate it by calling free on it. This means that when the above
function returns the pointer value stored in heap_arr, the array
pointed to will still exist when the calling function receives it.
Also, as long as the pointer value is safely stored in some pointer
object, you can continue to access the memory block as long as the
program runs and from *anywhere* in the program, provided a copy of
the pointer is given to it. When you're done using the memory block,
you can return it to the system using free(the_pointer_value).
One more *highly non-recommended* method of solving you problem is to
declare a _global_ array and pass it between all the functions that
need to operate on it. A global object, (actually the precise term is
file scope), is created by placing it's declaration *outside* of any
function. Like:
char global_arr[SOME_SIZE];
fx1(global_arr);
/* ... */
fx2(global_arr);
/* etc. */
This type of programming tightly couples data with functions and
allows arbitrary changes to data that may become very hard to track
and maintain. Therefore using global objects, without a *very good
reason* is not good programming practise.
There's one more method to do what you want, but it's too complicated
for you at this stage.
Quote:
Quote:
Quote:
else if(s[i] == 'a' || 'A')
You demonstrated in main that you knew how to check for a character
being equal to one of several values. What is this syntactically
correct but meaningless garbage?
>
what does that mean ?
Well, the equality operator has higher precedence than the logical
operator. So the above construct is actually:
else if ( (s[i] == 'a') || 'A' ) /* ... */
In C a printable character always has positive value. Also any value
other than zero is interpreted as true in test conditions. So in the
above statement, 'a' is tested for equality against the i'th element
of array s. Lets say it contains the character 'b'. Then the
expression yields zero, which is defined as false. However because
you've misunderstood precedence, you've coupled this test with the
value of a character literal 'A', binding them both with a logical OR
which returns true if either of it's operands is true. So even if the
test for equality returns false, the *other* side of the OR will
*always* yield true, since in C, the value of printable characters in
positive, and any non-zero value is taken as being true in logical
contexts.
What you should do is:
else if (s[i] == 'a' || s[i] == 'A') /* ... */
<snip>
Quote:
Quote:
You really need to work on simpler programs until you get the basics
down pat.
>
i can't. these are the *only* exercises K&R2 has provided.
Have you worked through *all* the exercises in K&R up to this point?
Have you successfully done *all* of them?