我的目标是根据输入收集输入和打开文件。
FILE*
open_input_file (char* fileName) //opens source file to be read
{
return fopen(fileName, "r");
}
在早期的函数中,我收集用户的输入并将其保存到fileName。当我调试程序时,它告诉我fopen返回NULL。这不是我想要的,我不确定问题出在哪里。
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName); // infileName is an output parameter for this
inFile = open_input_file(infileName);
}
我不知道问题是什么。有什么想法吗?
答案 0 :(得分:2)
您是否检查过硬盘驱动器指向的文件是否存在?
检查调试器中infileName的值,或者使用printf语句在屏幕上显示值。 printf(“'%s'\ n”,infileName);
您是否在open_input_file()调用内的文件上调用了fclose()。也许该文件仍然被锁定?
编辑:我刚检查了代码。我修改了你的english_to_morse()函数。 1. while 语句比 更容易理解。 2. fgetc()返回一个int而不是一个char。
在初始化的顶部,我添加了这个。这会使用和未定义的字符串“。??。”初始化数组中的每个字符串。这样可以更容易地找到奇怪的错误,因为数组中的所有内容都至少已初始化。
我修改了代码的不同部分,但您应该能够遵循。
initialize_morse_alphanum (char morseStrings[91][6])
{
for (int i=0;i<91;i++)
strcpy(morseStrings[i], ".??.");
....
....
void
english_to_morse(FILE* inputFile, FILE* outputFile, char morseStrings[91][6])
{ int convert;
convert = fgetc(inputFile);
while (convert != EOF)
{
fputs(morseStrings[convert], outputFile);
fputc(' ', outputFile);
printf ("%s ", morseStrings[convert]);
convert = fgetc(inputFile);
}
}
open_output_file (char* fileName) //opens destination file to be written
{ FILE* handle = NULL;
handle = fopen (fileName, "w"); <---- Remove the * from filename
return handle; }
另外,正如在不同的答案中所提到的,将一些边界检查添加到代码的不同区域会很好。目前它很容易崩溃。如果我的输入文件包含小写的'a'(ascii 96),则程序将访问超出范围的内存。所以你应该在某处添加一行if(convert&gt; ='0'&amp;&amp; convert&lt; ='Z')。我会让你解决这个问题。
答案 1 :(得分:2)
如果fopen
returns NULL
,则打开失败。 errno
将保留failure code,strerror(errno)
将返回开放失败原因的简短说明。
#include <errno.h>
#include <string.h>
...
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName); // infileName is an output parameter for this
if (!(inFile = open_input_file(infileName))) {
fprintf(stderr, "Error opening '%s': %s\n",
infileName, strerror(errno));
} else {
// open successful
...
}
}
gather_input
更好地确保infileName
以空值终止以防止缓冲区溢出。最简单的方法是将文件名缓冲区的大小定义为宏,并将最后一个字符设置为0.
#define FILENAMELEN 32
void gather_input(char infileName[]) {
...
infileName[FILENAMELEN-1]=0;
}
int main(void)
{ FILE* inFile = NULL;
char infileName[FILENAMELEN] = {'\0'};
这不是很灵活。您可以将文件名缓冲区的大小传递给gather_input
。
#define LENGTH(a) (sizeof(a) / sizeof(a[0]))
void gather_input(char infileName[], size_t len) {
...
infileName[len-1]=0;
}
int main(void)
{ FILE* inFile = NULL;
char infileName[32] = {'\0'};
gather_input(infileName, LENGTH(infileName)); // infileName is an output parameter for this
如果使用标准字符串操作函数,设置最后一个字符的替代方法是使用strl*
函数(strlcpy
and strlcat
)而不是它们的无界兄弟。如果您未使用strl*
,则应使用strncpy
和strncat
。
答案 2 :(得分:0)
确保gather_input
正常运行。这可能是一个问题,因为你正在尝试阅读你正在写的文件?在这种情况下,尝试关闭并再次打开流。