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.










share|improve this question


















  • 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












  • 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










  • 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















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.










share|improve this question


















  • 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












  • 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










  • 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













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.










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 at 1:10









Taelle Echon

214




214








  • 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












  • 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










  • 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














  • 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












  • 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










  • 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








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

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















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






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














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





















































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







Popular posts from this blog

Create new schema in PostgreSQL using DBeaver

Deepest pit of an array with Javascript: test on Codility

Costa Masnaga