C - File input/output redirection and EOF
up vote
0
down vote
favorite
my C class is having us read from a file with an unknown number of entries but a known format, which goes like this:
firstname, lastname
address line 1
address line 2
zip code
So we're dynamically allocating an array of pointers to structs, and I made a function getData which will use gets to read line by line and store everything appropriately. My biggest problem is how to make it so that it stops collecting data when the file has nothing left to read. I have crudely come up with while((strcpy(ptr[i].name, buffer))!=EOF)
which I'm sure makes no sense but it seemed to somewhat work, especially because it correctly prints out almost every entry. Here is the code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "address.h"
struct AddressBook {
char *name[10];
char *address[50];
int zip;
};
typedef struct AddressBook adds;
void getData(adds *ptr);
int main() {
//adds *ptrArr[50];
int size = 50;
adds *ptrs = (adds*)calloc(size, sizeof(adds*)); //array of 50 ptrs allocated dynamically
if (ptrs == NULL) {
printf("Bad memory allocation...exiting.");
exit(0);
}
else
printf("Allocation successful...n");
getData(ptrs);
system("pause");
return 0;
}
void getData(adds *ptr) {
printf("Gathering data...n");
char buffer[50];
int i = 0;
gets(buffer);
while((strcpy(ptr[i].name, buffer))!=EOF) {
if (i > 0) {
gets(buffer);
strcpy(ptr[i].name, buffer);
}
/*gets(buffer);
strcpy(ptr[i].name, buffer);*/
gets(buffer);
strcpy(ptr[i].address, buffer);
gets(buffer);
strcat(ptr[i].address, " ");
strcat(ptr[i].address, buffer);
gets(buffer);
ptr[i].zip = atoi(buffer);
printf("Printing data for line %d...n", i);
printf("name is: %snaddress is: %snzip is: %dn", ptr[i].name, ptr[i].address, ptr[i].zip);
printf("n");
i++;
}
}
Two problems are happening:
1. When I print, it will print up to 50 entries, which is just the amount of space I asked for but the actual number of entries is far less.
2.It prints our every entry correctly except for line 2. (or subscript 1)
here is the input if you're curious: https://pastebin.com/Ph5wzFeF
here is the output for the first 3 entries:
Printing data for line 0...
name is: A1, A2
address is: 20294 Lorenzana Dr Woodland Hills, CA
zip is: 91364
Printing data for line 1...
name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1,
zip is: 94023
Printing data for line 2...
name is: C1, C2
address is: 5142 Dumont Pl Azusa, CA
zip is: 91112
Debugging has been a pain because I can't use i/o redirection and the visual studio debugger at the same time. If anyone has any suggestions as to how I can debug I would appreciate it! But otherwise I would like some feedback on what i've got.
c eof
|
show 3 more comments
up vote
0
down vote
favorite
my C class is having us read from a file with an unknown number of entries but a known format, which goes like this:
firstname, lastname
address line 1
address line 2
zip code
So we're dynamically allocating an array of pointers to structs, and I made a function getData which will use gets to read line by line and store everything appropriately. My biggest problem is how to make it so that it stops collecting data when the file has nothing left to read. I have crudely come up with while((strcpy(ptr[i].name, buffer))!=EOF)
which I'm sure makes no sense but it seemed to somewhat work, especially because it correctly prints out almost every entry. Here is the code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "address.h"
struct AddressBook {
char *name[10];
char *address[50];
int zip;
};
typedef struct AddressBook adds;
void getData(adds *ptr);
int main() {
//adds *ptrArr[50];
int size = 50;
adds *ptrs = (adds*)calloc(size, sizeof(adds*)); //array of 50 ptrs allocated dynamically
if (ptrs == NULL) {
printf("Bad memory allocation...exiting.");
exit(0);
}
else
printf("Allocation successful...n");
getData(ptrs);
system("pause");
return 0;
}
void getData(adds *ptr) {
printf("Gathering data...n");
char buffer[50];
int i = 0;
gets(buffer);
while((strcpy(ptr[i].name, buffer))!=EOF) {
if (i > 0) {
gets(buffer);
strcpy(ptr[i].name, buffer);
}
/*gets(buffer);
strcpy(ptr[i].name, buffer);*/
gets(buffer);
strcpy(ptr[i].address, buffer);
gets(buffer);
strcat(ptr[i].address, " ");
strcat(ptr[i].address, buffer);
gets(buffer);
ptr[i].zip = atoi(buffer);
printf("Printing data for line %d...n", i);
printf("name is: %snaddress is: %snzip is: %dn", ptr[i].name, ptr[i].address, ptr[i].zip);
printf("n");
i++;
}
}
Two problems are happening:
1. When I print, it will print up to 50 entries, which is just the amount of space I asked for but the actual number of entries is far less.
2.It prints our every entry correctly except for line 2. (or subscript 1)
here is the input if you're curious: https://pastebin.com/Ph5wzFeF
here is the output for the first 3 entries:
Printing data for line 0...
name is: A1, A2
address is: 20294 Lorenzana Dr Woodland Hills, CA
zip is: 91364
Printing data for line 1...
name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1,
zip is: 94023
Printing data for line 2...
name is: C1, C2
address is: 5142 Dumont Pl Azusa, CA
zip is: 91112
Debugging has been a pain because I can't use i/o redirection and the visual studio debugger at the same time. If anyone has any suggestions as to how I can debug I would appreciate it! But otherwise I would like some feedback on what i've got.
c eof
1
For starters, your name and address arrays should bechar
notchar*
, and yourcalloc
call should takesizeof(adds)
, notsizeof(adds*)
. You should not cast the return value ofcalloc
and you should range-checki
to ensure you don't overflow your buffer. Usefgets
instead ofgets
because the latter is extremely unsafe.
– paddy
Nov 19 at 1:14
I have no idea why i made them char * , thanks for pointing that out. I figured i should ask for size of(adds*) because i'm allocating an array of pointers, not an array of structs. should I still be asking for adds even knowing this? I will implement a range check, and I figured I couldn't use fgets because he wants us to only use file input/output redirection, we haven't learned how to work with files within the source code itself. It would be much easier if it were that way though!
– Taelle Echon
Nov 19 at 1:20
Usefgets
. Check the result offgets
.
– jxh
Nov 19 at 1:20
Given accesses likeptr[i].address
, it's clear you're not using it as an array of pointers. Otherwise you would be allocating each entry and usingptr[i]->address
. Not to mention that a dynamically-allocated array of pointers would be of typeadds**
. Regardingfgets
, you simply usestdin
as the file stream.
– paddy
Nov 19 at 1:23
Ahhh okay thank you, i'll try fgets and use stdin, and do you mean I should be dynamically allocating the structs as well? like within my while loop set ptr[i] to a new struct? I have tried it and couldnt get the syntax to agree with me. Let me know if I;m misunderstanding you.
– Taelle Echon
Nov 19 at 1:27
|
show 3 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
my C class is having us read from a file with an unknown number of entries but a known format, which goes like this:
firstname, lastname
address line 1
address line 2
zip code
So we're dynamically allocating an array of pointers to structs, and I made a function getData which will use gets to read line by line and store everything appropriately. My biggest problem is how to make it so that it stops collecting data when the file has nothing left to read. I have crudely come up with while((strcpy(ptr[i].name, buffer))!=EOF)
which I'm sure makes no sense but it seemed to somewhat work, especially because it correctly prints out almost every entry. Here is the code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "address.h"
struct AddressBook {
char *name[10];
char *address[50];
int zip;
};
typedef struct AddressBook adds;
void getData(adds *ptr);
int main() {
//adds *ptrArr[50];
int size = 50;
adds *ptrs = (adds*)calloc(size, sizeof(adds*)); //array of 50 ptrs allocated dynamically
if (ptrs == NULL) {
printf("Bad memory allocation...exiting.");
exit(0);
}
else
printf("Allocation successful...n");
getData(ptrs);
system("pause");
return 0;
}
void getData(adds *ptr) {
printf("Gathering data...n");
char buffer[50];
int i = 0;
gets(buffer);
while((strcpy(ptr[i].name, buffer))!=EOF) {
if (i > 0) {
gets(buffer);
strcpy(ptr[i].name, buffer);
}
/*gets(buffer);
strcpy(ptr[i].name, buffer);*/
gets(buffer);
strcpy(ptr[i].address, buffer);
gets(buffer);
strcat(ptr[i].address, " ");
strcat(ptr[i].address, buffer);
gets(buffer);
ptr[i].zip = atoi(buffer);
printf("Printing data for line %d...n", i);
printf("name is: %snaddress is: %snzip is: %dn", ptr[i].name, ptr[i].address, ptr[i].zip);
printf("n");
i++;
}
}
Two problems are happening:
1. When I print, it will print up to 50 entries, which is just the amount of space I asked for but the actual number of entries is far less.
2.It prints our every entry correctly except for line 2. (or subscript 1)
here is the input if you're curious: https://pastebin.com/Ph5wzFeF
here is the output for the first 3 entries:
Printing data for line 0...
name is: A1, A2
address is: 20294 Lorenzana Dr Woodland Hills, CA
zip is: 91364
Printing data for line 1...
name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1,
zip is: 94023
Printing data for line 2...
name is: C1, C2
address is: 5142 Dumont Pl Azusa, CA
zip is: 91112
Debugging has been a pain because I can't use i/o redirection and the visual studio debugger at the same time. If anyone has any suggestions as to how I can debug I would appreciate it! But otherwise I would like some feedback on what i've got.
c eof
my C class is having us read from a file with an unknown number of entries but a known format, which goes like this:
firstname, lastname
address line 1
address line 2
zip code
So we're dynamically allocating an array of pointers to structs, and I made a function getData which will use gets to read line by line and store everything appropriately. My biggest problem is how to make it so that it stops collecting data when the file has nothing left to read. I have crudely come up with while((strcpy(ptr[i].name, buffer))!=EOF)
which I'm sure makes no sense but it seemed to somewhat work, especially because it correctly prints out almost every entry. Here is the code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "address.h"
struct AddressBook {
char *name[10];
char *address[50];
int zip;
};
typedef struct AddressBook adds;
void getData(adds *ptr);
int main() {
//adds *ptrArr[50];
int size = 50;
adds *ptrs = (adds*)calloc(size, sizeof(adds*)); //array of 50 ptrs allocated dynamically
if (ptrs == NULL) {
printf("Bad memory allocation...exiting.");
exit(0);
}
else
printf("Allocation successful...n");
getData(ptrs);
system("pause");
return 0;
}
void getData(adds *ptr) {
printf("Gathering data...n");
char buffer[50];
int i = 0;
gets(buffer);
while((strcpy(ptr[i].name, buffer))!=EOF) {
if (i > 0) {
gets(buffer);
strcpy(ptr[i].name, buffer);
}
/*gets(buffer);
strcpy(ptr[i].name, buffer);*/
gets(buffer);
strcpy(ptr[i].address, buffer);
gets(buffer);
strcat(ptr[i].address, " ");
strcat(ptr[i].address, buffer);
gets(buffer);
ptr[i].zip = atoi(buffer);
printf("Printing data for line %d...n", i);
printf("name is: %snaddress is: %snzip is: %dn", ptr[i].name, ptr[i].address, ptr[i].zip);
printf("n");
i++;
}
}
Two problems are happening:
1. When I print, it will print up to 50 entries, which is just the amount of space I asked for but the actual number of entries is far less.
2.It prints our every entry correctly except for line 2. (or subscript 1)
here is the input if you're curious: https://pastebin.com/Ph5wzFeF
here is the output for the first 3 entries:
Printing data for line 0...
name is: A1, A2
address is: 20294 Lorenzana Dr Woodland Hills, CA
zip is: 91364
Printing data for line 1...
name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1, name is: B1, nam
address is: 1, name is: B1, name is: B1,
zip is: 94023
Printing data for line 2...
name is: C1, C2
address is: 5142 Dumont Pl Azusa, CA
zip is: 91112
Debugging has been a pain because I can't use i/o redirection and the visual studio debugger at the same time. If anyone has any suggestions as to how I can debug I would appreciate it! But otherwise I would like some feedback on what i've got.
c eof
c eof
asked Nov 19 at 1:10
Taelle Echon
214
214
1
For starters, your name and address arrays should bechar
notchar*
, and yourcalloc
call should takesizeof(adds)
, notsizeof(adds*)
. You should not cast the return value ofcalloc
and you should range-checki
to ensure you don't overflow your buffer. Usefgets
instead ofgets
because the latter is extremely unsafe.
– paddy
Nov 19 at 1:14
I have no idea why i made them char * , thanks for pointing that out. I figured i should ask for size of(adds*) because i'm allocating an array of pointers, not an array of structs. should I still be asking for adds even knowing this? I will implement a range check, and I figured I couldn't use fgets because he wants us to only use file input/output redirection, we haven't learned how to work with files within the source code itself. It would be much easier if it were that way though!
– Taelle Echon
Nov 19 at 1:20
Usefgets
. Check the result offgets
.
– jxh
Nov 19 at 1:20
Given accesses likeptr[i].address
, it's clear you're not using it as an array of pointers. Otherwise you would be allocating each entry and usingptr[i]->address
. Not to mention that a dynamically-allocated array of pointers would be of typeadds**
. Regardingfgets
, you simply usestdin
as the file stream.
– paddy
Nov 19 at 1:23
Ahhh okay thank you, i'll try fgets and use stdin, and do you mean I should be dynamically allocating the structs as well? like within my while loop set ptr[i] to a new struct? I have tried it and couldnt get the syntax to agree with me. Let me know if I;m misunderstanding you.
– Taelle Echon
Nov 19 at 1:27
|
show 3 more comments
1
For starters, your name and address arrays should bechar
notchar*
, and yourcalloc
call should takesizeof(adds)
, notsizeof(adds*)
. You should not cast the return value ofcalloc
and you should range-checki
to ensure you don't overflow your buffer. Usefgets
instead ofgets
because the latter is extremely unsafe.
– paddy
Nov 19 at 1:14
I have no idea why i made them char * , thanks for pointing that out. I figured i should ask for size of(adds*) because i'm allocating an array of pointers, not an array of structs. should I still be asking for adds even knowing this? I will implement a range check, and I figured I couldn't use fgets because he wants us to only use file input/output redirection, we haven't learned how to work with files within the source code itself. It would be much easier if it were that way though!
– Taelle Echon
Nov 19 at 1:20
Usefgets
. Check the result offgets
.
– jxh
Nov 19 at 1:20
Given accesses likeptr[i].address
, it's clear you're not using it as an array of pointers. Otherwise you would be allocating each entry and usingptr[i]->address
. Not to mention that a dynamically-allocated array of pointers would be of typeadds**
. Regardingfgets
, you simply usestdin
as the file stream.
– paddy
Nov 19 at 1:23
Ahhh okay thank you, i'll try fgets and use stdin, and do you mean I should be dynamically allocating the structs as well? like within my while loop set ptr[i] to a new struct? I have tried it and couldnt get the syntax to agree with me. Let me know if I;m misunderstanding you.
– Taelle Echon
Nov 19 at 1:27
1
1
For starters, your name and address arrays should be
char
not char*
, and your calloc
call should take sizeof(adds)
, not sizeof(adds*)
. You should not cast the return value of calloc
and you should range-check i
to ensure you don't overflow your buffer. Use fgets
instead of gets
because the latter is extremely unsafe.– paddy
Nov 19 at 1:14
For starters, your name and address arrays should be
char
not char*
, and your calloc
call should take sizeof(adds)
, not sizeof(adds*)
. You should not cast the return value of calloc
and you should range-check i
to ensure you don't overflow your buffer. Use fgets
instead of gets
because the latter is extremely unsafe.– paddy
Nov 19 at 1:14
I have no idea why i made them char * , thanks for pointing that out. I figured i should ask for size of(adds*) because i'm allocating an array of pointers, not an array of structs. should I still be asking for adds even knowing this? I will implement a range check, and I figured I couldn't use fgets because he wants us to only use file input/output redirection, we haven't learned how to work with files within the source code itself. It would be much easier if it were that way though!
– Taelle Echon
Nov 19 at 1:20
I have no idea why i made them char * , thanks for pointing that out. I figured i should ask for size of(adds*) because i'm allocating an array of pointers, not an array of structs. should I still be asking for adds even knowing this? I will implement a range check, and I figured I couldn't use fgets because he wants us to only use file input/output redirection, we haven't learned how to work with files within the source code itself. It would be much easier if it were that way though!
– Taelle Echon
Nov 19 at 1:20
Use
fgets
. Check the result of fgets
.– jxh
Nov 19 at 1:20
Use
fgets
. Check the result of fgets
.– jxh
Nov 19 at 1:20
Given accesses like
ptr[i].address
, it's clear you're not using it as an array of pointers. Otherwise you would be allocating each entry and using ptr[i]->address
. Not to mention that a dynamically-allocated array of pointers would be of type adds**
. Regarding fgets
, you simply use stdin
as the file stream.– paddy
Nov 19 at 1:23
Given accesses like
ptr[i].address
, it's clear you're not using it as an array of pointers. Otherwise you would be allocating each entry and using ptr[i]->address
. Not to mention that a dynamically-allocated array of pointers would be of type adds**
. Regarding fgets
, you simply use stdin
as the file stream.– paddy
Nov 19 at 1:23
Ahhh okay thank you, i'll try fgets and use stdin, and do you mean I should be dynamically allocating the structs as well? like within my while loop set ptr[i] to a new struct? I have tried it and couldnt get the syntax to agree with me. Let me know if I;m misunderstanding you.
– Taelle Echon
Nov 19 at 1:27
Ahhh okay thank you, i'll try fgets and use stdin, and do you mean I should be dynamically allocating the structs as well? like within my while loop set ptr[i] to a new struct? I have tried it and couldnt get the syntax to agree with me. Let me know if I;m misunderstanding you.
– Taelle Echon
Nov 19 at 1:27
|
show 3 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53367105%2fc-file-input-output-redirection-and-eof%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
For starters, your name and address arrays should be
char
notchar*
, and yourcalloc
call should takesizeof(adds)
, notsizeof(adds*)
. You should not cast the return value ofcalloc
and you should range-checki
to ensure you don't overflow your buffer. Usefgets
instead ofgets
because the latter is extremely unsafe.– paddy
Nov 19 at 1:14
I have no idea why i made them char * , thanks for pointing that out. I figured i should ask for size of(adds*) because i'm allocating an array of pointers, not an array of structs. should I still be asking for adds even knowing this? I will implement a range check, and I figured I couldn't use fgets because he wants us to only use file input/output redirection, we haven't learned how to work with files within the source code itself. It would be much easier if it were that way though!
– Taelle Echon
Nov 19 at 1:20
Use
fgets
. Check the result offgets
.– jxh
Nov 19 at 1:20
Given accesses like
ptr[i].address
, it's clear you're not using it as an array of pointers. Otherwise you would be allocating each entry and usingptr[i]->address
. Not to mention that a dynamically-allocated array of pointers would be of typeadds**
. Regardingfgets
, you simply usestdin
as the file stream.– paddy
Nov 19 at 1:23
Ahhh okay thank you, i'll try fgets and use stdin, and do you mean I should be dynamically allocating the structs as well? like within my while loop set ptr[i] to a new struct? I have tried it and couldnt get the syntax to agree with me. Let me know if I;m misunderstanding you.
– Taelle Echon
Nov 19 at 1:27