2013-07-03 3 views
0

По какой-то причине fclose(), по-видимому, вызывает ошибку в программе, которую я пишу. Терминал Windows говорит, что «процесс возвратил 255», когда это произойдет. Ниже приведена часть кода:fclose() вызывает сбой в окнах

FILE* output = fopen("random.txt","w"); 
write(c,output); 
//fprintf(output,"shit\n"); 
fclose(output); 

«писать» в основном пишет вещи в выходной файл. Даже при сбое программы данные выводятся в файл. После операции записи я все равно могу записать в выходной файл, и текст будет там, если я это сделаю, но как-то закрытие файла вызывает ошибку. Не мог бы кто-нибудь объяснить мне, что может означать код ошибки (если есть), и как эта ошибка может быть решена? Спасибо.

EDIT: «write()» записывает в выходной файл, и это все; единственное, что он делает с выходным файлом, - fprintf-ing. Он ничего не возвращает, потому что это функция void. Не может видеть, что fclose() возвращает потому, что по-видимому программа падает, прежде чем я могу проверить возвращаемое значение: \

EDIT: Ниже специфика «запись()». Я изменил его на "write_insult()", чтобы избежать путаницы с системным вызовом.

void write_insult(Composite c,FILE* output){ 
printf("lol\n"); 
switch (c->type){ 
    case SENTENCE:{ 
     writeSentence(c,output); 
     break; 
    } 
    default: break; 
} 

}

void writeSentence(Composite c,FILE* output){ 
FILE* source; 
int random = 0; 
char* fileName = NULL; 
int i = 0; 
char* number = malloc(sizeof(char)*2); 
if (c->subtype < 10){ 
    number[0] = '0'; 
    sprintf(number+1,"%d\0",c->subtype); 
}else{ 
    sprintf(number,"%d\0",c->subtype); 
} 

fileName = malloc(sizeof(char)*17); 
strcpy(fileName,"res/SEN//.txt"); 
fileName[8] = number[0]; 
fileName[9] = number[1]; 
fileName[11] = '0'; 
fileName[12] = '0'; 
FILE* tester = NULL; 
while ((tester = fopen(fileName,"r")) != NULL){ 
    i++; 
    fclose(tester); 
    if (i < 10){ 
     fileName[12]++; 
    }else{ 
     fileName[11]++; 
     fileName[12] = '0'; 
     i = 0; 
    } 
} 
random = rand()%i; 
if (random < 10){ 
    number[0] = '0'; 
    sprintf(number+1,"%d\0",random); 
}else{ 
    sprintf(number,"%d\0",random); 
} 
fileName[11] = number[0]; 
fileName[12] = number[1]; 
fileName[17] = 0; 
source = fopen(fileName,"r"); 
Table t = parseFile(source); //remember to free 
i = 0; 
char* word = NULL; 
while (i < t->num){ 
    if (isInt(t->content[i])){ 
     word = chooseWord(atoi(t->content[i])); 
    }else{ 
     word = t->content[i]; 
    } 
    fprintf(output,"%s ",word); 
    i++; 
} 
fclose(source); 
destroyTable(t); 

}

EDIT: Я установил все вопросы, струнные, и ошибка не будет устранена. Кстати, если я вместо этого объявляю указатель файла внутри функции writeSentence вместо того, чтобы заранее открывать файл, а затем закрывать его до остановки функции, как-то все в порядке. Кстати, компилятор - это тот, который поставляется с Pelles C. Раньше это делало какие-то неуклюжие вещи, может быть, вина в том, что я не виноват?

EDIT: Возможно, я должен сконденсировать вопрос, задав вместо этого: при каких обстоятельствах fprintf может работать отлично в файле, открытом для записи, но не fclose, который сбой, прежде чем он сможет даже генерировать возвращаемое значение?

EDIT: Спасибо, ребята, за любую помощь и совет; Я узнал, что у меня есть нежелательная операция fopen где-то в коде. Кажется, это так, потому что проблема ушла.

+1

Что пишут и возвращают? – Mark

+7

Пожалуйста, опубликуйте определение 'write()'. – hmjd

+1

Отправьте пример, который мы можем воспроизвести, иначе вам не поможет. См. [Sscce.org] (http://sscce.org). – interjay

ответ

0

Извините, не знал, как все обстоит здесь. У меня не было больше успехов в расследовании того, что именно вызвало крах или что fclose возвращается, но, похоже, в коде есть нежелательная операция fopen. По какой-то причине это кажется виновником, так как проблема теперь исчезла. Спасибо вам за помощь

2

fclose сам, скорее всего, хорошо. Вероятно, проблема заключается в том, что у вас есть неопределенное поведение в другом месте вашего кода, что приводит к сбою программы позже. Во время разговора произошел сбой только fclose. Одним из примеров можно видеть из неопределенного поведения:

fileName = malloc(sizeof(char)*17); 
strcpy(fileName,"res/SEN//.txt"); 

Об этом пишет 18 байт (включая нулевой символ) в выделенных 17 байт. Существует также аналогичное переполнение буфера при записи в number. Разумеется, могут быть и другие случаи неопределенного поведения в другом месте кода, в том числе в функциях, которые вы не показывали. Один из возможных способов попытаться найти проблему - отключить разделы кода и посмотреть, продолжает ли он работать.

+0

Спасибо, я попробую. C ошибки работают таинственными способами, потому что в противном случае функциональность кажется прекрасной ... – user2531913

+0

Хм да и нет. Если вам выделено место в доме и произвольно возьмите больше, чем ваше, там тоже будут плохие вещи. Кстати, вам не нужно набирать вызовы sprintf, когда число равно 10. Вы можете просто использовать 'sprintf (buffer,«% 02d », number);' - 02d означает, что он будет иметь ширину 2 символа и будет быть дополненными '0' – enhzflep

0

Вы отводите 2 символов (скажем, 2 байта)

char* number = malloc(sizeof(char)*2); 
if (c->subtype < 10){ 

Затем заполнить первый с '0'

number[0] = '0'; 

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

sprintf(number+1,"%d\0",c->subtype); 
}else{ 

здесь тоже.

sprintf(number,"%d\0",c->subtype); 
} 

Попробуйте выделить по крайней мере 3 символов для нулевого прекращения, а также с помощью проверяемых строк копии, как snprintf, которая будет всегда Null прекратить и не будет идти от вашего массива.

Всегда проверяйте коды возврата.

1
fileName = malloc(sizeof(char)*17) 

- это всего лишь один символ для краткости (забыли «\ 0»?). Возможно, это все

Смежные вопросы