简体   繁体   English

C中字符串复制函数strcpy中的分段错误

[英]Segmentation fault in String copy function strcpy in C

#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]);
    }
}

Output: segmentation fault(core dumped) 输出: segmentation fault(core dumped)

ip.txt contains: ip.txt包含:

LOOP ADD AREG,A
 SUB B,A

Where is the error? 错误在哪里?

My friends, after watching your question, I find that you mistakenly wrote j into i in the final loop of your program. 我的朋友们,在看完您的问题后,发现您在程序的最后循环中将j错误地写入了i For i == 4 , the array temp[] will proceed to cross the border, which will lead to the segmentation fault.The way to deal is to replace i with j in the final loop, and strcmp(wc,"\\n") never become 0 in the first loop, so temp[] will also cross the border.To be honest, I advice you to write down the desire in the question next time.And it is also dangerous to copy wc into the elements of the array of pointers, especially before you allocate space for them, this is also the reason to cause segmentation fault. 对于i == 4 ,数组temp[]将越过边界,这将导致分段错误。处理的方法是在最终循环中将i替换为j,并用strcmp(wc,"\\n")永远不会在第一个循环中变为0,因此temp[]也将越界。老实说,我建议您下次在问题中写下愿望。将wc复制到其中的元素也很危险。指针数组,尤其是在为它们分配空间之前,这也是导致分段错误的原因。

fscanf(fp,"%s",wc);    

%s will match a sequence of non-white-space characters and will store that sequence at wc . %s将匹配非空格字符序列,并将该序列存储在wc Now since \\n is a white-space character this call will ignore it! 现在,由于\\n 空格字符,因此此调用将忽略它!

So wc will never be equal to \\n . 所以wc永远不会等于\\n

Therefore, while(strcmp(wc,"\\n") is an infinie loop as the strcmp will never return 0 . (Even when the end of file ip.txt is reached!) 因此, while(strcmp(wc,"\\n")是无限循环,因为strcmp永远不会返回0 (即使到达文件ip.txt的末尾!)

The statement i++ will at some point make i greater than 4 (array limit) and that's when you get the segmentation fault. i++语句将使i大于4 (数组限制),这就是您遇到分段错误的时候。 (Saves you from an infinite loop though!) (不过可以使您摆脱无限循环!)


Other issues: 其他事宜:

  1. fscanf(fp,"%s",wc);
    Now what if a sequence of non-white-space characters is greater than 9 characters? 现在,如果非空格字符序列大于9字符怎么办? fscnaf will store that sequence and an addiotional \\0 byte at the end of it, overwriting the buffer wc (size is 10, remember?) fscnaf将存储该序列末尾的\\0字节,覆盖缓冲区wc (大小为10,记得吗?)
    To avoid buffer overruns always use maximum field width with %s . 为避免缓冲区溢出,请始终将maximum field width%s eg 例如

     fscanf(fp,"%9s",wc); 
  2. fp=fopen("ip.txt","r");
    Now how do you know that fopen succeded? 现在您怎么知道fopen成功了? Always check whether fp is NULL before doing any processing with fp eg 使用fp进行任何处理之前,请务必先检查fp是否为NULL ,例如

     if(fp=fopen("ip.txt","r")) { //`fp` code goes here } else printf("fopen failed!\\n"); 

Solution: 解:
You haven't mentioned but if your aim is to store the words from just a single line in an array temp , do processing and then again store the words from next line in an array temp then you can use fgets() to fetch a line in a buffer. 您没有提到,但是如果您的目标是将一行中的单词存储在数组temp ,请进行处理,然后再次将下一行中的单词存储在数组temp则可以使用fgets()来获取一行在缓冲区中。 And then using sscanf() to retrieve each word from that buffer to store them in temp array. 然后使用sscanf()从该缓冲区检索每个单词以将它们存储在temp数组中。

Something like: 就像是:

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM