0

I am trying to make a simple text editor program in C, yet I have this weird bug. When I get to the first user prompt, the program crashes. Here is my code:

#include <stdio.h>

int main()
{   
FILE *filenew;
char firstchoice[200];
char filenamenew[200];
char overwrite;
char *textwrite;
char *filenameopen;
FILE *fileopen;
char readchar;
char *textopen;

    start:
puts("Welcome to the Texter Text Editor!");
printf("\n");
printf("\n");
puts("Type ~N~ to create a new document,");
puts("Type ~O~ to open an existing document,");
puts("And type ~Q~ to quit.");
scanf("%s",&firstchoice);
if(firstchoice=="~N~" || firstchoice=="~n~")
{
    puts("Enter the filename of the new document:");
    scanf("%s",&filenamenew);
    filenew = fopen(filenamenew,"r");
    if(filenew)
    {
        fclose(filenew);
        printf("%s already exists!\nDo you wish to overwrite it? [Y/N]",filenamenew);
        overwrite=getchar();
        if(overwrite=='y' || overwrite=='Y')
        {
            filenew=fopen(filenamenew,"w");
            goto textnew;
        }
        else if(overwrite=='N' || overwrite=='n')
        {
            goto start;
        }
    }

textnew:
    if(!filenew)
    {
    do
    {
        scanf("%s",textwrite);
        fprintf(filenew,"%s",textwrite);

    }
    while(textwrite!="~Q~" && textwrite!="~q~");
    }

}
else if(firstchoice=="~q~" || firstchoice=="~Q~")
{
    return(0);
}
else if (firstchoice=="~o~" || firstchoice=="~O~")
{
    printf("Enter the filename of the document you want to open:\n"); 
        scanf("%s",filenameopen);
    fileopen=fopen(filenameopen,"r+");
    if(!fileopen)
    {
        puts("File does not exist!");
        goto start;
    }
    else
    {
        do
        {
        readchar=getc(fileopen);
        putchar(readchar);
        }
        while(readchar!=EOF);
        do
        {
            scanf("%s",textopen);
            fprintf(fileopen,"%s",textopen);
        }while(textopen!="~Q~" && textopen!="~q~");
    }



}
return(0);
}

I know that it's messy, with all of the gotos and switching from char array to char pointer, but please try to help.

Bart
  • 19,692
  • 7
  • 68
  • 77
smilinggoomba
  • 91
  • 1
  • 2
  • 11
  • 1
    take your time and try to reformat and restructure your code. not for us, but for yourself. if pays off. – fazo Jul 30 '11 at 12:24

5 Answers5

4

The first problem I can see is string comparison:

firstchoice=="~N~"

should be

strcmp(firstchoice, "~N~") == 0

You compared the value of the pointers instead of the strings, so all comparison failed and program just got to the return clause.

Regarding the segmentation fault after:

  1. You open a new file, filenew = fopen(filenamenew,"r");, and if the file does not exist, (if(!filenew)), you try to write to it (fprintf(filenew,"%s",textwrite);). You need to open it for writing first.

  2. You call scanf("%s",textwrite); when textwrite is an uninitialized pointer and it points to no buffer, it should be either an array, or pointer to allocated memory (by malloc for example). This mistake exists with the following variables in you code:

    • char *textwrite;
    • char *filenameopen;
    • char readchar;
    • char *textopen;

After you pass that, I think most of the issues will be left behind.

MByD
  • 135,866
  • 28
  • 264
  • 277
  • This is definitely a big problem but shouldn't crash the program. – Starkey Jul 30 '11 at 12:27
  • I don't think the program crashes. I think it just quit unexpectedly, but I might be wrong. – MByD Jul 30 '11 at 12:29
  • 1
    @MByD Nope, it will most likely crash at the scanf line before it ever gets to the string comparison line. – Praetorian Jul 30 '11 at 12:31
  • @Praetorian - I have tested this code just to confirm. it is not the scanf (though there are segfaults later...) – MByD Jul 30 '11 at 12:36
  • By crashes I meant that the program randomly quits. That is all cleared up now (thanks MByD and yi_H), but trying to open a file crashes the program. – smilinggoomba Jul 30 '11 at 12:41
2
  • You compare C strings with strcmp which return -1, 0 or 1 (0 meaning the are equal). There is also stricmp which does case insensitive comparison.
  • Scanf expect pointers to the elements and the name of an array is already a pointer, so don't use &.
  • To check whether a file exists: C check if file exists
  • Try to restructure your code so it's composed of simple functions. It's hard to read and maintain monolithic code.
  • Turn on showing warnings (check the compiler you are using). Your code should compile without warnings.
Community
  • 1
  • 1
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
1
char *textwrite;    
 ...
scanf("%s",textwrite);

You never allocated memory for textwrite. You should try something like

textwrite = malloc(sizeof(char) * 128);
scanf("127%s" , textwrite);

I don't know if this is really your problem (yet).

0

To stop your crash, don't pass in the pointer for firstchoice, pass in the variables itself.

scanf("%s",firstchoice);

For arrays, you don't need to take the pointer for a function like scanf. You do this with your other scanf as well.

There are several problems with the code which I won't go into detail because obviously this is a learning exercise for you. First one though, get rid of the goto.

Starkey
  • 9,673
  • 6
  • 31
  • 51
  • @MByD I don't think you are correct with this statement. The warning that Praetorian posts proves otherwise. – Starkey Jul 30 '11 at 12:29
  • It was weired the firs time I heard, but why don't you try it? – MByD Jul 30 '11 at 12:38
  • @MByD There is a difference, `firstchoice` is a pointer to the first element of the array, `&firstchoice` is a pointer to the whole array. Try printing out the pointer values of `firstchoice + 1` and `&firstchoice + 1`. It only works because your `scanf` implementation must cast its input explicitly to a `char *` before advancing the pointer. – Praetorian Jul 30 '11 at 12:47
  • There is no difference since (any) function call will decrease this parameter from array to pointer anyway. – MByD Jul 30 '11 at 12:50
0

scanf expects a pointer to a char array, you're passing it a pointer to a pointer to a char array

scanf("%s",&firstchoice);

The above line needs to be

scanf("%s",firstchoice);

or

scanf("%s",&firstchoice[0]);

Also, you can't simply compare a char array to a string literal using ==, you must use strcmp.

Compiling your code produced the following warnings. I suggest you start paying attention to them; turn up your compiler's warning level if you're not seeing them.

prog.c: In function ‘main’:
prog.c:22: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[200]’
prog.c:23: warning: comparison with string literal results in unspecified behavior
prog.c:23: warning: comparison with string literal results in unspecified behavior
prog.c:26: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[200]’
prog.c:53: warning: comparison with string literal results in unspecified behavior
prog.c:53: warning: comparison with string literal results in unspecified behavior
prog.c:57: warning: comparison with string literal results in unspecified behavior
prog.c:57: warning: comparison with string literal results in unspecified behavior
prog.c:61: warning: comparison with string literal results in unspecified behavior
prog.c:61: warning: comparison with string literal results in unspecified behavior
prog.c:83: warning: comparison with string literal results in unspecified behavior
prog.c:83: warning: comparison with string literal results in unspecified behavior
prog.c:22: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c:26: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c:49: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c:64: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c:81: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result
prog.c:49: warning: ‘textwrite’ may be used uninitialized in this function
prog.c:64: warning: ‘filenameopen’ may be used uninitialized in this function
prog.c:81: warning: ‘textopen’ may be used uninitialized in this function
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • The compilation warnings have no real meaning in this case, when you work with arrays then the array and the pointer to array are the same. – MByD Jul 30 '11 at 12:34