fprintf分段错误 - 解释就像我5

时间:2014-03-07 17:30:30

标签: c segmentation-fault printf

我正在尝试将一些字符串写入文件。编译时没有任何警告,但是当我运行a.out时会出现段错误。但它会创建目标文件。我是C的新手,所以我为我的格式和其他缺点道歉。这是我的代码:

#include<stdio.h>

int main (void)
{
    FILE *fp_out;

    char str1[]="four score and seven years ago our";
    char str2[]="fathers broughy forth on this continent,";
    char str3[]="a new nation, concieved in Liberty and dedicated";
    char str4[]="to the proposition that all men are created equal.";

    fp_out=fopen("my_file", "w");

    if(fp_out!=NULL)
    {
        fprintf(fp_out,"%s\n", str1[100]);
        fprintf(fp_out,"%s\n", str2[100]);
        fprintf(fp_out,"%s\n", str3[100]);
        fprintf(fp_out,"%s\n", str4[100]);
        fclose(fp_out);
    }
    else
        printf("The file \"my_file\" couldn't be opened\n");

    return 0;
}

4 个答案:

答案 0 :(得分:5)

您应该阅读fprintf()上的手册。

int fprintf(FILE *stream, const char *format, ...);

在您使用%s的格式字符串中,这意味着您将传递fprintf()一串字符。

这是一串字符:

char str1[]="four score and seven years ago our";

这是打印字符串的方式:

fprintf(fp_out,"%s\n", str1);

你在这里想做什么:

fprintf(fp_out,"%s\n", str1[100]);

打印str1的101 st 字符,它不会那么长,所以你试图访问超出你的阵列所拥有的内存...更不用说你将一个字符传递给一个格式字符串,期望一个字符串产生UB。

答案 1 :(得分:3)

您只需将指针传递给数组

if(fp_out!=NULL)
{
    fprintf(fp_out,"%s\n", str1);
    fprintf(fp_out,"%s\n", str2);
    fprintf(fp_out,"%s\n", str3);
    fprintf(fp_out,"%s\n", str4);
    fclose(fp_out);
}

在你的代码中,'str1 [100]'表示从str1中获取第100个字符。这将是0到255范围内的单个字符。您的格式字符串是'%s',这意味着'我将向您传递指向字符串的指针'。你传递了一个字符(实际上只是一个数字),所以你有效地给了一个指针&lt; 255 - 这是一个非法地址,因此是seg错误。

在正确的代码中,'str1'是指向字符串的指针,因此有效。在您的示例中,str1没有任何接近100个字符的位置,因此结果可能是任何内容(包括其他seg错误)。

记住:C经常(特别是printf)并不关心你传递的是什么。如果你错了......麻烦。

哦......而且......当我说100时,它们从0开始编号(所以它真的是101)

答案 2 :(得分:1)

str1[100]您没有任何角色。使用指向以null结尾的字符串的字符指针。

    char *str1 ="four score and seven years ago our";
    char *str2 ="fathers broughy forth on this continent,";
    char *str3 ="a new nation, concieved in Liberty and dedicated";
    char *str4 ="to the proposition that all men are created equal.";

    if(fp_out!=NULL)
    {
        fprintf(fp_out,"%s\n", str1);
        fprintf(fp_out,"%s\n", str2);
        fprintf(fp_out,"%s\n", str3);
        fprintf(fp_out,"%s\n", str4);
        fclose(fp_out);
    }

答案 3 :(得分:1)

分段错误是当您尝试访问无权访问的内存时生成的错误。在您的代码中,您将str1 [100]传递给printf以获取%s说明符。 %s说明符需要char *(字符指针)。 str1 [100]本质上是垃圾,因为它在你声明的字符串之外。访问str1 [100]可能不会产生分段错误,但可能会产生分段错误,具体取决于堆栈中最终指向的位置。但是printf接受了你给它的垃圾,并尝试将其解除引用作为字符指针,从而导致分段错误。更正后的代码如下。

#include<stdio.h>

int main (void)
{
    FILE *fp_out;

    char str1[]="four score and seven years ago our";
    char str2[]="fathers broughy forth on this continent,";
    char str3[]="a new nation, concieved in Liberty and dedicated";
    char str4[]="to the proposition that all men are created equal.";

    fp_out=fopen("my_file", "w");

    if(fp_out!=NULL)
    {
        fprintf(fp_out,"%s\n", str1);
        fprintf(fp_out,"%s\n", str2);
        fprintf(fp_out,"%s\n", str3);
        fprintf(fp_out,"%s\n", str4);
        fclose(fp_out);
    }
    else
        printf("The file \"my_file\" couldn't be opened\n");

    return 0;
}