#include<stdio.h>
#include<string.h>
int main()
{
char temp[4][10],wc[10];
int i=0,j;
FILE *fp;
fp=fopen("ip.txt","r");
fscanf(fp,"%s",wc);
while(strcmp(wc,"\n"))
{
strcpy(temp[i],wc);
fscanf(fp,"%s",wc);
i++;
}
for(j=0;j<i;j++)
{
printf("%s",temp[j]);
}
}
输出:segmentation fault(core dumped)
ip.txt包含:
LOOP ADD AREG,A
SUB B,A
错误在哪里?
答案 0 :(得分:2)
我的朋友们,在看完你的问题之后,我发现你在程序的最后一个循环中错误地将j
写入i
。对于i == 4
,数组temp[]
将继续越过边界,这将导致分段错误。处理的方法是在最后一个循环中用j替换i,strcmp(wc,"\n")
永远不会在第一个循环中变为0,所以temp[]
也会越过边界。说实话,我建议你下次在问题中记下这个愿望。复制wc
也很危险进入指针数组的元素,尤其是在为它们分配空间之前,这也是导致分段错误的原因。
答案 1 :(得分:2)
fscanf(fp,"%s",wc);
%s
将匹配一系列非空白字符,并将该序列存储在wc
。现在,由于\n
是一个空格字符,此调用将忽略它!
所以wc
永远不会等于\n
。
因此,while(strcmp(wc,"\n")
是一个infinie循环,因为strcmp
永远不会返回0
。 (即使到达文件ip.txt
的末尾!)
语句i++
在某些时候会使i
大于4
(数组限制),那就是当您遇到分段错误时。 (尽管你可以避免无限循环!)
其他问题:
fscanf(fp,"%s",wc);
现在,如果非空白字符序列大于9
个字符,该怎么办? fscnaf
会在序列结尾处存储和一个addiotional \0
字节,覆盖缓冲区wc
(大小为10,还记得吗?)
为避免缓冲区溢出,请始终将maximum field width
与%s
一起使用。例如
fscanf(fp,"%9s",wc);
fp=fopen("ip.txt","r");
现在你怎么知道fopen
成功了?在使用fp
进行任何处理之前,请务必检查NULL
是否为fp
,例如
if(fp=fopen("ip.txt","r"))
{
//`fp` code goes here
}
else
printf("fopen failed!\n");
解决方案:
您还没有提到,但如果您的目标是将单词中的单词存储在数组temp
中,请执行处理,然后再将下一行中的单词存储在数组temp
中,然后您就可以了使用fgets()
获取缓冲区中的一行。然后使用sscanf()
从该缓冲区中检索每个单词以将它们存储在temp
数组中。
类似的东西:
char buffer[50], temp[4][10], *buf, *wc;
int i;
while(fgets(buffer, 50, stdin) != NULL)
{
i = 0;
buf = buffer;
while((wc = strtok(buf, " \n")) && (i < 4))
{
strcpy(temp[i++], wc);
if (buf && i)
buf = NULL;
}
// process words here
}