three six
three six

Reputation: 23

fprintf segmentation fault - explain like I'm 5

I'm trying to write some strings into a file. This compiles with no warnings, but when I run the a.out it segfaults. It does create the target file, though. I'm very new to C, so I apologize for my formatting and other shortcomings. Here is my code:

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

Upvotes: 2

Views: 18790

Answers (4)

Rob
Rob

Reputation: 3381

You just pass a pointer to the array

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

In your code, 'str1[100]' means fetch me the 100th character from str1. That is going to be a single character in the range 0 to 255. Your format string is '%s' which means 'I am going to pass you a pointer to a string'. You passed a character (which is just a number really) so you effectively gave a pointer <255 - which is an illegal address hence the seg fault.

In the correct code 'str1' is a pointer to a string and so works. In your example str1 doesn't have anywhere near 100 characters and so the result could be anything (including an additional seg fault).

Remember: C quite often (and printf in particular) doesn't care what you pass it. If you are wrong... trouble.

oh...and... when I say 100th, they are numbered from 0 (so it is really 101st)

Upvotes: 3

grubs
grubs

Reputation: 181

A segmentation fault is an error generated when you attempt to access memory that you don't have permission to access. In your code you are passing str1[100] to printf for a %s specifier. The %s specifier expects a char* (character pointer). str1[100] is essentially garbage, since it is outside of the string that you declared. Accessing str1[100] probably doesn't generate the segmentation fault, though it could, depending on where in the stack that ends up pointing. But printf takes that garbage that you gave it and tries to dereference it as a character pointer which results in the segmentation fault. The corrected code is below.

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

Upvotes: 2

Mike
Mike

Reputation: 49523

You should read the manual on fprintf().

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

In your format string you're using %s, that means you're going to pass fprintf() a string of characters.

This is a string of characters:

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

This is how you print a string of characters:

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

What you're trying to do here:

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

is print the 101st character of str1, it's not nearly that long, so you're trying to access memory way beyond what your array owns... not to mention that you're passing a character to a format string expecting a string resulting in UB.

Upvotes: 10

Arjun Sreedharan
Arjun Sreedharan

Reputation: 11453

You don't have any character at str1[100]. Use character pointer that points to a null-terminated string.

    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.";

and

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

Upvotes: 1

Related Questions