尝试扫描字符串时程序崩溃

时间:2015-10-07 07:10:16

标签: c

我无法从包含任意游戏结果的.dat文件中扫描数据(用于测试程序)

结果格式如下:(#表示分数为整数)

team_a#team_b# team_a#team_b# team_a#team_b# 。 。 。 team_a#team_b#

每一行都是不同的游戏。

我目前正在尝试使用fgets()函数来扫描每个游戏/行,然后使用sscanf_s()函数从每一行获取数据(看起来好像我知道它的格式化方式并将其存储到我定义的数据结构中。

如果有更简单,更快速和/或更可靠(万无一失)的方法,我非常乐意接受有关我将如何将数据导入结构的方式所做的更改建议

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

Microsoft's secure sscanf_s解释格式说明符和参数的方式略有不同:为了防止缓冲区溢出,每种字符串格式(%s%c%[)都必须在缓冲区后传递相应的缓冲区大小。

所以你的扫描命令应为:

    sscanf_s(data_file_line[i],
        "%s %d %s %d",
        game_results[i].first_team_name,
        sizeof(game_results[i].first_team_name),
        &game_results[i].first_team_score,
        game_results[i].second_team_name,
        sizeof(game_results[i].second_team_name),
        &game_results[i].second_team_score);

您的代码还存在其他一些问题:

  • 您应该检查sscanf_s的返回值,以便知道该行已成功解析。返回值是转换的项目数,因此在您的情况下应该是4.还要注意%s扫描单词和团队名称,如" Man Utd"和斯托克城"有两个单词,不会正确解析。
  • 正如其他人所说,feof结构会让你读取文件太多。忘记foef并使用读取函数的返回值。例如,fgets在到达文件末尾时返回NULL,因此您可以将其用作循环条件:while (fgets(buf, sizeof(buf), f)) ...
  • 您不会检查i是否溢出。如果您有一个长文件,i可能不够大。
  • 如果您正在解析和存储线条,则不需要有一系列线条;只需反复使用一个行缓冲区。

答案 1 :(得分:0)

我简化了一点,它工作正常。你的工作还没完成。请试试这个,

 #include <usual.h>

 #define MAX_NAME_CHARS 15
 #define MAX_DATA_FILE_LINE_LENGTH 32
 #define MAX_GAME_RESULTS 128

 int main( void )
 {
   FILE *inp2b;

   typedef struct game_results
   {
     char first_team_name[MAX_NAME_CHARS];
     int first_team_score;
     char second_team_name[MAX_NAME_CHARS];
     int second_team_score;
   } game_results_t;

   game_results_t game_results[MAX_GAME_RESULTS];
   char data_file_line[MAX_DATA_FILE_LINE_LENGTH][MAX_DATA_FILE_LINE_LENGTH];
   int errorcode = 0;
   int i = 0;

 //errorcode = fopen_s(&inp2b,"C:\\Users\\Cody\\Documents\\Visual Studio 2012\\DATAFILES FOR PA2\\input2b.dat","r");
   inp2b = fopen( "C:\\testdat\\input2b.dat", "r" );

   if ( inp2b == NULL )
     errorcode = 1;

   if ( errorcode != 0 )
   {
     printf( "Error opening 2nd data file!\n\n" );
     return ( 0 );
   }
   else
   {
     printf( "\n\n\nFile was opened successfully!\n\n" );
   }

   i = 0;

   while ( !feof( inp2b ) )
   {
     fgets( data_file_line[i], MAX_DATA_FILE_LINE_LENGTH, inp2b );
     puts( data_file_line[i] );
     printf( "\n" );
     //   sscanf_s(data_file_line[i],"%s %d %s %d",game_results[i].first_team_name,&game_results[i].first_team_score,game_results[i].second_team_name,&game_results[i].second_team_score);
     sscanf( data_file_line[i], "%s %d %s %d", game_results[i].first_team_name,
        &game_results[i].first_team_score,
        game_results[i].second_team_name,
        &game_results[i].second_team_score );

     printf( "\n\n %s %d %s %d \n\n", game_results[i].first_team_name,
        game_results[i].first_team_score,
        game_results[i].second_team_name,
        game_results[i].second_team_score );
     i++;
   }

   fclose( inp2b );

   return ( 0 );
 }