从两个输入文件读取字符时如何修复 'Segmentation Fault(core dumped)' 错误?
How to fix 'Segmentation Fault(core dumped)' error when reading characters from two input files?
我正在编写加密程序,但由于错误而停止:'Segmentation Fault(Core Dumped)'。下面的程序假设从两个输入文件打印:
第一个输入文件:应读入,然后将大写字符更改为小写字符,将小写字符更改为大写字符。
第二个输入文件:应该被读入并且只打印用户想要的字符在文件中出现的次数。在这种情况下,我想要的用户想要的字符是字母 'a'.
假设第一个输入文件 (input.txt) 包含:
你好,我叫乔
这应该打印为:你好,我的名字是 jOE
假设第二个输入文件 (keys.txt) 包含:
一个
男
这应该只打印字符: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;}
在您的代码中
(argc[1]="e")
应该是
!strcmp(argv[1], "e")
argc[2]
和 argc[3]
的同种错误。
记住,argc
是 int
类型(不是数组)。 argv[]
属于 char *
.
类型
也就是说,在使用 argv[n-1]
.
之前,您应该始终根据 n
检查 argc
值
然后,请记住,仅当第一个操作数产生 TRUE 值时,才会评估 &&
的第二个操作数。你应该检查你在
中使用的逻辑
if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
&&((keyFile=fopen(argc[3],"r"))==NULL))
我认为它没有达到您希望它达到的目的。
此外,正如 @iharob 先生所指出的,您似乎从未初始化任何一个 for
循环中使用的计数器变量。这将导致未定义的行为。
你有很多错误
第一个if
说法,完全错误
argc[1] = "e"
从很多角度来看都是错误的,首先你不能用 ==
运算符压缩字符串,但你没有使用比较运算符,它是赋值运算符,你不能分配给数组,所以这是双重错误。
- 您使用了
&&
运算符来检查两个文件是否同时位于 NULL
,如果只有一个文件是,则结果为 false,从而使后面的代码调用未定义的行为,可能导致 SEGMENTATION FAULT.
你永远不会检查程序是否使用正确数量的参数调用,但你仍然访问 argc
数组,顺便说一下,它通常是 argv
,argc
用于参数数量,即您使用 args
的位置,但这实际上并不重要。
你的for
循环也是错误的
for (i > 0 ... )
你永远不会初始化i
,还有一点关于字符串在c中是如何工作的知识,会让c程序员写出下面的循环来遍历字符串
for (i = 0 ; ((str[i] != '\n') && (str[i] != '[=11=]')) ; ++i)
因为 fgets()
将读取通过按 Return/Enter 键插入的尾随 '\n'
并因此刷新标准输入,您需要检查反对 str[i] == '\n'
但如果你是偏执狂,你也应该检查 '[=27=]'
我是偏执狂,我确实检查过,虽然这很低效,但我更愿意这样做,而不是以后看到意想不到的事情。
这是您的程序示例,没有错误,我不知道它是否符合您的要求,但它是同一个程序,只是有可能导致 SEGMENTATION FAULT[=53= 的错误]更正
#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] != '[=12=]')) ; ++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] != '[=12=]')) ; ++i)
{
if (str2[i] == 'A')
putchar(str2[i]);
}
}
printf("%s\n", str);
fclose(inputFile);
return 0;
}
我认为您代码中的主要问题是您在使用 i
和 x
之前没有初始化它们。
替换行
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".
}
我正在编写加密程序,但由于错误而停止:'Segmentation Fault(Core Dumped)'。下面的程序假设从两个输入文件打印:
第一个输入文件:应读入,然后将大写字符更改为小写字符,将小写字符更改为大写字符。
第二个输入文件:应该被读入并且只打印用户想要的字符在文件中出现的次数。在这种情况下,我想要的用户想要的字符是字母 'a'.
假设第一个输入文件 (input.txt) 包含: 你好,我叫乔
这应该打印为:你好,我的名字是 jOE
假设第二个输入文件 (keys.txt) 包含:
一个
男
这应该只打印字符: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;}
在您的代码中
(argc[1]="e")
应该是
!strcmp(argv[1], "e")
argc[2]
和 argc[3]
的同种错误。
记住,argc
是 int
类型(不是数组)。 argv[]
属于 char *
.
也就是说,在使用 argv[n-1]
.
n
检查 argc
值
然后,请记住,仅当第一个操作数产生 TRUE 值时,才会评估 &&
的第二个操作数。你应该检查你在
if((argc[1]="e")&&((finp = fopen(argc[2],"r"))==NULL)
&&((keyFile=fopen(argc[3],"r"))==NULL))
我认为它没有达到您希望它达到的目的。
此外,正如 @iharob 先生所指出的,您似乎从未初始化任何一个 for
循环中使用的计数器变量。这将导致未定义的行为。
你有很多错误
第一个
if
说法,完全错误argc[1] = "e"
从很多角度来看都是错误的,首先你不能用==
运算符压缩字符串,但你没有使用比较运算符,它是赋值运算符,你不能分配给数组,所以这是双重错误。- 您使用了
&&
运算符来检查两个文件是否同时位于NULL
,如果只有一个文件是,则结果为 false,从而使后面的代码调用未定义的行为,可能导致 SEGMENTATION FAULT.
你永远不会检查程序是否使用正确数量的参数调用,但你仍然访问
argc
数组,顺便说一下,它通常是argv
,argc
用于参数数量,即您使用args
的位置,但这实际上并不重要。你的
for
循环也是错误的for (i > 0 ... )
你永远不会初始化
i
,还有一点关于字符串在c中是如何工作的知识,会让c程序员写出下面的循环来遍历字符串for (i = 0 ; ((str[i] != '\n') && (str[i] != '[=11=]')) ; ++i)
因为
fgets()
将读取通过按 Return/Enter 键插入的尾随'\n'
并因此刷新标准输入,您需要检查反对str[i] == '\n'
但如果你是偏执狂,你也应该检查'[=27=]'
我是偏执狂,我确实检查过,虽然这很低效,但我更愿意这样做,而不是以后看到意想不到的事情。
这是您的程序示例,没有错误,我不知道它是否符合您的要求,但它是同一个程序,只是有可能导致 SEGMENTATION FAULT[=53= 的错误]更正
#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] != '[=12=]')) ; ++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] != '[=12=]')) ; ++i)
{
if (str2[i] == 'A')
putchar(str2[i]);
}
}
printf("%s\n", str);
fclose(inputFile);
return 0;
}
我认为您代码中的主要问题是您在使用 i
和 x
之前没有初始化它们。
替换行
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".
}