从.txt文件中读取并将其保存在数组中。使用fscanf进行故障排除

时间:2014-10-27 08:08:31

标签: c file-io segmentation-fault eof scanf

我希望从包含英语句子的.txt文件中读取并将它们存储到字符数组中。每个角色都有。我试过但是得到了分段错误:11。我在使用fscanf和从C中读取文件时遇到了麻烦。

#include<stdio.h>
#include<math.h>
#include<limits.h>
int main()
{
    FILE* fp = fopen("file1.txt","r");
    char c , A[INT_MAX];
    int x;
    while(1)
    {
      fscanf("fp,%c",&c);
      if(c == EOF)
       {break;}
      A[x] = c;
      x++; 
    }
    int i;
    for (i=0;i<x;i++)
     printf("%c",A[i]);
return 0;
}

2 个答案:

答案 0 :(得分:1)

问题1:将数组放入堆栈A[INT_MAX]是不好的做法;它在堆栈上分配了一个不合理的空间(并且会在INT_MAX相对于内存大小的机器上崩溃)。获取文件大小,然后获取malloc空间。

fseek(fp, SEEK_END);
long size = ftell(fp);
rewind(fp);
char *A = malloc((size_t) size); // assumes size_t and long are the same size
if (A == NULL) {
  // handle error
}

问题2:fscanf错了。如果您坚持使用fscanf(这不是阅读整个文件的好方法;请参阅问题4),您应该更改:

fscanf("fp,%c",&c);`

应该是

int count = fscanf(fp, "%c",&c);
if (count <= 0)
  break;

问题3:您的x计数器未初始化。如果您坚持使用fscanf,则需要对其进行初始化:

int x = 0;

问题4:fscanf是读取整个文件的错误方法。假设您已经确定了文件的大小(请参阅问题1),您应该使用fread读取文件,如下所示:

int bytes_read = fread(A, 1, size, fp);
if (bytes_read < size) {
  // something went wrong
}

我最初的答案,以及一个很好的一般规则:

您需要检查返回值,因为c值永远不会是EOF,因为EOF是一个int值,不适合{ {1}}。 (你应该总是检查返回值,即使看起来不应该发生错误,但我没有在上面的代码中一直这样做。)

来自http://www.cplusplus.com/reference/cstdio/fscanf/

返回值

成功时,该函数返回成功填充的参数列表的项数。由于匹配失败,读取错误或文件结束的范围,此计数可以匹配预期的项目数或更少(甚至为零)。

如果在读取时发生读取错误或达到文件结尾,则设置正确的指示符(feof或ferror)。并且,如果在成功读取任何数据之前发生任何一次,则返回EOF。

如果解释宽字符时发生编码错误,则该函数将errno设置为EILSEQ。

答案 1 :(得分:0)

嗨,你应该知道程序应该读取数据。即使您像字符串一样读取行,也可以访问所有字符。

尝试一下

#include<stdio.h>
#include<string.h>
#define INT_MAX 100
int main()
{
 FILE* fp = fopen("file1.txt","r");
 char c , A[INT_MAX];
 int i;
 int x;
 j=0
 while(fscanf(fp,"%s",A[j])!=EOF)
 {
  j++; 
 }
 int i;
 int q;
 for(q=0;q<j;q++)
 { 
  for (i=0;i<strlen(A[q]);i++)
   printf("%c ",A[q][i]);
 printf("\n");
 }
return 0;
}