Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
229 views
in Technique[技术] by (71.8m points)

c - How to use fscanf() for two strings (of ANY length) and dynamically allocate/de-allocate the memory properly

I need to read an input .txt file and print out two separate strings from each line in the file. I used a while loop and a fscanf function to get each string and ignore blank space between. If the strings in a line of the input file are too long, I get a segmentation fault. However, I am also getting a munmap_chunk(): invalid pointer error when I run my executable.

If I don't allocate memory for string1 and string2, fscanf doesn't work properly. I believe fscanf is changing the pointers to string1 and string2, which is causing the munmap_chunk() error. However, I need to de-allocate the memory I gave string1 and string2 so I don't have memory leaks.

How do I scan this file for strings (of ANY length) and de-allocate the memory properly?

int main(int argc, char *argv[]) 
{
  char *string1;
  char *string2;
  string1 = (char *)malloc(sizeof(string1)); //these strings need memory allocated for the fscanf to function properly
  string2 = (char *)malloc(sizeof(string2)); 
  FILE* file = fopen(argv[1], "r");
  
  while (fscanf(file, "%s %s", string1, string2) != EOF)
    {
      printf("%s %s
", string1, string2);
    }
  fclose(file);

  //Deallocating memory
  free(string1);
  free(string2);
  return 0;
}
question from:https://stackoverflow.com/questions/66055845/how-to-use-fscanf-for-two-strings-of-any-length-and-dynamically-allocate-de

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

'fscanf' does not change pointers but it can corrupt memory if you do not allocate enough space for your input.

And you are not allocating the memory correctly: string1 and string2 are pointers, so all you are allocating is a size of a pointer (4 or 8 bytes depending on your system).

If you need to read a line from a file and you do not know the maximum length of the line in advance, you can not use fscanf.

You need to allocate a starting buffer, say something like:

string1 = malloc(512 * sizeof(char));

Were 512 is an arbitrary but reasonably large length for a line. You then use fread to read one byte at a time in a loop, and check for end of line (usually ' ').

You must also count how much you read, and if the line is longer than 512 bytes, use realloc to increase the size of your buffer, like so:

if (bytesRead == (string1Size - 1) && curByte != '
') {
    string1Size += 512;
    string1 = realloc(string1, string1Size);
}

Here, bytesRead is an int variable counting how many bytes you successfully read so far, and string1Size is also int variable used to track the size of string1 buffer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...