To make this simplier for you guys, I made a small program based off
my much bigger program I am making. I thought I knew pointers and
functions pretty well until now. The program reads a file 'ryan.txt'
and is supposed to print out the information. For some reason I cant
get the array to work from function to function. The file 'ryan.txt'
is as follows:
3
red 10
black 12
white 15
/* SMALL EXAMPLE OF BIGGER PROBLEM
BY RYAN */
#include<stdio.h> /* input/output header */
void restore(char *a[][19], int *b[]);
void print(char *a[][19], int *b[]);
int main(void)
{
/*int numbers, functions, characters, etc */
char *item[100][19];
int *quantity[100];
int i;
printf("1. To read chars.\n");
printf("2. To print chars.\n");
scanf("%d",&i);
if (i == 1)
restore(item,quantity);
else
print(item,quantity);
return 0;
}
void print(char *a[][19], int *b[]) {
int j;
for (j = 0; j < 4; j++)
printf( "%s %d ", a[j], &b[j]);
main();
}
void restore(char *a[][19], int *b[]) {
int j,k;
FILE * infile;
infile = fopen( "ryan.txt","r" );
fscanf( infile, "%d", &k);
for (j = 0; j < k; j++)
fscanf( infile, "%s %d ", a[j], &b[j]);
printf("Array Created! YAY!\n");
main();
} |
Clarification of Question by
fikal-ga
on
18 Nov 2004 21:22 PST
the code you gave me did not work completely. The message Array
Created! YAY! kepy on printing out until the program crashed. I have
added a little to the program because if you notice the program reads
the number of lines that are going to be in the file first. fscanf(
infile, "%d", &k); I need the program to get the variable and by
using pointers allow the print function to use the &k variable. I
will repost my program which now gives me errors with the pointers. I
am sure someone here can fix this program and compile it w/ no flaws.
the variable k has been changed to number. Thank you
#include<stdio.h> /* input/output header */
int restore(char *a[][19], int *b[], int *number);
int print(char *a[][19], int *b[], int *number);
int main(void)
{
/*int numbers, functions, characters, etc */
char *item[100][19];
int *quantity[100];
int i;
int *number=0;
printf("1. To read chars.\n");
printf("2. To print chars.\n");
while (1) {
scanf("%d",&i);
if (i == 1) {
restore(item,quantity,number);
i=0; }
else
print(item,quantity,number);
i=0;
}
return 0;
}
int print(char *a[][19], int *b[], int *number) {
int j;
for (j = 0; j < *number; j++)
printf( "%s %d ", a[j], &b[j]);
return *number;
}
int restore(char *a[][19], int *b[], int *number) {
int j;
FILE * infile;
infile = fopen( "ryan.txt","r" );
fscanf( infile, "%d", &number);
for (j = 0; j < *number; j++)
fscanf( infile, "%s %d ", a[j], &b[j]);
printf("Array Created! YAY!\n");
return *number;
}
|
Hi fikal,
You have some excess asterisks. Let's start with the the quantity array.
int *quantity[100];
This declares quantity to be an array of 100 pointers to integers, but
you don't have 100 integers whose addresses you need to store. What
you want here is just an array of integers, so you can store up to 100
integers.
int quantity[100];
Once we make this change, we have to adjust all the references to this
array accordingly. So the b parameters to the restore and print
functions should be "int b[]" or "int* b" (these are equivalent), but
not "int *b[]".
In the restore function, fcanf expects a pointer to an integer. b is
an array of integers now, so b[j] is an integer, so &b[j] is a pointer
to an integer, so the existing code is correct.
In the print function, printf expects an integer parameter to match
the "%d". As we just saw, &b[j] is a pointer to an integer, not an
integer, so that expression does not work here. The function should
just pass the integer value b[j] to printf, not the address of b[j].
Similar considerations apply to the item array. You want an array of
100 19-character arrays, not an array of 100 arrays of 19 pointers to
characters. You don't have 1900 characters for all these pointers to
address, and you need a place to store the character data. So the
declaration should be:
char item[100][19];
As with the quantity array, we will need to change the function
parameters accordingly. The a parameters should be declared "char
a[][19]".
In the print function, printf expects a pointer to characters to match
the %s format specification. a[j] is actually an array of characters,
but it gets converted to a pointer to its first element when you pass
it as a parameter, so it will work with printf.
In the restore function, fscanf also expects a pointer to characters,
so a[j] also works there.
Similarly, the number variable in main should be an int, not a pointer
to int. When main calls print and restore, it should pass the address
of this variable, &number.
The number parameter in restore is a pointer to an integer, and the
first fscanf call needs a pointer to an integer to match the "%d"
specification. Therefore, the function should just pass number to
fscanf, not the address of number (&number) as it does now.
I think these are the main things to be fixed.
If you need more explanation of any of this advice or you find you
need more help to get the program working, please ask for a
clarification and I will advise you further.
Regards,
--efn |
Request for Answer Clarification by
fikal-ga
on
19 Nov 2004 11:30 PST
that worked great, i have made one small additoin to my example
program that i can not figure out. Theres something wrong with my add
function. I seem to have trouble with double arrays.
#include<stdio.h> /* input/output header */
int restore(char a[][19], int b[], int *number);
int print(char a[][19], int b[], int *number);
int add(char a[][19], int b[], int howmuch, char product, int *number);
int main(void)
{
/*int numbers, functions, characters, etc */
char item[100][19],char product;
int quantity[100];
int i;
int number=0,howmuch=0;
printf("1. To read chars.\n");
printf("2. To print chars.\n");
printf("3. To add chars.\n");
while (1) {
scanf("%d",&i);
if (i == 1) {
restore(item,quantity,&number);
i=0; }
if (i == 2) {
print(item,quantity,&number);
i=0; }
if (i == 3) {
scanf("%d%c",howmuch,product);
add(item,quantity, howmuch, product,&number);
i=0; }
}
return 0;
}
int print(char a[][19], int b[], int *number) {
int j;
for (j = 0; j < *number; j++)
printf( "%s %d ", a[j], b[j]);
return *number;
}
int restore(char a[][19], int b[], int *number) {
int j;
FILE * infile;
infile = fopen( "ryan.txt","r" );
fscanf( infile, "%d", number);
for (j = 0; j < *number; j++)
fscanf( infile, "%s %d ", a[j], &b[j]);
printf("Array Created! YAY!\n");
return *number;
}
int add(char a[][19], int b[], int howmuch, char product, int *number) {
if (*number == 0)
printf("Error: you must restore an order first\n");
*number++;
a[*number][19] = product;
b[*number] = howmuch;
return *number;
}
|
Clarification of Answer by
efn-ga
on
19 Nov 2004 18:40 PST
The scanf call in main needs work. As in other cases, a "%d" in scanf
calls for a pointer to an integer. howmuch is an integer, not a
pointer to an integer, so the main function should pass its address
(&howmuch), not its value.
I suspect you want product to be a character string, not a single
character. If this is so, it should be declared as a character array.
If it is, then passing its name to scanf will work, because the array
reference will be converted to a pointer to the array's first element.
If you make this change, you should change the declaration of the
product parameter to the add function accordingly. You should also
change the format specification passed to scanf from "%c" for a
character to "%s" for a string.
The add function assigns product to a[*number][19]. a[*number] is an
array of 19 characters and array subscripts start from zero, so the
elements of a[*number] are a[*number][0] through a[*number][18] and
a[*number][19] is beyond the bounds of the array. Unfortunately, C
does not protect you from errors like this.
If you take my advice above and make product a string instead of a
character, assigning it to a[*number] will not work. To copy a
character string, you need to use a library function like strcpy or
strncpy. strcpy is easier to use and strncpy is safer.
I hope this helps.
--efn
|
Request for Answer Clarification by
fikal-ga
on
20 Nov 2004 13:17 PST
here is the updated ver and im getting error C2440: '=' : cannot
convert from 'char [19]' to 'char'. Thanks in advance, ur very
helpful!
#include<stdio.h> /* input/output header */
#include<string.h> /* some basic string command */
int restore(char a[][19], int b[], int *number);
int print(char a[][19], int b[], int *number);
int add(char a[][19], int b[], int howmuch, char product[], int *number);
int main(void)
{
/*int numbers, functions, characters, etc */
char item[100][19], product[19];
int quantity[100];
int i;
int number=0,howmuch=0;
printf("1. To read chars.\n");
printf("2. To print chars.\n");
printf("3. To add chars.\n");
while (1) {
scanf("%d",&i);
if (i == 1) {
restore(item,quantity,&number);
i=0; }
if (i == 2) {
print(item,quantity,&number);
i=0; }
if (i == 3) {
scanf("%d%s",&howmuch,product);
add(item,quantity, howmuch, product,&number);
i=0; }
}
return 0;
}
int print(char a[][19], int b[], int *number) {
int j;
for (j = 0; j < *number; j++)
printf( "%s %d ", a[j], b[j]);
return *number;
}
int restore(char a[][19], int b[], int *number) {
int j;
FILE * infile;
infile = fopen( "ryan.txt","r" );
fscanf( infile, "%d", number);
for (j = 0; j < *number; j++)
fscanf( infile, "%s %d ", a[j], &b[j]);
printf("Array Created! YAY!\n");
return *number;
}
int add(char a[][19], int b[], int howmuch, char product[], int *number) {
char tempproduct[19];
int j=0;
if (*number == 0)
printf("Error: you must restore an order first\n");
*number++;
*number = j;
strcpy(tempproduct,product);
a[j][19] = tempproduct;
b[j] = howmuch;
return *number;
}
|
Clarification of Answer by
efn-ga
on
20 Nov 2004 18:13 PST
Hi Ryan,
*number = j;
This doesn't seem like a good idea. Since j has previously been set
to zero, this means that the add function sets number to zero back in
main, and the add function always stores data in element 0. Instead,
you can just use *number, as you had before.
strcpy(tempproduct,product);
a[j][19] = tempproduct;
While using strcpy is on the right track, this doesn't work, as the
compiler has told you. You don't need tempproduct, and there is still
no element 19 in a 19-element array, only 0 through 18. Instead, use
strcpy to copy from product directly to a[*number].
strcpy(a[*number], product);
--efn
|
Request for Answer Clarification by
fikal-ga
on
20 Nov 2004 21:03 PST
my add statement now looks like the following:
int add(char a[][19], int b[], int howmuch, char product[], int *number) {
if (*number == 0)
printf("Error: you must restore an order first\n");
*number++;
strcpy(a[*number], product);
b[*number] = howmuch;
return *number;
}
I get no errors but for some reason my print statement doesnt print
the new line and number still returns 3 instead of 4. any
suggestions. you are the best!
|
Clarification of Answer by
efn-ga
on
20 Nov 2004 22:43 PST
I missed this before.
1) *number++;
This could be parsed as
2) (*number)++;
or
3) *(number++);
Interpretation 2 increments the integer addressed by the number
pointer, which is what you want. Interpretation 3 increments the
number pointer so it no longer points to the number variable in main,
then gets the integer the pointer addresses and does nothing with that
integer.
The rules of operator precedence determine which interpretation the
compiler uses. As it happens, the ++ operator has higher precedence
than the * operator, so number clings to it rather than the *
operator, and the compiler uses the unwanted interpretation 3.
So you will have to add some parentheses to persuade the compiler to
use interpretation 2, to get the result you want.
--efn
|