2012-04-11 8 views
0

Очень новое для программирования на C. Я пишу программу, в которой я хочу предложить пользователю ввести имя файла, который будет открыт для чтения. В моем коде, показанном ниже, я хочу выбросить ошибку, если она не открывается или файл не существует, но когда я его запускаю, мой код взрывается, и мне нужно закрыть программу (DOS)C - Как запросить пользователя ввести имя файла

/*ask user for the name of the file*/ 
    printf("enter file name: "); 
    gets(fname); 


//Opens the file from where the text will be read. 
fp=fopen(fname, "r"); 

//Checks if the file us unable to be opened, then it shows the error message 
if (fp == NULL) 
    { 
    printf("\nError, Unable to open the file for reading\n"); 
    } 

// вы можете проверить это, создав файл name.txt. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

+6

Как вы определили 'fname'? О, пожалуйста, пожалуйста, пожалуйста, не используйте 'get' - когда-либо! Рассмотрим «fgets» как одну из возможных альтернатив. –

+0

Вы также должны четко понимать, что вы имеете в виду, когда говорите «когда я его запускаю», особенно если вы новичок в C. Вы имеете в виду, что он не компилируется, он немедленно сбой при запуске или сбой после попытки для ввода имени файла и ввода ввода? – merlin2011

ответ

0

Не знаете, что вам не хватает, но эта программа компилируется и запускается для меня с использованием cl.exe в командной строке.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(){ 
    char fname[100]; 
    FILE* fp; 
    memset(fname, 0, 100); 
    /*ask user for the name of the file*/ 
    printf("enter file name: "); 
    gets(fname); 


    //Opens the file from where the text will be read. 
    fp = fopen(fname, "r"); 

    //Checks if the file us unable to be opened, then it shows the error message 
    if (fp == NULL) 
    { 
     printf("\nError, Unable to open the file for reading\n"); 
    } 

} 

отметить также, что некоторые компиляторы (в том числе от Microsoft) требуют, чтобы поместить все объявления в верхней части функции при вызове с параметрами по умолчанию.

3

Ну, вы должны убедиться, что есть достаточно места в fname для хранения имени файла, в противном случае вы почти наверняка вызовет коррупцию и «взрывать» :-)

Например, следующий фрагмент кода:

char fname[10]; 
gets (fname); 

будет проблематичным, если ввести более подробную информацию, чем fname. В этот момент вы находитесь на неопределенной территории поведения и ничего может случиться.

Но, поскольку gets не дает возможности ограничить ввод пользователем, вы никогда не должны его использовать!

Правильный, защищенный, способ ввода пользователя можно найти в this answer.

Он использует fgets, поскольку это может ограничить ввод пользователем. Он также допускает приглашение, дает сообщение об ошибке, если что-то пойдет не так, правильно обрабатывает конец файла и удаляет оставшуюся часть слишком большой строки, чтобы она не могла повлиять на следующую операцию ввода.

На самом деле, я скопирую его сюда, чтобы сделать этот ответ самодостаточным:

#include <stdio.h> 
#include <string.h> 

#define OK  0 
#define NO_INPUT 1 
#define TOO_LONG 2 
static int getLine (char *prmpt, char *buff, size_t sz) { 
    int ch, extra; 

    // Get line with buffer overrun protection. 
    if (prmpt != NULL) { 
     printf ("%s", prmpt); 
     fflush (stdout); 
    } 
    if (fgets (buff, sz, stdin) == NULL) 
     return NO_INPUT; 

    // If it was too long, there'll be no newline. In that case, we flush 
    // to end of line so that excess doesn't affect the next call. 
    if (buff[strlen(buff)-1] != '\n') { 
     extra = 0; 
     while (((ch = getchar()) != '\n') && (ch != EOF)) 
      extra = 1; 
     return (extra == 1) ? TOO_LONG : OK; 
    } 

    // Otherwise remove newline and give string back to caller. 
    buff[strlen(buff)-1] = '\0'; 
    return OK; 
} 

Вы можете назвать это следующим образом, указывая буфер и размер, и получать индикацию ошибки по возвращении:

// Test program for getLine(). 

int main (void) { 
    int rc; 
    char buff[10]; 

    rc = getLine ("Enter string> ", buff, sizeof(buff)); 
    if (rc == NO_INPUT) { 
     // Extra NL since my system doesn't output that on EOF. 
     printf ("\nNo input\n"); 
     return 1; 
    } 

    if (rc == TOO_LONG) { 
     printf ("Input too long [%s]\n", buff); 
     return 1; 
    } 

    printf ("OK [%s]\n", buff); 

    return 0; 
} 
+0

Могу ли я использовать scanf? – NewLearner

+0

@NewLearner, есть и другие проблемы с 'scanf', особенно если вы используете строку формата 'unbounded string''% s'.Он также подвержен переполнению буфера. 'scanf' означает« отсканировать форматирование », и не так много _unformatted_, чем пользовательский ввод :-) Не поймите меня неправильно, это нормально в большинстве случаев, особенно для обучения C или классной работы, или быстрых и грязных программ, но это не хорошо для кода качества продукции. – paxdiablo

0

ну, это то, что произошло со мной, добавив условие «еще» для «если» для меня. Как упоминалось, это код.

#include<stdio.h> 
#include<conio.h> 
#include<string.h> 

int main() 
{ 

char fname[100]; 
FILE* fp; 
memset(fname, 0, 100); 
/*ask user for the name of the file*/ 
printf("enter file name: "); 
gets(fname); 

fp = fopen(fname, "r"); 

//Checks if the file us unable to be opened, then it shows the error message 
if (fp == NULL) 
{ 
    printf("\nError, Unable to open the file for reading\n"); 
} 

else 
{ 
    printf("hello"); 
} 


getch(); 
} 

Также убедитесь, что вы добавили «#include» в качестве файла заголовка.