C中文件操作的分段错误

发布于 2024-08-29 07:10:53 字数 1292 浏览 4 评论 0原文

#include<stdio.h>

/* this is a lexer which recognizes constants , variables ,symbols, identifiers , functions , comments and also header files . It stores the lexemes in 3 different files . One file contains all the headers and the comments . Another file will contain all the variables , another will contain all the symbols. */

int main()
{
    int i;
    char a,b[20],c;
    FILE *fp1;

    fp1=fopen("source.txt","r"); //the source file is opened in read only mode which will passed through the lexer

    //now lets remove all the white spaces and store the rest of the words in a file 

    if(fp1==NULL)
    {
        perror("failed to open source.txt");
        //return EXIT_FAILURE;
    }
    i=0;
    while(1)
    {


        a=fgetc(fp1);

        if(a !="")
        {
            b[i]=a;
        }
        else
        {


            fprintf(fp1, "%.20s\n", b);
            i=0;
            continue;
        }
        i=i+1;                  

        /*Switch(a)
        {
            case EOF :return eof;
            case '+':sym=sym+1;

            case '-':sym=sym+1;

            case '*':sym=sym+1;

            case '/':sym=sym+1;

            case '%':sym=sym+1;

            case '
        */
    }
return 0;
}

这段代码怎么会出现分段错误呢?

#include<stdio.h>

/* this is a lexer which recognizes constants , variables ,symbols, identifiers , functions , comments and also header files . It stores the lexemes in 3 different files . One file contains all the headers and the comments . Another file will contain all the variables , another will contain all the symbols. */

int main()
{
    int i;
    char a,b[20],c;
    FILE *fp1;

    fp1=fopen("source.txt","r"); //the source file is opened in read only mode which will passed through the lexer

    //now lets remove all the white spaces and store the rest of the words in a file 

    if(fp1==NULL)
    {
        perror("failed to open source.txt");
        //return EXIT_FAILURE;
    }
    i=0;
    while(1)
    {


        a=fgetc(fp1);

        if(a !="")
        {
            b[i]=a;
        }
        else
        {


            fprintf(fp1, "%.20s\n", b);
            i=0;
            continue;
        }
        i=i+1;                  

        /*Switch(a)
        {
            case EOF :return eof;
            case '+':sym=sym+1;

            case '-':sym=sym+1;

            case '*':sym=sym+1;

            case '/':sym=sym+1;

            case '%':sym=sym+1;

            case '
        */
    }
return 0;
}

how does this code end up in segmentation fault?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

舟遥客 2024-09-05 07:10:53

而且,字符串 b 可能不是以 null 结尾的。在代码中的某个时刻,您需要:

 b[i] = '\0';

And also, the string b is probably not null terminated. At some point in your code you need:

 b[i] = '\0';
孤云独去闲 2024-09-05 07:10:53

看起来需要检查以确保其写入的内容没有超出数组 b 的末尾。如果它读取超过 20 个字符,则会写入超过该字符并损坏堆栈。

It looks like it needs a check to be sure it is not writing beyond the end of array b. If it reads over 20 characters, it will write past it and corrupt the stack.

难得心□动 2024-09-05 07:10:53

没有检查来测试文件结尾

更改

while(1) 

while (!feof(fp1))

编辑:

但是段错误的原因是b末尾缺少NULL字符。您可以在将 b 写入文件之前在其末尾添加 NULL 字符:

b[i] = 0; // i must <=19
fprintf(fp1, "%.20s\n", b);

这样您还需要确保填充的内容不会超过 >19 字符到 b 中,这样您就始终有空间来写入 NULL 字符。

There is no check to test the End of File.

Change

while(1) 

to

while (!feof(fp1))

EDIT:

But the reason for seg-fault is the missing NULL char at the end of b. You can add the NULL char at the end of b just before writing it to the file:

b[i] = 0; // i must <=19
fprintf(fp1, "%.20s\n", b);

This way you also need to ensure that you don't stuff more than 19 char into b that way you always have space to write the NULL char.

病毒体 2024-09-05 07:10:53

段错误??通常无限循环...


使用以下...

#include<stdio.h>

/* this is a lexer which recognizes constants , variables ,symbols, identifiers , functions , comments and also header files . It stores the lexemes in 3 different files . One file contains all the headers and the comments . Another file will contain all the variables , another will contain all the symbols. */

int main()
{
    int i;
    char a,b[20],c;
    FILE *fp1;

    fp1=fopen("source.txt","r"); //the source file is opened in read only mode which will passed through the lexer

    //now lets remove all the white spaces and store the rest of the words in a file 

    if(fp1==NULL)
    {
        perror("failed to open source.txt");
        //return EXIT_FAILURE;
    }
    i=0;
    while(!feof(fp1))
    {


        a=fgetc(fp1);

        if(a !="")
        {
            b[i]=a;
        }
        else
        {

            b[i]='\0';
            fprintf(fp1, "%.20s\n", b);
            i=0;
            continue;
        }
        i=i+1;                  

        /*Switch(a)
        {
            case EOF :return eof;
            case '+':sym=sym+1;

            case '-':sym=sym+1;

            case '*':sym=sym+1;

            case '/':sym=sym+1;

            case '%':sym=sym+1;

            case '
        */
    }
return 0;
}

祝你好运!

CVS @ 2600赫兹

SegFault?? usually INFINITE LOOP...


Use the following...

#include<stdio.h>

/* this is a lexer which recognizes constants , variables ,symbols, identifiers , functions , comments and also header files . It stores the lexemes in 3 different files . One file contains all the headers and the comments . Another file will contain all the variables , another will contain all the symbols. */

int main()
{
    int i;
    char a,b[20],c;
    FILE *fp1;

    fp1=fopen("source.txt","r"); //the source file is opened in read only mode which will passed through the lexer

    //now lets remove all the white spaces and store the rest of the words in a file 

    if(fp1==NULL)
    {
        perror("failed to open source.txt");
        //return EXIT_FAILURE;
    }
    i=0;
    while(!feof(fp1))
    {


        a=fgetc(fp1);

        if(a !="")
        {
            b[i]=a;
        }
        else
        {

            b[i]='\0';
            fprintf(fp1, "%.20s\n", b);
            i=0;
            continue;
        }
        i=i+1;                  

        /*Switch(a)
        {
            case EOF :return eof;
            case '+':sym=sym+1;

            case '-':sym=sym+1;

            case '*':sym=sym+1;

            case '/':sym=sym+1;

            case '%':sym=sym+1;

            case '
        */
    }
return 0;
}

GoodLUCK!!

CVS @ 2600Hertz

疑心病 2024-09-05 07:10:53

像这样使用 while :

...
 while((a=fgetc(fp1))!=EOF)
    {
        if(a !="")
        {
            b[i]=a;
        }
...

您每次都会检查 a 是否与 EOF 不同。如果a等于EOF,则处理将停止。

我会考虑使用 fread() / fgets(),并解析结果字符串,而不是逐个字符读取。我认为这可能会提高解析器的整体性能。

Use your while like this:

...
 while((a=fgetc(fp1))!=EOF)
    {
        if(a !="")
        {
            b[i]=a;
        }
...

You will check every-time if a is different from EOF. If a equals EOF, the processing will stop.

I would consider reading a bigger buffer with fread() / fgets(), and parse the resulting string, instead of reading character by character. I think this may improve the overall performance of your parser.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文