newbie program, pointers again...

M

Martin Joergensen

Hi,

Okay I'm really bad at this... I tried to make a program that stores some
characters in a large 1-D array and some of this information for instance
the first 8 lines of text should then be written both to a file and to the
screen....

I get 6 errors + 8 warnings...
- - - --
/* purpose of program:

Instead of making two identically printf(" ") + fprinft(fp, " ");
statements, a pointer to char

holds the text that should be output to *both* the screen and to a file.

//printf("\n");

// printf("********************** INPUT AND RESULTS:
*************************\n");

// printf("* X_A * X_B * Y_A * Y_B *** r(test) * r(degrees) *\n");

//
printf("***********************************************************************\n");

// printf("* %7.2lf * %7.2lf * %7.2lf * %7.2lf *** %7.2lf * %7.2lf *\n",
X_A, X_B, Y_A, Y_B, r_test, r_degrees);

//
printf("***********************************************************************\n");

*/

#include <stdio.h>

#include <math.h>

#include <ctype.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h> // for memcpy

void repeat(char *dest_array, char ch, int n, unsigned int *position);

void insert(char *dest_array, char *source_str, unsigned int *position);

//////////////

main()

{

char *text;

char *str[80]; /* static mem. allocated, max 1 line = 80 chars */

FILE *outputfile;

unsigned long size = 1600*sizeof(char); /* space for 20 lines */

unsigned int *position = 0;

text = malloc(size);

if (!text)

{

fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n", __FILE__, __LINE__,
size);

exit(EXIT_FAILURE);

}

memcpy(text, "\n", (size_t) 2 ); /* start by moving to the next line */

insert(text, str, position); /* insert string into text-array (this array is
the one to be written to both screen+file) */

repeat(text, '*', 20, position); /* make 20 stars: ****************** etc...
*/

memcpy(text, " INPUT ", (size_t) 7 ); /* move to text-array */

insert(text, str, position);

if ( (outputfile=fopen("result.txt", "w") )==NULL)

{

printf("\nError file: \"result.txt\".\n\n");

}

else

{

/* write data from text both to screen *and* to file - still unsure about
how to do this part too */

}

fclose(outputfile);

system("PAUSE");

return 0;

}



/* functions */

void repeat(char *dest_array, char ch, int n, unsigned int *position)

{

int i;

for(i=0; i<n; i++)

memcpy(dest_array[position+i], ch, (size_t) 1);

*position += n;

}

void insert(char *dest_array, char *source_str, unsigned int *position)

{

int i, n;

n = strlen(source_str);

while(i=0; i<n; i++)

*(dest_array[position+i]) = *source_str;

*position += n;

}

- - - - -

Suggestions? I need a little help to get going, I think :)

Sorry, I hate to ask again...



Best regards / Med venlig hilsen
Martin Jørgensen
 
R

Richard G. Riley

Hi,

Okay I'm really bad at this... I tried to make a program that stores some
characters in a large 1-D array and some of this information for instance
the first 8 lines of text should then be written both to a file and to the
screen....

I get 6 errors + 8 warnings...
- - - --

Hi Martin,

I would suggest reading a c beginner guide to pointers, arrays,
pointer dereferencing and strings in C. There is a lot wrong with your
program that a short course in the above would help you eradicate. You
have lots of unitialised variables, overwriting of strings, and
incorrect pointer usage when you should have been using plain int or
char. The fact that it doesnt compile should indicate some work to be
done:)

Here is one such tutorial which might help with these issues:

http://home.netcom.com/~tjensen/ptr/ch3x.htm

And at the risk of incurring the wrath of some of the regulars, when
your program compiles then stepping through with a debugger would help
you see the data moving around at run time and clarify a lot of the
differences betwee pointers, data pointed to by pointers and objects
such as chars and ints.

some guidelines:

consider using sprintf() to set up your "text" area.
printf("%s",text) to write to the console.
Check your function prototypes for argument ordering : you have them
wrong way around.
If you have functions which append to char buffers then its not such a
bad idea to return the pointer to the end of that buffer for further
addition/characters later in the program. It saves repeated
calculations to find where in the buffer new information must be added on.

Possibly someone will post more of a solution, but until you have the
basics sorted in your head (see tutorial or google another one up),
then you will struggle : if you come from a higher level language
background it can appear daunting, but it will become clearer in no
time. Then you can enter the minefield of making it more robust across
compilers and platforms.

best of luck!
 
M

Martin Joergensen

Richard G. Riley said:
Here is one such tutorial which might help with these issues:

http://home.netcom.com/~tjensen/ptr/ch3x.htm

That is a *very* good tutorial... I still have read a couple of tutorials
about this topic, but might be that I was a little tired yesterday too...
However, I think your comments was enough for me to get going... And I'll
definately print out this tutorial...

-snip-
some guidelines:

consider using sprintf() to set up your "text" area.
printf("%s",text) to write to the console.

Yep, ofcourse... Appreciate the comments.

-snip-
Possibly someone will post more of a solution, but until you have the
basics sorted in your head (see tutorial or google another one up),
then you will struggle : if you come from a higher level language
background it can appear daunting, but it will become clearer in no
time. Then you can enter the minefield of making it more robust across
compilers and platforms.

I think I can figure it out from now.

In any case, I'll post what I end up with later just to see if anyone has
anything further to add.... Looks promising from now :)


Best regards / Med venlig hilsen
Martin Jørgensen
 
R

Richard G. Riley

That is a *very* good tutorial... I still have read a couple of tutorials
about this topic, but might be that I was a little tired yesterday too...
However, I think your comments was enough for me to get going... And I'll
definately print out this tutorial...

It's not the most precise, but what it does it does well : clearly and
obviously with no unnecessary showing off for the beginner C programmer.
-snip-

Yep, ofcourse... Appreciate the comments.

-snip-

I think I can figure it out from now.

Thats what these groups are for!

In any case, I'll post what I end up with later just to see if anyone has
anything further to add.... Looks promising from now :)

I strongly advise you to use a debugger if you have one, check you have only
instantiated data you *need* (there is nothing worse than unused data
lying around), and to not repeat anything unless you really have to.

In your case, it *might* need "repeat" and "insert", but I doubt
it. Stand back and ask what it is you really want : it might be as
simple as something like (not compiled):

char buffer[MAXBUF];
sprintf(buffer,"%s\n%s\n%s\n%s","Top,"**********",refLine,"Bottom");
...
...
printf("%s\n",buffer); // to screen
"write to file"; // left as exercise.
Best regards / Med venlig hilsen
Martin Jørgensen

Good luck. When you have a concise solution you will get that C bug :
can an exe really be that few lines? I think Java forced me back to C ...
 
M

Martin Joergensen

Richard G. Riley said:
best of luck!

OMFG.... That was really a pain in the ass! :)

But I finally made it :)

I would like to hear your comments, if you have any - proposals etc..?
--------------
/* purpose of program:

Instead of making two identically printf(" ") + fprinft(fp, " ");
statements, a pointer to char

holds the text that should be output to *both* the screen and to a file.

//printf("\n");

// printf("********************** INPUT AND RESULTS:
*************************\n");

// printf("* X_A * X_B * Y_A * Y_B *** r(test) * r(degrees) *\n");

//
printf("***********************************************************************\n");

// printf("* %7.2lf * %7.2lf * %7.2lf * %7.2lf *** %7.2lf * %7.2lf *\n",
X_A, X_B, Y_A, Y_B, r_test, r_degrees);

//
printf("***********************************************************************\n");

*/

#include <stdio.h>

#include <math.h>

#include <ctype.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h> // for memcpy

void repeat(char **dest_array, const char ch, const int n);

void add_text(char **dest_array, const char *source_array);

//////////////

int main()

{

char *char_ptr; /* pointer to beginning of char (array) */

char *destination_arr;

FILE *outputfile;

unsigned long size = 1600*sizeof(char); /* space for 20 lines */

char_ptr = malloc(size);

if (!char_ptr)

{

fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n", __FILE__, __LINE__,
size);

exit(EXIT_FAILURE);

}

destination_arr = char_ptr;

printf("sizeof(char) = %i byte(s)\n", sizeof(char) );

printf("\nPointer values:\n");

printf("char_ptr = %15p\n", char_ptr);

add_text(&destination_arr, "Howdy! ");

add_text(&destination_arr, "You crazy dumb computer!");

add_text(&destination_arr, "I really hate you!");

repeat(&destination_arr, '*', 10);

add_text(&destination_arr, "You stink, go away!");

repeat(&destination_arr, '-', 20);

if ( (outputfile=fopen("result.txt", "w") )==NULL)

{

printf("\nError opening output-file: \"result.txt\".\n\n");

}

else

{

fprintf(outputfile, "%s", char_ptr);

}

printf("%s", char_ptr);

fclose(outputfile);

system("PAUSE");

return 0;

}



/* functions */



void add_text(char **dest_array, const char *source_array)

{

sprintf(*dest_array, ("%s", source_array) );

printf("strlen(source_array) = %i\n", strlen(source_array) );

*dest_array += strlen(source_array);

}

void repeat(char **dest_array, const char ch, const int n)

{

int i; /* local variable: counter */

for(i=0; i<n; i++) (*dest_array) = ch;

(*dest_array)[n] = '\0'; /* terminate string */

*dest_array += n; /* update position */

}
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Richard said:
I strongly advise you to use a debugger if you have one, check you have only
instantiated data you *need* (there is nothing worse than unused data
lying around), and to not repeat anything unless you really have to.

Yeah, I would never have made it without a debugger...
In your case, it *might* need "repeat" and "insert", but I doubt
it. Stand back and ask what it is you really want : it might be as
simple as something like (not compiled):

I didn't see this post, before I finished the program...
char buffer[MAXBUF];
sprintf(buffer,"%s\n%s\n%s\n%s","Top,"**********",refLine,"Bottom");
...
...
printf("%s\n",buffer); // to screen
"write to file"; // left as exercise.

Yes, I agree. But I want to make a more complicated layout which for
instance calculates the necessary number of empty spaces (and the number
of necessary stars) and formats it in a nice table output format:

You saw some of this stuff:
- - - -
printf("********** INPUT AND RESULTS:*************\n");

printf("* X_A * X_B * Y_A * Y_B *** r(test) * r(degrees) *\n");
printf("**************************************************\n");

printf("* %7.2lf * %7.2lf * %7.2lf * %7.2lf *** %7.2lf * %7.2lf *\n",
X_A, X_B, Y_A, Y_B, r_test, r_degrees);
- - - -

And I wouldn't be able to do any "dynamic" calculation of the number of
spaces, etc. without doing my function as I did...

BTW: I'm going to need to figure out how many digits a certain result
takes up... Do you have any idea about that?

Let's say the user inputs something: 4324.3 - the program does some
calculation based on this input and gets the result 123.1. How do I know
how many digits are in the result (most important without any decimals)?

Should I just say: if (number) <=9 {maxdigits = 1}, if (number) <=99
{maxdigits = 2}, etc...?

Ofcourse, I'm going to have more results so I make a for loop and go
through all results. I then figure out which results take up the maximum
number of digits. Based on that I figure out if I have space for
decimals (if I really would go crazy, I could based on this result make
the program show the result in exponential format if the number of
digits are way too high, i.e. 4.312e-15 / 42.2e4).

I still need to work on the table layout, though - only finished the 2
necessary routines at this point.
Good luck. When you have a concise solution you will get that C bug :
can an exe really be that few lines? I think Java forced me back to C ...

Haha... You're right... Looking at the code now makes me think: Is it
really that simple? :)

It really caused me a lot of trouble to figure out that I not just
needed a * reference pointer variable, but I think it is necessary to
have a ** reference pointer variable! And pass the address using &-operator!

That was really tricky, if you could imagine :)


Best regards / Med venlig hilsen
Martin Jørgensen
 
R

Richard G. Riley

OMFG.... That was really a pain in the ass! :)

But I finally made it :)

I would like to hear your comments, if you have any - proposals
etc..?

If you insist on using an add_text function as opposed to sprintf,
then you might consider to change "add_text"/repeat to return a
pointer to next space in buffer :

e.g (untested or compiled), and since you now understand pointers a
bit better ...


char * repeat(char *d,char c,unsigned int n){
while(n--)
*d++=c;
*d='\0';
return d;
}

char * addText(char *d,char *s){
while(*d++=*s++); //strcpy updating our dest pointer as we go
return --d; //point at null
}

then your main code looks like

refNextChar = repeat(refNextChar,"*",20);
refNextChar = addText(refNextChar,"Hello");

Its a preference of mine and not set in stone. Your way seems shorter
at the calling code level,
but involves dereferencing and, IMO, complicating the utility functions
prototypes and. It just seems more logical to me since
you are always only adding to the end anyway, and we also remove calls
to strlen : we keep our own running tally. I have never liked
functions with change their parameter values through pointers : better
to return the value and let the parent decide what to update. Some
might disagree strongly.

But the main thing is that you are now understanding pointers & arrays
better I think. Now tidy your code and remove all the apparently
unnecessary header comments :) Take a look at all the headers you have
included : are they really all necessary?

Good luck!


--------------
/* purpose of program:

Instead of making two identically printf(" ") + fprinft(fp, " ");
statements, a pointer to char

holds the text that should be output to *both* the screen and to a file.

//printf("\n");

// printf("********************** INPUT AND RESULTS:
*************************\n");

// printf("* X_A * X_B * Y_A * Y_B *** r(test) * r(degrees) *\n");

//
printf("***********************************************************************\n");

// printf("* %7.2lf * %7.2lf * %7.2lf * %7.2lf *** %7.2lf * %7.2lf *\n",
X_A, X_B, Y_A, Y_B, r_test, r_degrees);

//
printf("***********************************************************************\n");

*/

#include <stdio.h>

#include <math.h>

#include <ctype.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h> // for memcpy

void repeat(char **dest_array, const char ch, const int n);

void add_text(char **dest_array, const char *source_array);

//////////////

int main()

{

char *char_ptr; /* pointer to beginning of char (array) */

char *destination_arr;

FILE *outputfile;

unsigned long size = 1600*sizeof(char); /* space for 20 lines */

char_ptr = malloc(size);

if (!char_ptr)

{

fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n", __FILE__, __LINE__,
size);

exit(EXIT_FAILURE);

}

destination_arr = char_ptr;

printf("sizeof(char) = %i byte(s)\n", sizeof(char) );

printf("\nPointer values:\n");

printf("char_ptr = %15p\n", char_ptr);

add_text(&destination_arr, "Howdy! ");

add_text(&destination_arr, "You crazy dumb computer!");

add_text(&destination_arr, "I really hate you!");

repeat(&destination_arr, '*', 10);

add_text(&destination_arr, "You stink, go away!");

repeat(&destination_arr, '-', 20);

if ( (outputfile=fopen("result.txt", "w") )==NULL)

{

printf("\nError opening output-file: \"result.txt\".\n\n");

}

else

{

fprintf(outputfile, "%s", char_ptr);

}

printf("%s", char_ptr);

fclose(outputfile);

system("PAUSE");

return 0;

}



/* functions */



void add_text(char **dest_array, const char *source_array)

{

sprintf(*dest_array, ("%s", source_array) );

printf("strlen(source_array) = %i\n", strlen(source_array) );

*dest_array += strlen(source_array);

}

void repeat(char **dest_array, const char ch, const int n)

{

int i; /* local variable: counter */

for(i=0; i<n; i++) (*dest_array) = ch;

(*dest_array)[n] = '\0'; /* terminate string */

*dest_array += n; /* update position */

}

------


Best regards / Med venlig hilsen
Martin Jørgensen
 
A

ais523

Martin said:
Richard said:
I strongly advise you to use a debugger if you have one, check you have only
instantiated data you *need* (there is nothing worse than unused data
lying around), and to not repeat anything unless you really have to.

Yeah, I would never have made it without a debugger...
In your case, it *might* need "repeat" and "insert", but I doubt
it. Stand back and ask what it is you really want : it might be as
simple as something like (not compiled):

I didn't see this post, before I finished the program...
char buffer[MAXBUF];
sprintf(buffer,"%s\n%s\n%s\n%s","Top,"**********",refLine,"Bottom");
...
...
printf("%s\n",buffer); // to screen
"write to file"; // left as exercise.

Yes, I agree. But I want to make a more complicated layout which for
instance calculates the necessary number of empty spaces (and the number
of necessary stars) and formats it in a nice table output format:

You saw some of this stuff:
- - - -
printf("********** INPUT AND RESULTS:*************\n");

printf("* X_A * X_B * Y_A * Y_B *** r(test) * r(degrees) *\n");
printf("**************************************************\n");

printf("* %7.2lf * %7.2lf * %7.2lf * %7.2lf *** %7.2lf * %7.2lf *\n",
X_A, X_B, Y_A, Y_B, r_test, r_degrees);
- - - -

And I wouldn't be able to do any "dynamic" calculation of the number of
spaces, etc. without doing my function as I did...

BTW: I'm going to need to figure out how many digits a certain result
takes up... Do you have any idea about that?

Let's say the user inputs something: 4324.3 - the program does some
calculation based on this input and gets the result 123.1. How do I know
how many digits are in the result (most important without any decimals)?

Should I just say: if (number) <=9 {maxdigits = 1}, if (number) <=99
{maxdigits = 2}, etc...?

Ofcourse, I'm going to have more results so I make a for loop and go
through all results. I then figure out which results take up the maximum
number of digits. Based on that I figure out if I have space for
decimals (if I really would go crazy, I could based on this result make
the program show the result in exponential format if the number of
digits are way too high, i.e. 4.312e-15 / 42.2e4).

I still need to work on the table layout, though - only finished the 2
necessary routines at this point.
Good luck. When you have a concise solution you will get that C bug :
can an exe really be that few lines? I think Java forced me back to C ....

Haha... You're right... Looking at the code now makes me think: Is it
really that simple? :)

It really caused me a lot of trouble to figure out that I not just
needed a * reference pointer variable, but I think it is necessary to
have a ** reference pointer variable! And pass the address using &-operator!

That was really tricky, if you could imagine :)


Best regards / Med venlig hilsen
Martin Jørgensen
 
A

ais523

Martin said:
BTW: I'm going to need to figure out how many digits a certain result
takes up... Do you have any idea about that?

In C99, try looking up sprintf. sprintf(NULL,0,format,...) returns the
number of characters that printf(format,...) would print. In C89,
you're better off doing it by hand.

(Sorry for a post I made that just quotes all of Martin's post and adds
no new content. I messed up Google's interface, and I hate it when
other people do that.)
 
M

Micah Cowan

Martin Joergensen said:
Hi,

Okay I'm really bad at this... I tried to make a program that stores some
characters in a large 1-D array and some of this information for instance
the first 8 lines of text should then be written both to a file and to the
screen....

I get 6 errors + 8 warnings...
- - - --
/* purpose of program:

Instead of making two identically printf(" ") + fprinft(fp, " ");
statements, a pointer to char

holds the text that should be output to *both* the screen and to a file.

#include <stdio.h>
#include <math.h>
#include <ctype.h>

I don't think you're using these two above...
#include <stdio.h>

You've already included this...
#include <stdlib.h>

#include <string.h> // for memcpy

and for strlen().
void repeat(char *dest_array, char ch, int n, unsigned int *position);

void insert(char *dest_array, char *source_str, unsigned int *position);

//////////////

main()

You are strongly advised to use
int main(void)

implicit int has been removed from C--in the same version of C that
allows //-style comments (which you should probably still avoid on
USENET, as they have a tendency to get line-wrapped).

"void" in a parameter list != an empty parameter list. The one you
used means that main will pretty much blindly accept any arguments you
give to it, but then undefined behavior would occur. Explicit void is
much better. (C++ behaves differently.)
{

char *text;

char *str[80]; /* static mem. allocated, max 1 line = 80 chars */

FILE *outputfile;

unsigned long size = 1600*sizeof(char); /* space for 20 lines */

You mean, 20 lines of maximum 80 chars each. Also a size_t would make
a slightly more appropriate type, but it doesn't really matter.

BTW, sizeof(char) is always, *always*, equal to 1.
unsigned int *position = 0;

text = malloc(size);

if (!text)

{

fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n", __FILE__, __LINE__,
size);

exit(EXIT_FAILURE);

}

memcpy(text, "\n", (size_t) 2 ); /* start by moving to the next line */

I'm not sure, but I'm guessing you mean to write this to
str[]...
insert(text, str, position); /* insert string into text-array (this array is
the one to be written to both screen+file) */

Especially since you "insert" str[] into text[] here, but str[]
currently holds unspecified garbage.

However, since it's a string literal, why not skip the write to str[],
and do:

insert(text, "\n", position);

directly?
repeat(text, '*', 20, position); /* make 20 stars: ****************** etc...
*/

I'm thinking you might have wanted to put a newline after this...
memcpy(text, " INPUT ", (size_t) 7 ); /* move to text-array */

insert(text, str, position);

Similarly here.

BTW, using hard-coded magic numbers for the size value
is just asking for trouble later on. In fact, it's already
wrong. Earlier you copied both bytes from the string, which means you
copied the \n byte and the terminating null character byte. This time,
you only copied the 7 characters, but no terminating null character.

Or did you think that "\n" is two characters; '\', and 'n'?

If you insist on using the memcpy(), you should use the sizeof
operator to get exactly the size you want. Use a const char[] to store
the contents from a literal initializer, and then use it in memcpy().

const char INPUT_STR[] = " INPUT ";
...
memcpy(text, INPUT_STR, sizeof INPUT_STR);
if ( (outputfile=fopen("result.txt", "w") )==NULL)

{

printf("\nError file: \"result.txt\".\n\n");

}

else

{

/* write data from text both to screen *and* to file - still unsure about
how to do this part too */

}

fclose(outputfile);

system("PAUSE");

The above line isn't portable, of course. Much better to set up your
terminal not to exit automatically when the program terminates. Or you
could use getchar() [the former suggestion is still better].
return 0;

}
/* functions */

void repeat(char *dest_array, char ch, int n, unsigned int *position)

{

int i;

for(i=0; i<n; i++)

memcpy(dest_array[position+i], ch, (size_t) 1);

If you're just writing a byte, then

dest_array[position+i] = ch;

seems better suited.
*position += n;
}

void insert(char *dest_array, char *source_str, unsigned int *position)

{

int i, n;

n = strlen(source_str);

while(i=0; i<n; i++)

You meant for instead of while.
*(dest_array[position+i]) = *source_str;

*position += n;

}


There's no real reason for n, i, or strlen(), here.

strlen() will scan through all the characters in source_str, just to
find the null character. Then you proceed to scan through them again
for the copy. It would be better to do one scan, that does the copy
/and/ terminates upon encountering the null character. Of course,
that's exactly what strcpy() does (though you can't use that here,
because it wouldn't update position, so you'd still need to call
strlen()).

Even if you needed to call strlen(); memcpy() seems more approriate
than a custom for-loop.

However, since you don't need strlen(), and do need to update
position, why not use position instead of i? This way, you only have
to update one variable, not two.

char *cur;
for (cur = source_str; *cur != '\0'; ++cur) {
dest_str[*position] = *cur;
++*position;
}

You could probably do something similar for repeat(); although in that
case you actually do need n... still, i is unnecessary.
Suggestions? I need a little help to get going, I think :)

I think you need to familiarize yourself a little more thoroughly with
the facilities you're using. It looks like Mr Riley has already helped
you start this.

I don't see any need whatsoever for you to keep space for 20
lines. Why not simply output lines one at a time? This way you only
need space for one line at a time.

However, a technique you need to know for when you /are/ doing
something like that (in fact, it's needed even when you're just doing
/one/ line...), is to always keep track of how much space you have
available in your buffer. Overrunning buffer space is probably the
number one most serious and most common bug in C programs.

Now, to answer your actual question... there is no way to save a call
to both printf() and fprintf() [or equivalent], one for each file
you're writing to (including stdout). However, you /can/ wrap it up
inside a single function, if you expect to be making such calls in
more than one place.

For your simple write loop you've got going, it's probably not worth
it. However, if you really are going to do these double-writes in more
than one place, you'll want to #include <stdarg.h> and write your own
function, similar to:

double_printf(const char *format, ...);

And within it, you'll need to use va_start(), va_arg(), vprintf(),
vfprintf(), and va_end(). Read up on these functions, and try out an
implementation. You should probably post it here for review when
you're done, but try to get it working first (it really won't be
hard).

HTH,
Micah
 
K

Keith Thompson

Martin Joergensen said:
#include <stdio.h>

#include <math.h>

#include <ctype.h>

#include <stdio.h> [snip]
int main()

{

char *char_ptr; /* pointer to beginning of char (array) */

char *destination_arr;

FILE *outputfile;

unsigned long size = 1600*sizeof(char); /* space for 20 lines */

char_ptr = malloc(size);

if (!char_ptr)

{

fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n", __FILE__, __LINE__,
size);

exit(EXIT_FAILURE);

}
[snip]

Your code would be a lot easier to read if you (1) didn't double-space
everything, and (2) indented properly.

Blank lines are useful to show grouping (between function definitions,
for example, but adding a blank line after *every* line of code just
wastes space. Possibly your news software is inserting the blank
lines; if so, please figure out why. (Use alt.test or misc.test if
you need to experiment.)

Tabs used for indentation can sometimes disappear, depending on your
news software. Use spaces only. (Some text editors try to insert
tabs without being asked. Find out how to override this behavior, or,
if you're on a Unix-like system, filter the file through "expand".)
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

ais523 said:
In C99, try looking up sprintf. sprintf(NULL,0,format,...) returns the
number of characters that printf(format,...) would print. In C89,
you're better off doing it by hand.

(Sorry for a post I made that just quotes all of Martin's post and adds
no new content. I messed up Google's interface, and I hate it when
other people do that.)

I don't think I have a C99 compiler... But I just got a really great
idea, I think. Works both for double and int.

1) However I think I'm going to cast to something....
2) Not sure if it works completely for negative numbers.

Idea: I use math-library... log( abs(number) )

Examples:

log(54) = 1.73 -> 2 digits.
log( abs(-423) ) = log(423) = 2.62 -> 3 digits. Might have to add 1 char
for the minus-sign too.

The good thing is it works for all numbers up to +inf (in theory).

For numbers below 1 I think I can take the reciprocal values and do log(
abs(1/number) ), +/- 1 char for minus-sign...

Agreed? I haven't thought about this smaller than 1 thing completely...


Best regards / Med venlig hilsen
Martin Jørgensen
 
?

=?ISO-8859-1?Q?Martin_J=F8rgensen?=

Keith Thompson wrote:
-snip-
Your code would be a lot easier to read if you (1) didn't double-space
everything, and (2) indented properly.

1) I didn't think about that.

2) I also do indent correctly in MS visual studio 2005. But when I
copy/paste it (with correct indenting) to my news-post there are
different colors (green and blue?) and after I send the post and see it,
the formatting is gone + the colors went away.

Do you know how I fix this problem? The news-client was Outlook-Express.
So that is 2 Microsoft-products...
Blank lines are useful to show grouping (between function definitions,
for example, but adding a blank line after *every* line of code just
wastes space. Possibly your news software is inserting the blank
lines; if so, please figure out why. (Use alt.test or misc.test if
you need to experiment.)

I think it is my news-software... Outlook express. But you're right...
Very annyoing.
Tabs used for indentation can sometimes disappear, depending on your
news software. Use spaces only. (Some text editors try to insert

I always do ctrl+A + "auto-indent" everything.
tabs without being asked. Find out how to override this behavior, or,
if you're on a Unix-like system, filter the file through "expand".)

Microsoft mostly... I hope somebody knows what is happening and how to
avoid it. I find it really annoying too...


Best regards / Med venlig hilsen
Martin Jørgensen
 
C

CBFalconer

Martin said:
Okay I'm really bad at this... I tried to make a program that
stores some characters in a large 1-D array and some of this
information for instance the first 8 lines of text should then be
written both to a file and to the screen....

I get 6 errors + 8 warnings...
- - - --
/* purpose of program:

I, for one, will simply not read code that is not reasonably
indented, and that has wrapped lines and // comments. Ensure your
lines are no more than 72 chars long (better 65), use /* comments
*/, and do not use tab chars.

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
<http://www.dinkumware.com/refxc.html> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
<http://clc-wiki.net> (C-info)
 
V

Vladimir S. Oka

Keith Thompson wrote:
-snip-


1) I didn't think about that.

2) I also do indent correctly in MS visual studio 2005. But when I
copy/paste it (with correct indenting) to my news-post there are
different colors (green and blue?) and after I send the post and see
it, the formatting is gone + the colors went away.

Do you know how I fix this problem? The news-client was
Outlook-Express. So that is 2 Microsoft-products...

Double plus bad. ;-)

You can try telling VS to not use TABs, but spaces (preferable in any
case, IMHO). Also, try telling OE to compose posts in plain text.
I think it is my news-software... Outlook express. But you're right...
Very annyoing.

I can't think of a reason for this, but you may try some other Windows
news client. Once upon a time, before I renounced the dark side, I used
Gravity, and found it excellent (I actually regret they never did a
Linux version, or set the source free). I think it's been released for
free a few years back, and the company went titsup but you may still be
able to find it on the Web (if you fail, send me an e-mail, and I may
be able to dig it out of some ancient backups).
 
K

Keith Thompson

Vladimir S. Oka said:
Double plus bad. ;-)

You can try telling VS to not use TABs, but spaces (preferable in any
case, IMHO). Also, try telling OE to compose posts in plain text.

<OT>
Or you might copy-and-paste from MS Visual Studio to notepad or
wordpad, and from there to your news software. I don't know whether
this would actually work, but it might at least cause it to be
converted to plain text and let you fix any formatting problems before
posting.

Or see if MSVS lets you save your source as plain text.
</OT>
 
A

ais523

I said:
In C99, try looking up sprintf. sprintf(NULL,0,format,...) returns the
number of characters that printf(format,...) would print. In C89,
you're better off doing it by hand.

Clearly, 'sprintf' should be 'snprintf'.
 
M

Martin Joergensen

"CBFalconer" <[email protected]> skrev i en meddelelse
-snip-
I, for one, will simply not read code that is not reasonably
indented, and that has wrapped lines and // comments. Ensure
your
lines are no more than 72 chars long (better 65), use /*
comments
*/, and do not use tab chars.

I think it should be okay now... But it is really bugging me that
I have to copy the code to notepad and then copy it back
here.......... Fucking Microsoft-shit. Then I have to figure out
which header-files I don't need, but that should be piece of cake
just using trial and error.

It works now, so I think I'll just stick to that unless somebody
has any really great idea that I didn't see.

- - - --
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // for memcpy

void repeat(char **dest_array, const char ch, const int n);
void add_text(char **dest_array, const char *source_array);

//////////////
int main()
{
char *char_ptr; /* pointer to beginning of char (array) */
char *destination_arr;

FILE *outputfile;
unsigned long size = 1600*sizeof(char); /* space for 20 lines
*/

char_ptr = malloc(size);
if (!char_ptr)
{
fprintf(stderr, "%s: line %d, malloc(%lu) failed.\n",
__FILE__, __LINE__, size);
exit(EXIT_FAILURE);
}

destination_arr = char_ptr;

printf("sizeof(char) = %i byte(s)\n", sizeof(char) );
printf("\nPointer values:\n");
printf("char_ptr = %15p\n", char_ptr);

add_text(&destination_arr, "Howdy! ");
add_text(&destination_arr, "You crazy dumb computer!");
add_text(&destination_arr, "I really hate you!");
repeat(&destination_arr, '*', 10);
add_text(&destination_arr, "You stink, go away!");
repeat(&destination_arr, '-', 20);

if ( (outputfile=fopen("result.txt", "w") )==NULL)
{
printf("\nError opening output-file:
\"result.txt\".\n\n");
}
else
{
fprintf(outputfile, "%s", char_ptr);
}

printf("%s", char_ptr);
fclose(outputfile);
system("PAUSE");
return 0;
}


* functions */


void add_text(char **dest_array, const char *source_array)
{
sprintf(*dest_array, ("%s", source_array) );

printf("strlen(source_array) = %i\n", strlen(source_array) );
*dest_array += strlen(source_array);
}

void repeat(char **dest_array, const char ch, const int n)
{
int i; /* local variable: counter */

for(i=0; i<n; i++) (*dest_array) = ch;

(*dest_array)[n] = '\0'; /* terminate string */

*dest_array += n; /* update position */
}


Best regards / Med venlig hilsen
Martin Jørgensen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top