Почему в выходной строке отображаются данные, которые я никогда не писал?

Я пишу программу, которая шифрует файл, добавляя 10 к каждому символу. Каким-то образом часть рабочего каталога программы печатается в файл, и я понятия не имею, почему.

#include <stdio.h>
    int main(void){
        FILE *fp;
        fp=fopen("tester.csv","r+");
        Encrypt(fp);      
        fclose(fp);
    }

    int Encrypt(FILE *fp){
        int offset=10;
        Shift(fp, offset);
    }
    int Decrypt(FILE *fp){
        int offset= -10;
        Shift(fp, offset);
    }
    int Shift(FILE *fp, int offset){
        char line[50],tmp[50], character;
        long position;
        int i;
        position = ftell(fp);
        while(fgets(line,50,fp) != NULL){
            for(i=0;i<50;i++){
                character = line[i];
                character = (offset+character)%256;
                tmp[i] = character; 
                if(character=='\n' || character == 0){break;}                
            }
            fseek(fp,position,SEEK_SET);
            fputs(tmp,fp);
            position = ftell(fp);
            fseek(stdin,0,SEEK_END);
        }
      }

файл изначально читается

this, is, a, test
i, hope, it, works!

после запуска программы:

~rs}6*s}6*k6*~o}~
/alexio/D~6*y|u}+
k6*~o}~
/alexio/D

где users/alexio/Desktop является частью пути. Как это произошло???


person agarrow    schedule 16.11.2012    source источник


Ответы (3)


Поскольку вы «кодируете» строку, она не будет заканчиваться нулем (это ваш случай) или будет содержать нуль даже до конца строки (символ + смещение % 256 == 0). Позже вы пытаетесь записать его в виде строки, которая переполняет ваш буфер и выводит часть аргументов вашей программы.

Используйте fread и fwrite.

person Karoly Horvath    schedule 16.11.2012

Линия

fputs(tmp,fp);

выводит, вероятно, строку с ненулевым завершением. Таким образом, он продолжает копировать память в файл, пока не найдет нуль.

Вам нужно добавить ноль в конец «tmp» в случае, если цикл прерывается на новой строке.

person Keith    schedule 16.11.2012
comment
ваше решение имеет некоторые недостатки, см. мой ответ. - person Karoly Horvath; 16.11.2012

Несколько вещей:

  1. Вы кодируете все 50 символов из буфера чтения, независимо от того, сколько из них было фактически прочитано с помощью fgets(). Напомним, что fgets() читает строку, а не весь буфер (если только строка не длиннее буфера, а ваша нет). Все, что превышает длину строки из вашего строкового файла, является мусором стека.

  2. Затем вы сбрасываете все эти дополнительные мусорные данные и многое другое, не завершая свою строку tmp[] перед записью с помощью fputs(), которую вы все равно не должны использовать. Еще больше стекового мусора.

Решение. Используйте fread() и fwrite() для этой кодировки. Нет никаких причин использовать строковые функции. Когда вы будете писать свой декодер, вы поблагодарите себя за использование fread() и fwrite()

person WhozCraig    schedule 16.11.2012