【问题标题】:How to fix 'Segmentation Fault(core dumped)' error when reading characters from two input files?从两个输入文件读取字符时如何修复“分段错误(核心转储)”错误?
【发布时间】:2015-06-11 09:02:26
【问题描述】:

我正在编写加密程序,但由于错误:“分段错误(核心转储)”而停止。下面的程序假设从两个输入文件打印:

第一个输入文件:先读入,然后大写转小写,小写转大写。

第二个输入文件:应该被读入并且只打印用户想要的字符在文件中出现的次数。在这种情况下,我想要的用户想要的字符是字母“a”。

假设第一个输入文件(input.txt)包含: 你好,我叫乔

这应该打印为:你好,我的名字是乔

假设第二个输入文件(keys.txt)包含:

一个

M

这应该只打印字符:A

注意这并不一定加密输入文件,但是,我正在尝试熟悉一次使用多个输入文件。我可以使用我能得到的所有帮助!谢谢!

另外,编译时,代码应如下所示:

gcc myProgram.c

./a.out e input.txt keys.txt

(上面的“e”代表加密。)

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


 int main(int args, char *argc[]){

 int i,c,x,len,len2;
 char str[1024];
 char str2[500];
 FILE *finp;
 FILE *keyFile;

 /* ****** CODE TO ENCRYPT STARTS HERE ****** */
 if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
 &&((keyFile=fopen(argc[3],"r"))==NULL)){

 printf("Could Not Open file %s\n", argc[2]);
 exit(1);

 }//End First IF statement


/* *** START CODE TO GRAB FROM 1st INPUT FILE: input.txt *** */
/*Grab strings from first input file and change lower case to upper case and         
upper to lower case*/

 while(fgets(str,1024,finp)!=NULL){

  len = strlen(str);
  for(i>0;i<len;++i){
  if(((str[i]>=64)&&(str[i]<=90))||((str[i]>=97&&(str[i]<=122))))
  str[i]^=32;}}
  /* *** END OF CODE FOR 1st INPUT FILE **** */



  /* *** START CODE TO GRAB FROM 2nd INPUT FILE: keys.txt **** */
  /*Grab character from second input file and print the character*/

  while(fgets(str2,500,keyFile)!=NULL){

  len2 = strlen(str2);
  for(x>0;x<len2;++x){
   if(str2[x]=='A'){
   putchar(str2[x]);
   }}
   /* ***** END CODE FOR 2nd INPUT FILE*** */


   }


   printf("%s\n",str);

   fclose(finp);
   return 0;}

【问题讨论】:

  • 你说的是简单的'return 1'吗?
  • 你永远不会在 for 循环中初始化 xi
  • 您能否解释一下您在我的 if 语句中所说的非常错误的条件?我现在明白你所说的 'argc[1]="e"' 是什么意思了。
  • @iharob argc[1]="e" 如果argc 是可写的,则保证为真,而argc[1]=="e" 则保证为假。 (但是 argc[1]="e" 具有未定义的行为,因为不能保证数组是可写的。)此外:Raoul,不要使用这样的非标准名称 - 标准参数名称是 int main(int argc, char *argv[]),并使用 argc 表示数组参数和args 的数字真的很混乱。
  • @Gilles 我第一次没有注意到赋值运算符。

标签: c arrays input command-line-arguments


【解决方案1】:

在您的代码中

(argc[1]="e")

应该是

!strcmp(argv[1], "e")

argc[2]argc[3] 出现同样的错误。

请记住,argc 的类型为 int(不是数组)。 argv[] 的类型为 char *

也就是说,您应该始终检查argc 值与n 之间的对比,以免使用argv[n-1]

那么,请记住,&amp;&amp; 的第二个操作数只有在第一个操作数产生 TRUE 值时才会被计算。你应该检查你正在使用的逻辑

  if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
                                &&((keyFile=fopen(argc[3],"r"))==NULL))

我认为它不能达到你想要的目的。

另外,正如 @iharob 先生所指出的,您似乎从来没有初始化在您的任一 for 循环中使用的计数器变量。这将导致未定义的行为。

【讨论】:

  • 我已尝试使用您建议的代码修复我的代码并收到众所周知的“总线错误(核心转储)”。这有什么意义?
  • @RaoulDuke 还有很多其他错误。寻找更新的答案。
  • @dear downvoter,有了您的善意评论,我有机会纠正和改进我的答案。请考虑留下一个。
【解决方案2】:

你有很多很多错误

  1. 第一个if声明,完全错误

    1. argc[1] = "e",从很多角度来看都是错误的,首先你不能用==运算符来计算字符串,但是你没有使用比较运算符,它是赋值运算符,你不能分配给数组,所以它是双重错误的。
    2. 您使用&amp;&amp; 运算符检查两个文件是否同时位于NULL,如果其中只有一个是错误的,则使后面的代码调用未定义的行为,可能导致分段错误
  2. 您永远不会检查程序是否使用正确数量的参数调用,但您仍然可以访问 argc 数组,顺便说一下,通常是 argvargc 用于参数,即您在哪里使用args,但这实际上并不重要。

  3. 您的for 循环也错误

    for (i > 0 ... )
    

    你永远不会初始化i,而且对字符串在c中如何工作有一点了解,会让c程序员编写以下循环来遍历字符串

    for (i = 0 ; ((str[i] != '\n') && (str[i] != '\0')) ; ++i)
    

    由于fgets() 将读取通过按 Return/Enter 键插入的尾随 '\n' 并因此刷新标准输入,因此您需要检查 str[i] == '\n' 但如果您是偏执狂,您应该还要检查'\0'我是偏执狂,我确实检查了虽然这效率低下,但我更喜欢这样做而不是以后看到意想不到的事情。

这是您的程序示例,没有错误,我不知道它是否符合您的要求,但它是相同的程序,只是有错误可能导致 SEGMENTATION FAULT 更正

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

int main(int argc, char *argb[])
{
    int   i;
    char  str[1024];
    char  str2[500];
    FILE *inputFile;
    FILE *keyFile;

    if (argc < 3) /* insufficient number of parameters provided */
        return -1;
    if (argb[1][0] == 'e')
        return 0;
    inputFile = fopen(argb[2], "r");
    if (inputFile == NULL)
     {
        printf("Could Not Open file %s\n", argb[2]);
        return -1;
     }
    keyFile = fopen(argb[3], "r");
    if (keyFile == NULL)
     {
        printf("Could Not Open file %s\n", argb[2]);

        fclose(inputFile);
        return -1;
     }

    while (fgets(str, sizeof(str), inputFile) != NULL)
    {
        for (i = 0 ; ((str[i] != '\n') && (str[i] != '\0')) ; ++i)
        {
            if (((str[i] >= 64) && (str[i] <= 90)) || ((str[i] >= 97) && (str[i]<=122)))
                str[i] ^= 32;
        }
    }

    while (fgets(str2, sizeof(str2), keyFile) != NULL)
     {
        for (i = 0 ; ((str2[i] != '\n') && (str2[i] != '\0')) ; ++i)
         {
            if (str2[i] == 'A')
                putchar(str2[i]);
         }
     }
    printf("%s\n", str);

    fclose(inputFile);
    return 0;
}

【讨论】:

  • 我给你很多道具。此代码可以正常运行并运行。但是,即使使用 printf("%s\n", str); 也不会打印任何内容。在末尾。为什么?
  • 我在帖子里说过,不知道能不能用,而且我真的怀疑输入文件丢失或类似的东西,在出口点添加printf()错误检查已完成,您将知道发生了什么。
【解决方案3】:

我认为您代码中的主要问题是您在使用 ix 之前没有初始化它们。

换行

  for(i>0;i<len;++i){

  for(i=0;i<len;++i){
  //  ^^^ i = 0; not i > 0;

并替换该行

     for(x>0;x<len2;++x){

     for(x=0;x<len2;++x){
     //  ^^^ x = 0; not x > 0;

您可以在函数开始时清理代码。中使用的逻辑

 if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
 &&((keyFile=fopen(argc[3],"r"))==NULL)){

 printf("Could Not Open file %s\n", argc[2]);
 exit(1);

 }//End First IF statement

在许多帐户上都是错误的。将其替换为更具可读性的代码:

if ( strcmp(argv[1], "e") == 0 )
{
   if ( (finp = fopen(argc[2],"r")) == NULL )
   {
      printf("Could Not Open file %s\n", argc[2]);
      exit(1);
   }

   if ( (keyFile = fopen(argc[3],"r")) == NULL )
   {
      printf("Could Not Open file %s\n", argc[3]);
      exit(1);
   }
}
else
{
   // Decide what you want to do when the first argument is not "e".
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 2016-02-25
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 2016-03-13
    相关资源
    最近更新 更多