Ошибка в текстовом редакторе - PullRequest
0 голосов
/ 30 июля 2011

Я пытаюсь создать простую программу текстового редактора на C, но у меня есть эта странная ошибка. Когда я получаю первый пользовательский запрос, программа вылетает. Вот мой код:

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

Я знаю, что это грязно, со всеми gotos и переключением с массива char на указатель на char, но, пожалуйста, попробуйте помочь.

Ответы [ 5 ]

4 голосов
/ 30 июля 2011

Первая проблема, которую я вижу, это сравнение строк:

firstchoice=="~N~"

должно быть

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

Вы сравнили значение указателей вместо строк, поэтому все сравнение не удалось, и программа просто попала в предложение return.

Относительно ошибки сегментации после:

  1. Вы открываете новый файл, filenew = fopen(filenamenew,"r");, и, если файл не существует, (if(!filenew)), вы пытаетесь записать в него (fprintf(filenew,"%s",textwrite);). Сначала нужно открыть его для записи.

  2. Вы вызываете scanf("%s",textwrite);, когда textwrite является неинициализированным указателем и указывает на отсутствие буфера, это должен быть либо массив, либо указатель на выделенную память (например, malloc). Эта ошибка существует со следующими переменными в вашем коде:

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

После того, как вы пройдете это, я думаю, что большинство проблем останется позади.

2 голосов
/ 30 июля 2011
  • Вы сравниваете строки C с strcmp, которые возвращают -1, 0 или 1 (0 означает, что они равны). Существует также stricmp, который делает сравнение без учета регистра.
  • Scanf ожидает указатели на элементы, а имя массива уже является указателем, поэтому не используйте &.
  • Чтобы проверить, существует ли файл: C проверить, существует ли файл
  • Попробуйте реструктурировать ваш код, чтобы он состоял из простых функций. Трудно читать и поддерживать монолитный код.
  • Включить показ предупреждений (проверьте используемый вами компилятор). Ваш код должен компилироваться без предупреждений.
1 голос
/ 30 июля 2011
char *textwrite;    
 ...
scanf("%s",textwrite);

Вы никогда не выделяли память для textwrite.Вы должны попробовать что-то вроде

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

Я не знаю, действительно ли это ваша проблема (пока).

0 голосов
/ 30 июля 2011

scanf ожидает указатель на массив символов, вы передаете ему указатель на указатель на массив символов

scanf("%s",&firstchoice);

Приведенная выше строка должна быть

scanf("%s",firstchoice);

или

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

Кроме того, вы не можете просто сравнить массив символов со строковым литералом, используя ==, вы должны использовать strcmp.

Компиляция вашего кода вызвала следующие предупреждения. Я предлагаю вам начать обращать на них внимание; увеличьте уровень предупреждений вашего компилятора, если вы их не видите.

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
0 голосов
/ 30 июля 2011

Чтобы остановить ваш сбой, не передавайте указатель для firstchoice, передавайте сами переменные.

scanf("%s",firstchoice);

Для массивов вам не нужно брать указатель на функциюкак scanf.Вы делаете это и со своим другим scanf.

Есть несколько проблем с кодом, которые я не буду вдаваться в подробности, потому что, очевидно, это учебное упражнение для вас.Первый, хотя, избавиться от goto.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...