Перезапись строк в файле на C, странный вывод
Я пытаюсь пройтись по файлу построчно (каждая строка не более 50 символов), сдвинуть каждый символ на 10 или -10 (для шифрования и дешифрования), а затем распечатать сдвинутую строку там, где была старая строка. Но я получаю действительно забавный вывод.
вот код:
#include <stdio.h>
int main(void){
FILE *fp;
fp=fopen("tester.csv","r+");
Encrypt(fp); // I call decrypt here when I test it.
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 = (character+offset)%256;
tmp[i] = character;
}
fseek(fp,position,SEEK_SET);
fputs(tmp, fp);
position = ftell(fp);
}
}
так что если tester.csv изначально читает
this, is, a, test
запуск программы производит
~rs}6*s}6*k6*~o}~
êñv[ ‰
this, is, a, test
3 ответа
fputs(tmp, fp);
fputs
записывает байты до завершающего 0 байта.
while(fgets(line,50,fp) != NULL){
for(i=0;i<50;i++){
character = line[i];
character += offset;
tmp[i] = character;
}
тебе смена 50 char
s, независимо от того, какой длины была строка, в которой вы читали, и, следовательно, большую часть времени, в байте нет 0-байтов. tmp
буфер, таким образом fputs
часто записывает не менее 50 байтов, некоторые из которых не имеют ничего общего с тем, что было в файле в этом месте, и выходят за пределы буфера, что вызывает неопределенное поведение и может вызвать сбой.
Вы должны проверить завершающий 0-байт в цикле, возможно, даже остановка на новой строке - хорошая идея.
while(fgets(line,50,fp) != NULL){
for(i = 0; i < 50 && line[i] != 0 && line[i] != '\n'; i++){
character = line[i];
character += offset;
tmp[i] = character;
}
Примечание: тело цикла будет проще line[i] += offset;
,
Попробуйте использовать GDB для отладки вашей программы, так как она шифруется.
Компилировать с:gcc -g -Wall YOURPROGRAM.cxx
Запустите GDB:gdb YOURPROGRAM.cxx
Установить точку останова:
Перерыв в строке 3: break 3
Отладка вашей программы: run
Вы можете пройти через каждую строку кода, используя step
а также next
и распечатывать переменные в каждой точке, используя print VARIABLENAME
, Это мощная программа, и она действительно полезна при отладке.
Вы, вероятно, не должны использовать линейно-ориентированные fgets()
а также fputs()
так как вы могли бы получить NUL '\0'
символы в выходных данных о шифровании, а во входных данных о дешифровании (и переводы строк будут. Использование fread()
а также fwrite()
, Убедитесь, что вы обрабатываете правильное количество символов тоже; fgets()
может не возвращать 49 символов и NUL; строка может быть короче, и вы все равно не хотите обрабатывать NUL.