c - 在 C 中覆盖文件中的行,奇怪的输出

标签 c file io fseek ftell

我试图逐行浏览一个文件(每行不超过 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

最佳答案

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,因此大多数时候,tmp 中没有 0 字节> 缓冲区,因此 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;

关于c - 在 C 中覆盖文件中的行,奇怪的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13408558/

相关文章:

c++ - 为 win32 线程使用不同的静态库内存

ruby - 将绝对路径转换为相对路径

python - 为什么在使用 Python 2.7.11 IDLE 时无法保存中文文件?

java - 在 Android 中检查文件是否为空

c - 如何在 C 中打印 ListView

C - 在多个函数中使用结构

c++ - 视频文件读写

android - 即使在 MEDIA_MOUNTED 状态下设置了权限和外部存储也无法写入 sdcard

java - 关于同时读取和写入文件的关注点是什么?

c++ - 是否有 C/C++ 函数可以安全地处理被零除?