C文件读取循环总是中断

C文件读取循环总是中断,c,fopen,eof,C,Fopen,Eof,我一直在研究C语言,现在正在开发一个简单的程序来读取文本文件,应用caesar密码,然后写入新的输出文件。我的问题是,构建输出字符串的while循环立即终止,声称下一个字符是EOF,即使它显然不是。代码如下: #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> #define MORD ".mord" void die(const char

我一直在研究C语言,现在正在开发一个简单的程序来读取文本文件,应用caesar密码,然后写入新的输出文件。我的问题是,构建输出字符串的while循环立即终止,声称下一个字符是EOF,即使它显然不是。代码如下:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#define MORD ".mord"

void die(const char *message)
{
  if(errno) {
    perror(message);
  } else {
    printf("ERROR: %s\n", message);
  }

  exit(1);
}

int main(int argc, char *argv[])
{
  if(argc != 3) die("USAGE: dodsmord <filename> <offset>");
  char *infilename = argv[1];
  char *outfilename = strcat(infilename, MORD);
  int offset = atoi(argv[2]);
  char *outstr[1000];
  FILE *infile = fopen(infilename, "r+");
  FILE *outfile = fopen(outfilename, "w+");
  if(infile == NULL) {
    die("Could not open input file");
  }
  if(outfile == NULL) {
    die("Could not open output file");
  }
  int c;
  int i = 0;
  printf("reading input file...\n");
  while(1) {
    c = fgetc(infile);
    printf("c == EOF: %d\n", c == EOF ? 1 : 0);
    printf("EOF: %d\n", EOF);
    printf("c is now: %c\n", c);
    if(c == EOF) break;
    outstr[i] = c + offset;
    i++;
  }
  printf("done reading! writing outstr to outfile...\n");
  fwrite(outstr, sizeof(char), i, outfile);

  printf("closing streams...\n");
  fclose(infile);
  fclose(outfile);

  return 0;
}
这和你想象的不一样

它设置了内嵌名,使其指向与argv[1]相同的内存,然后strcat更改该内存以附加.mord

然后它返回它,以便outfilename也指向内存

因此,您将输入文件名更改为.mord文件名,当您尝试打开它时,我不知道会发生什么,这取决于它是否存在

您想要的是:

char *infilename = argv[1];
char *outfilename = malloc (strlen (infilename) + strlen (MORD) + 1);
if (outfilename == NULL) {
    handleOutOfMemoryHere();
}
strcpy (outfilename, infilename);
strcat (outfilename, MORD);
:
// weave you cypher magic here
:
free (outfilename);

代码中的第二行将为输出文件名提供一个单独的内存区域,strcpy/strcat组合将正确地构造它。

问题是由以下原因引起的:

char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
原因:strcat执行就地复制并返回src的地址。试试这个,你会看到:

char *infilename = argv[1];
char *outfilename = strcat(infilename, MORD);
printf("TEST: %p %p\n", infilename, outfilename);
要解决此问题,请使用以下方法:

char *infilename = argv[1];
char *outfilename = malloc(strlen(infilename) + strlen(MORD) + 1);
strcpy(outfilenname, infilename);
strcat(outfilename, MORD);

问题出在下面这行

char *outfilename = strcat(infilename, MORD);
正在将InfineName修改为test.txt.mord

移动

在下一行之上

    char *outfilename = strcat(infilename, MORD);
问题是:

  char *infilename = argv[1];
  char *outfilename = strcat(infilename, MORD);
strcat将更改infilename,并将该MORD追加到其末尾,因此您使用argv[1].MORD作为输入文件名。我打赌这是一个空文件

解决方案:

改变

char *outfilename = strcat(infilename, MORD);


您已将变量c声明为int,并将其用作char。为什么??@Himanshu这是完全正确的。事实上,用于返回的变量(例如fgetc)必须是int,否则当它返回EOF时可能会发生奇怪的事情。您是否检查了输入文件中是否确实包含某些内容?它的大小不是零?@JoachimPileborg,你的意思是c==EOF有效吗??我不这么认为。@Himanshu绝对如此,这就是它应该如何使用的。注意,infilename指向argv[1],它是只读的,但strcat修改了它。您应该在strcatOk之前复制其内容,但其大小有限。实际上,argv需要根据C11 5.1.2.2.1/2进行修改:argc和argv参数以及argv数组指向的字符串应由程序进行修改,并在程序启动和程序终止之间保留其最后存储的值。我想把你答案中的那一段删掉。
    char *outfilename = strcat(infilename, MORD);
  char *infilename = argv[1];
  char *outfilename = strcat(infilename, MORD);
char *outfilename = strcat(infilename, MORD);
char *outfilename = malloc(strlen(infilename) + strlen(MORD) + 1);
if (outfilename == NULL) { /* malloc failed */ }
strcpy(outfilename, infilename);
strcat(outfilename, MORD);