C 我为什么要犯错?

C 我为什么要犯错?,c,segmentation-fault,fopen,C,Segmentation Fault,Fopen,我对C语言非常陌生,我试图一个字符一个字符地读取文件的内容,并将其输出到流中。但即使我的fopen()命令被注释掉了,我也会收到segfault(内核转储) 我必须运行命令:./a.outmyOut.txt才能正确执行我的文件 以下是我到目前为止的情况: #include <stdio.h> void main(char *fileName[]) { printf("filename is %s.\n",fileName[0]); //Get file based on

我对C语言非常陌生,我试图一个字符一个字符地读取文件的内容,并将其输出到流中。但即使我的fopen()命令被注释掉了,我也会收到segfault(内核转储)

我必须运行命令:./a.outmyOut.txt才能正确执行我的文件

以下是我到目前为止的情况:

#include  <stdio.h>
void main(char *fileName[]) 
{
  printf("filename is %s.\n",fileName[0]);
  //Get file based on a string inputed
  FILE *fp=fopen(fileName[0],"r"); //Fetches our file as read only
  char ch;
  int lineCount = 0;
  int wordCount = 0;
  int charCount = 0;

  //Failed to find/open file. NULL character.
  if (fp == 0) printf("Woops! Couldn't open file!\n");

  //While not at end of file, grab next char.
  else while( (ch=fgetc(fp)) != EOF) 
    {
      if (ch == '\n') //on newline
      {
    //Prints (charCount,wordCount)\n lineCount:
    printf("(%d,%d)%c%d:",charCount,wordCount,ch,lineCount);
    charCount = 0;
    lineCount += 1;
      }
      else printf("%c",ch); //mirrors char.
    }
  fclose(fp); //Closes file (gotta be tidy!)

}
#包括
void main(字符*文件名[])
{
printf(“文件名为%s.\n”,文件名[0]);
//根据输入的字符串获取文件
FILE*fp=fopen(文件名[0],“r”);//以只读方式获取文件
char ch;
int lineCount=0;
int字数=0;
int charCount=0;
//找不到/打开文件。空字符。
如果(fp==0)printf(“Woops!无法打开文件!\n”);
//不在文件末尾时,抓取下一个字符。
而((ch=fgetc(fp))!=EOF)
{
如果(ch=='\n')//在换行符上
{
//打印(字符数、字数)\n行数:
printf((%d,%d)%c%d:”,字符数,字数,ch,行数);
字符数=0;
行数+=1;
}
else printf(“%c”,ch);//镜像字符。
}
fclose(fp);//关闭文件(必须整洁!)
}

每当在C中出现segfault时,都应该在参数列表中嗅到错误的指针或地址。在这种特殊情况下,main的签名总是
intmain(intargc,char**argv)
。你的不是

你想要的是

int main(int argc, char ** argv) {
  ...
  FILE * fp = fopen(argv[1]); // Quiz: why argv[1]? What's argv[0]?
你在编译器中侥幸逃脱,基本上是因为运气


我还注意到,在您的示例调用中,参数列表中实际上没有参数,因为您使用的是重定向。

您不能仅仅发明一种调用
main
的方法。您需要使用以下标准方法之一:

int main(int argc, char *argv[])
{
    if (argc < 2) {
        fprintf(stderr, "Missing filename\n");
        return -1;
    }
    FILE *fp = fopen(argv[1], "r");
    // ...
}
intmain(intargc,char*argv[])
{
如果(argc<2){
fprintf(stderr,“缺少文件名\n”);
返回-1;
}
文件*fp=fopen(argv[1],“r”);
// ...
}
请注意,
argv[0]
包含程序名(如果可用,则包含空字符串)

程序出现故障,因为您在
char*filename[]
参数中收到了
int argc
参数。如果使用单个命令行参数运行程序,则作为第一个参数传入的值应为2,这不是有效的指针值。表达式
文件名[0]
取消对地址的引用并导致segfault。

使用:

int main(int argc, char* argv[])
并使用argv[1]作为文件名


Main函数必须始终接收这两个参数。

因为您正在调用未定义的行为。查看您的
main()
params。您似乎缺少了一些非常重要的内容。这消除了我的segfault,但通过我的命令:“./a.outmyOut.txt”我收到了缺少文件名的错误。为什么?因为您没有提供任何命令行参数。相反,您重定向了stdin和stdout。如果这是您想要的,那么就去掉所有的
文件
内容,只需从stdin读取并写入stdout(例如,使用
fgets
scanf
printf
)。