问题
I need to write a program to read from a file, then save the words into a linked list for further use. I decided to read the text character by character using fgetc, then save all into the list each time a newline ('\n') or space (' ') is detected, indicating one word.
Sorry I'm a newbie in file pointers, this is what I've gotten so far:
struct list { //global
char string[30];
struct list *next;
};
int main(void) {
FILE *filePtr;
char file[] = "text.txt";
char tempStr[30];
list *curr, *header;
char c;
int i = 0;
curr = NULL;
header = NULL;
if((filePtr = fopen(file, "r")) == NULL) {
printf("\nError opening file!");
getchar();
exit(101);
}
printf("\nFile is opened for reading.\n");
while(!EOF) {
while((c = fgetc(filePtr) != ' ') && (c = fgetc(filePtr) != '\n')) {
curr = (list*)malloc(sizeof(list));
//c = fgetc(filePtr);
tempStr[i] = fgetc(filePtr);
i++;
}
tempStr[i] = '\0';
strcpy(curr->string, tempStr);
curr->next = header;
header = curr;
i = 0;
}
while(curr!=NULL) {
printf("%s - ", curr->string); //This will not print.
curr = curr->next;
}
if(fclose(filePtr) == EOF) {
printf("\nError closing file!");
getchar();
exit(102);
}
printf("\nFile is closed.\n");
getchar();
getchar();
}
If the text file:
have a nice day
Desired output:
have - a - nice - day
But, I could not print out anything except the file opened and closed.
Thanks.
回答1:
Value of the macro EOF is -1, which is a system macro defined in stdio.h. File read APIs(fgetc, fread, fscanf) will return -1 once it reaches end of file. So in your program you have while(!EOF) this will be always false, because NOT of -1 is always 0. -1 will be represented in 2's complement so all bits of that variable will be 1. (If size of int is 2, -1 will be stored as 0xFFFF in int variable).
Use the below sample code.
while(EOF != (c = fgetc(filePtr)))
{
if ((c == ' ') || (c == '\n'))
{
if (i == 0)
{
continue;
}
tempStr[i] = '\0';
i = 0;
//here do your linklist node creation and insertion operation
continue;
}
tempStr[i] = c;
i++;
}
回答2:
while(!EOF) {
This is a constant condition that is always false, so you never read anything.
Your code also has other problems, such as doing
curr = (list*)malloc(sizeof(list));
in a loop but using curr outside the loop.
回答3:
You should replace the while condition with whatever function you're using to read the file - are you sure fgets isn't horrendously more efficient than this?
IE read the string into a much larger buffer than you expect, then copy it into an appropriately sized buffer and attach that to the node.
回答4:
This is always false:
while(!EOF)Review your memory allocation code.
curr = (list*)malloc(sizeof(list))Files may not have newlines at the end of the file.
while((c = fgetc(filePtr) != ' ') && (c = fgetc(filePtr) != '\n'))
回答5:
Spoiler:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list {
struct list *next;
char string[30];
};
int main(void) {
FILE *fp;
char file[] = "llist4.c";
/* in C you CANNOT omit the "struct keyword" from a declaration or definition. */
struct list *head=NULL, **pp= &head;
int ch; /* getc() returns an int */
size_t len ;
char buff[30];
fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "\nError opening file!");
exit(EXIT_FAILURE);
}
printf("\nFile has been opened for reading.\n");
for (len=0; len < sizeof buff; ) {
ch = fgetc(fp);
if (ch == EOF && !len) break;
if (ch == ' ' || ch == '\n' || ch == EOF) {
if (!len) continue;
buff[len] = '\0';
*pp = malloc(sizeof **pp);
if (!*pp) break;
strcpy((*pp)->string, buff);
(*pp)->next = NULL;
pp = &(*pp)->next ;
len=0; continue;
}
buff[len++] = ch;
}
if (len) {
fprintf(stderr, "\nWord was too large, or out of memory\n");
}
for( ;head; head= head->next) {
printf("%s - ", head->string);
}
if (fclose(fp) == EOF) {
fprintf(stderr, "\nError closing file!\n");
exit(EXIT_FAILURE);
}
printf("\nFile has been closed.\n");
exit(EXIT_SUCCESS);
}
来源:https://stackoverflow.com/questions/11168381/read-word-from-file-into-simple-linked-list