简体   繁体   中英

Why does fscanf randomly change characters in my strings when I am trying to read a file in C?

I am writing a program in C in which I need to create an array of structs, save that array of structs into a file, then open that file, read that file, and copy the contents of that file into an array of structs (this particular struct called "friend" holds three strings). However, if the array holds three friends like this:

John Doe 234-1230 (string, string, string) <br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>

I get something like this once I save this array to a file an open it using the open function below:

Joán Doe 234-2132<br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>

or

John Doe 234-2132<br>
Kool Kat 343-3413<br>
Suz Q 234-1234<br>

where one string (almost always the first string in the struct) is almost the exact same with one or more random character(s) switched out. Can anyone tell me what is causing this error?

void open(friend* book, int* size){
   FILE *pRead;
   char address[100];
   char answer = 'a';
   printf("\nWARNING: Any unsaved data in the current phonebook will be lost!");
   printf("\nType the file-name you would like to open(press '1' for the default location):");
   scanf("%s", &address);

   if(strcmp(address, "1") == 0){
      strcpy(address, "default.dat");
   }

   pRead = fopen(address, "r");
   if(pRead == NULL){
      printf("\nFile not opened\n");
   }else{
      int counter = 0;
      while(!feof(pRead)){
         fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
         counter++;
         realloc(book, sizeof(friend) * counter);
      }
      *size = counter;
      fclose(pRead);
      printf("\n%s has been loaded into the program!", address);
   }
}

Other info: When I keep calling this function on the same file, it will eventually produce the correct strings, which makes me believe my save function is correct. Does this have to do with memory allocation?

Here is my struct code:

typedef struct Contact{ //creates a struct that holds three strings (first name, last name, phone number) (can be referred to as either Contact or friend
   char pFName[20]; //first name of friend
   char pLName[20]; //last name of contact
   char pNumber[12]; //phone number of contact
}friend;

I see a definite issue here:

  while(!feof(pRead)){
     fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
     counter++;
     realloc(book, sizeof(friend) * counter);
  }

You always read into memory you don't own, and then ask to realloc afterwards. Also, you ignore the return value from realloc . Even if you assume it will never be NULL, it is still allowed to relocate your data. It would be safer to do this:

  while(!feof(pRead)){
     book = realloc(book, sizeof(friend) * (counter+1));
     fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
     counter++;
  }

Now, accepting that book can change, you'll need to either pass it as a double pointer, or have your function return it.

There are other things here that you should avoid, such as the feof test, the fact that you're not checking the return value of fscanf , and that you're not protecting against buffer overflow. However, seeing your input and output, I don't think that any of these are directly affecting you right now.

There is an error on the scanf function when you are reading the file name.

scanf("%s", &address);

you should remove &.

However, this probably is not the cause of your problem because it works in the majority of the systems. Basically the problem here is that scanf("%s", &string) decay to a pointer-to-char[256] , while scanf is expecting a char * type. It works because the pointers &string and &string[0] are represented the same way. However, your code is depending on a thing which is not guarantee by the standard C which may have a different behaviour in a different system.

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