简体   繁体   中英

Reading string input from file in C

I have a text file called "graphics" which contains the words "deoxyribonucleic acid".

When I run this code it works and it returns the first character. "d"

int main(){

    FILE *fileptr;                          
    fileptr = fopen("graphics.txt", "r");   
    char name;

    if(fileptr != NULL){ printf("hey \n"); }
    else{ printf("Error"); }

    fscanf( fileptr, "%c", &name);
    printf("%c\n", name);
    fclose( fileptr );

    return 0;
}

When I am using the fscanf function the parameters I am sending are the name of the FILE object, the type of data the function will read, and the name of the object it is going to store said data, correct? Also, why is it that I have to put an & in front of name in fscanf but not in printf ?

Now, I want to have the program read the file and grab the first word and store it in name. I understand that this will have to be a string (An array of characters). So what I did was this: I made name into an array of characters that can store 20 elements.

char name[20];

And changed the parameters in fscanf and printf to this, respectively:

fscanf( fileptr, "%s", name);
printf("%s\n", name);

Doing so produces no errors from the compiler but the program crashes and I don't understand why. I am letting fscanf know that I want it to read a string and I am also letting printf know that it will output a string. Where did I go wrong? How would I accomplish said task?

This is a very common problem. fscanf reads data and copies it into a location you provide; so first of all, you need the & because you provide the address of the variable (not the value) - that way fscanf knows where to copy TO.

But you really want to use functions that copy "only as many characters as I have space". This is for example fgets() , which includes a "max byte count" parameter:

char * fgets ( char * str, int num, FILE * stream );

Now, if you know that you only allocated 20 bytes to str , you can prevent reading more than 20 bytes and overwriting other memory.

Very important concept!

A couple of other points. A variable declaration like

char myString[20];

results in myString being a pointer to 20 bytes of memory where you can put a string (remember to leave space for the terminating '\\0' !). So you can use !). So you can use myString as the char * argument in fscanf or fgets`. But when you try to read a single character, and that characters was declared as

char myChar;

You must create the pointer to the memory location "manually", which is why you end up with &myChar .

Note - if you want to read up to white space, fscanf is the better function to use; but it will be a problem if you don't make sure you have the right amount of space allocated. As was suggested in a comment, you could do something like this:

char myBuffer[20];
int count = fscanf(fileptr, "%19s ", myBuffer);
if(count != 1) {
  printf("failed to read a string - maybe the name is too long?\n");
}

Here you are using the return value of fscanf (the number of arguments correctly converted). You are expecting to convert exactly one; if that doesn't work, it will print the message (and obviously you will want to do more than print a message…)

Not answer of your question but; for more efficient memory usage use malloc instead of a static declaration.

char *myName // declara as pointer
myName = malloc(20) // same as char[20] above on your example, but it is dynamic allocation

... // do your stuff

free(myName) // lastly free up your allocated memory for myName

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM