Using fread and fwrite in one stream at the same time caused a problem
This program want to read from a file. the content in the file is the string "Hello, world". then judge each character of the string to see if the character greater than or equal to the const character 'e', if the character meet the condition, than change the character to its previous character in the alphabetical order (eg. 'b' change to 'a', 'e' change to 'd'). Finally, output the changed file content to the screen.
The question is how do the fwrite and fread work? why can't I get rid off the variable pos2 to simplify the expression. If anyone can help, thanks a lot!
#include <stdio.h>
int main()
{
FILE *fp;
char s[20];
char t[20];
char transfer;
int i;
int pos; // storing the position of the file before reading from the file
int pos1; // check the position of the file
int pos2; // storing the position of the file after reading from the file
#pragma region create a file named "Hello", write "Hello, world" into the file, close it
if ((fp = fopen("Hello", "wb") )== NULL)
{
printf("can't open file\n");
exit(0);
}
strcpy(s, "Hello, world");
fwrite(s, sizeof(char)*20, 1, fp);
fseek(fp, 0, SEEK_SET);
fclose(fp);
#pragma endregion create a file named "Hello", write "Hello, world" into the file, close it
#pragma region read from the file named "Hello", deal with its current, write the change into the file.
if ((fp = fopen("Hello", "rb+")) == NULL )
{
printf("can't open file\n");
exit(1);
}
i = 0;
while(i < 20)
{
// 提问,该处为何不能利用fwrite的自动定位免去注释掉的语句行(即使用了pos2的语句行)。
// Here is the problem. since the fread and fwrite function can move the position of the
// file, I think I can get rid off the following commented two sentences with the
// variable pos2 in it
pos = ftell(fp); // storing the position before reading from file
fread(&transfer, sizeof(char), 1, fp); // the position of the file moved to the next char
// pos2 = ftell(fp); // storing the position after reading from file
pos1 = ftell(fp);
if (transfer >= 'e') // if the character greater or equal to 'e' minus 1.
{
transfer -= 1;
}
fseek(fp, pos, SEEK_SET); // back to the position where the character is read to change the char
fwrite(&transfer, sizeof(char), 1, fp);// the position of the file moved to the next char
// fseek(fp, pos2, SEEK_SET); //
pos1 = ftell(fp);
i++;
}
fseek(fp, 0, SEEK_SET);
fclose(fp);
#pragma endregion read from the file named "Hello", deal with its current, write t开发者_如何学JAVAhe change into the file.
#pragma region read from the file named "Hello", output the changed string
if((fp = fopen("Hello", "rb")) == NULL)
{
printf("Can't open file\n");
exit(2);
}
fread(t, sizeof(char)*20, 1, fp);
printf("The output is: %s \n", t);
// the right output is (the two sentences above with pos2 in it is commented) :
// The output is: Hdkkn,vnqkd
// the wrong output is (the two sentences above with pos2 in it isn't commented):
// The output is: Hddddddddddddddddddd烫烫烫烫Hello, world
fseek(fp, 0, SEEK_SET);
fclose(fp);
#pragma endregion read from the file named "Hello", output the changed string
system("pause");
}
I didn't actually get the point why you are trying to comment in/out the 2 lines. Because nothing changes whether you comment them in or comment them out. You have already got rid of pos2 in your code (which is what you are asking).
So if you use the following code for your while loop
pos = ftell(fp); // storing the position before reading from file
fread(&transfer, sizeof(char), 1, fp);
pos1 = ftell(fp);
if (transfer >= 'e') // if the character greater or equal to 'e' minus 1.
{
transfer -= 1;
}
fseek(fp, pos, SEEK_SET);
fwrite(&transfer, sizeof(char), 1, fp);
i++;
then you get "The output is: Hdkkn,vnqkd" which is the expected result.
You could also take each line from the file to an array and make operations on it then write it back to the file. By this way, it could be more generic and you don't have to use magic numbers like "20".
EDIT:
I use gcc 4.5.2 on my linux platform. I don't want to comment on other platforms but as I mentioned before you could take the line to a buffer and then after operation you could write it back. You could try to replace the following code with your while loop:
char line[20] = {0};
fread(line, sizeof(char), 20, fp);
for(i = 0; i < strlen(line); i++)
{
if(line[i] >= 'e')
line[i] -= 1;
}
fseek(fp, 0, SEEK_SET);
fwrite(line, sizeof(char), strlen(line), fp);
By this way you could get rid of many variables. It is your choice.
精彩评论