Использование fread и fwrite в одном потоке одновременно вызвало проблему - PullRequest
0 голосов
/ 06 сентября 2011

Эта программа хочет читать из файла. содержимое файла представляет собой строку «Hello, world». затем оцените каждый символ строки, чтобы увидеть, если символ больше или равен константному символу 'e', ​​если символ соответствует условию, чем заменить символ на свой предыдущий символ в алфавитном порядке (например, изменить 'b' на «а», «е» изменить на «д»). Наконец, выведите измененное содержимое файла на экран.

Вопрос в том, как работают fwrite и fread? почему я не могу избавиться от переменной pos2, чтобы упростить выражение. Если кто-то может помочь, большое спасибо!

#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 the 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");
}

1 Ответ

0 голосов
/ 06 сентября 2011

На самом деле я не понял, почему вы пытаетесь закомментировать две строки.Потому что ничего не изменится, комментируете ли вы их или комментируете.Вы уже избавились от pos2 в своем коде (о чем вы и просите).

Итак, если вы используете следующий код для цикла while

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++;

, вы получите «Результат: Hdkkn, vnqkd», который является ожидаемым результатом.

Вы также можете перенести каждую строку из файла в массив и выполнить над ним операции, а затем записать ее обратно в файл.Таким образом, это может быть более общим, и вам не нужно использовать магические числа, такие как «20».

РЕДАКТИРОВАТЬ:

Я использую gcc 4.5.2 на моей платформе Linux.Я не хочу комментировать другие платформы, но, как я упоминал ранее, вы можете перенести строку в буфер, а затем после операции вы можете записать ее обратно.Вы можете попробовать заменить следующий код на цикл while:

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);

Таким образом вы сможете избавиться от многих переменных.Это ваш выбор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...