fgets()和strcpy()有问题
我正在写一个C程序,首先打开并读取一个包含50个电影标题的文件,每个标题写在一行上。接下来,我尝试将文件的每一行(或电影标题)分配到名为FilmArray[51]的数组的每个元素中。我正在使用strcpy()执行此操作,但每次程序到达strcpy的第一个循环时都会崩溃,我似乎无法找出哪里出错了fgets()和strcpy()有问题,c,fgets,strcpy,C,Fgets,Strcpy,我正在写一个C程序,首先打开并读取一个包含50个电影标题的文件,每个标题写在一行上。接下来,我尝试将文件的每一行(或电影标题)分配到名为FilmArray[51]的数组的每个元素中。我正在使用strcpy()执行此操作,但每次程序到达strcpy的第一个循环时都会崩溃,我似乎无法找出哪里出错了 int main() { int i=0; char array[51]; char FilmArray[51]; bool answer; FILE *films; films = fopen("fi
int main()
{
int i=0;
char array[51];
char FilmArray[51];
bool answer;
FILE *films;
films = fopen("filmtitles.txt", "r");
if(films == NULL){
printf("\n ************* ERROR *************\n");
printf("\n \"filmtitles.txt\" cannot be opened.\n");
printf("\n PROGRAM TERMINATED\n");
exit(EXIT_FAILURE);
}
while(fgets(array, sizeof array, films) != NULL){
printf("%d. %s",i, array);
strcpy(FilmArray[i], array);
i++;
}
FilmArray
是字符数组,而不是字符串数组
所以当你在做
strcpy(FilmArray[i], array);
编译器将把FilmArray[i]
中的值转换为指针,并将其用作字符串的目标。这将导致严重的后果
事实上,编译器应该为此向您发出警告,如果没有,那么您需要启用更多警告,因为警告是关于编译器认为可疑并可能导致UB的事情的消息。您的代码实际上是在尝试执行整数到指针的转换,将
char
传递到char*
类型的参数。尝试将和与strcpy一起使用:
strcpy(&FilmArray[i], array);
&
为FilmArray[i]
指定指针的使用建议以下代码
suggest the following code
which compiles with no errors/warnings
is complete (given the posted code)
eliminates a lot of the code clutter
eliminates the 'magic' numbers buried in the code
#include<stdio.h>
#include<stdlib.h>
#define MAX_NUM_FILMS (51)
#define MAX_FILM_TITLE_LEN (51)
int main()
{
int i=0;
char FilmArray[ MAX_NUM_FILMS ][ MAX_FILM_TITLE_LEN ] = {{'\0'}};
FILE *films;
films = fopen("filmtitles.txt", "r");
if(films == NULL)
{
printf("\n ************* ERROR *************\n");
printf("\n \"filmtitles.txt\" cannot be opened.\n");
printf("\n PROGRAM TERMINATED\n");
exit(EXIT_FAILURE);
}
// implied else, fopen successful
while(fgets(&FilmArray[i][0], MAX_FILM_TITLE_LEN, films))
{
printf("%d. %s\n",i, FilmArray[i]);
i++;
}
// other code here
fclose( films ); // cleanup
return(0);
} // end function: main
它编译时没有错误/警告
已完成(给定发布的代码)
消除了大量的代码混乱
消除隐藏在代码中的“神奇”数字
#包括
#包括
#定义最大胶片数(51)
#定义最大胶片标题长度(51)
int main()
{
int i=0;
char FilmArray[MAX_NUM_FILMS][MAX_FILM_TITLE_LEN]={{{{0'};
文件*电影;
films=fopen(“filmtitles.txt”,“r”);
如果(胶片==NULL)
{
printf(“\n****************错误***************\n”);
printf(“\n\”filmtitles.txt\”无法打开。\n”);
printf(“\n程序终止\n”);
退出(退出失败);
}
//否则,fopen成功了
而(fgets和FilmArray[i][0],MAX_FILM_TITLE_LEN,films))
{
printf(“%d.%s\n”,i,FilmArray[i]);
i++;
}
//这里还有其他代码
fclose(电影);//清理
返回(0);
}//结束函数:main
您正在使用调试器吗?它在哪里坠毁?有运行时错误吗?char FilmArray[51];。。。strcpy(FilmArray[i],数组)代码>应生成编译器警告。节省时间。启用所有编译器警告。char FilmArray[51]代码>-->char FilmArray[50][51]代码>另一个好主意是区分标题的长度和标题的数量。对于bothas使用50以及其他建议的修复,您感到困惑,#include
和#include
是必需的。如果您使用的是非常旧的编译器,那么应用适当的include会增加您收到类似错误警告的机会;将该值转换为指针是一种可能的做法(但不是很明智,我不清楚编译器供应商为什么认为这是一个好主意)。在C89中,它是UB,不需要诊断(也不需要转换)。如果读取太多(缓冲区溢出),它将从FilmArray
末尾运行。虽然这很可能只是一个编码练习,但如果定义了最大值以避免此类问题行为,我建议实际使用最大值<代码>而(例如,i
。