#include <stdio.h>
int main()
{
int n=0;
int a[n], i;
int multi_array[n][3];
FILE *point = fopen("example.txt", "r");
fscanf(point,"%d" , &n);
printf("This is n: %d " , n);
for(i = 0; i < n; i++)
{
fscanf( point , "%d," , &multi_array[n][3]);
}
for(i = 0; i < n; i++)
{
printf("%d\n" , multi_array[n][3]);
}
}
&#34; example.txt&#34;文件具有如下代码:
3
1,10,0
2,1,2
3,2,6
第一个数字确定数组(n)的数量,并且底部三行数字将存储到那些数组中,例如:1,10,0应存储在第一个数组中,2,1,2存储在第二个数组中等等。
我上面的代码给了我一个分段错误错误。
答案 0 :(得分:0)
由于您事先并不知道您的数组需要多少行,因此您无法在堆栈中声明它(即。int a[n]
和int multi_array[n][3]
不会工作)。更改n的值时,C不会为您调整数组大小;你已经将它们声明为0并且它们保持这种状态,这就是为什么当你试图取消引用它们时你得到SEGV的原因。
如果切换到calloc()并声明为int *multi_array[3]
,事情应该更适合你。
你的printf()和fscanf()中也有一个错误,你只能解除引用数组中的最后一个元素,而不是全部三个元素。你有一个进一步的错误,你实际上解除了一个超出结尾的元素,因为3个元素的数组包含元素[0],[1]和[2]。
答案 1 :(得分:0)
这一行:
fscanf( point , "%d," , &multi_array[n][3]);
应该是:
if( 3 != fscanf( point, :"%d,%d,%d",
&multi_array[i][0],
&multi_array[i][1],
&multi_array[i][2] ) )
{ // then fscanf failed
fprintf( stderr, "failed to read all 3 integers on data line: %d\n". i);
exit( EXIT_FAILURE );
}
// implied else, fscanf successful
同样,在调用fopen()
时,始终检查(!= NULL)返回的值以确保操作成功。类似于:
FILE *point = fopen("example.txt", "r");
if( !point )
{
perror( "fopen to read 'example.txt' failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
当数组的大小由读入的值而不是硬编码值确定时,将所有使用该大小的语句放置在读取大小的点之后声明一个数组。这样编译器就可以生成用于分配所需大小的代码。注意:此类数组称为VLAs
(可变长度数组)
为避免编译器警告有关未使用的变量(并节省堆栈空间),请始终删除未使用的数组,I.E。删除这一行:
int a[n],
最佳做法是将数据定义保持在使用这些数据定义的位置。
代码应该自行清理。期望操作系统在草率代码之后进行清理是不好的编程习惯。
'魔术'数字使代码更难以理解,调试等。发布的代码包含幻数“3”。最好是“魔术”数字被赋予有意义的名称以及整个代码中使用的有意义的名称。这通常由#define
语句或enum
语句完成。
当系统函数指示发生错误时,则全局变量'errno'设置为适当的值。 'errno'应该用于显示相关文本。有两种方法可以做到这一点:
perror( "your error message" );
和
#include <errno.h>
...
fprintf( stderr, "the call to xxx returned the following error: %s\n", strerror( errno ) );
以下代码演示了以上所有内容:
#include <stdio.h> // fscanf(), perror(), printf(), fprintf(), stderr, fclose(), fopen()
#include <stdlib.h> // exit(), EXIT_FAILURE
#define NUM_DATA_PER_LINE 3
int main( void )
{
int n;
FILE *point = fopen("example.txt", "r");
if( !point )
{
perror( "fopen to read 'example.txt' failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
if( 1 != fscanf(point,"%d" , &n) )
{
fprintf( stderr, "fscanf failed to read the count of data lines" );
fclose( point );
exit( EXIT_FAILURE );
}
// implied else, fscanf successful
printf("This is n: %d " , n);
int multi_array[n][ NUM_DATA_PER_LINE ];
for(int i = 0; i < n; i++)
{
if( NUM_DATA_PER_LINE != fscanf( point , "%d,%d,%d",
&multi_array[i][0],
&multi_array[i][1],
&multi_array[i][2]) )
{
fprintf( stderr, "fscanf failed to read 3 items from data line: %d\n", i );
fclose( point );
exit( EXIT_FAILURE );
}
// implied else, fscanf successful
}
fclose( point );
for( int i = 0; i < n; i++ )
{
for( int j=0; j < NUM_DATA_PER_LINE; j++ )
{
printf( "%d\n" , multi_array[i][j] );
}
}
}