1

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?

2
  • If you want to use fscanf, you'd better set a width. %19s for example. Commented Dec 24, 2013 at 4:21
  • stackoverflow.com/questions/19496440/… Commented Dec 24, 2013 at 4:29

2 Answers 2

0

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 usemyStringas thechar *argument infscanforfgets`. 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…)

Sign up to request clarification or add additional context in comments.

2 Comments

I got it to work but my question now is what exactly does fgets and fscanf return? And what does the value tell me?.. For example, fgets does it return a pointer to an character object? fscanf returns an int, what does that int mean??
The return value of fgets is a pointer to the string (char *) on success, and NULL` on error. fscanf returns the number is parameters (from parameter string) found and converted. If you pass three arguments and it finds only two, then it returns 2 and the last variable will have its old contents.
0

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 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.