2016-01-02 2 views
0

У меня есть txt-файл с именами файлов и их размером. Это, как я написал текстовый файл:Чтение строки за строкой C

banana //file name 
3 //the size of file banana 
programs 
12 
music 
524 

Я должен найти клавиатуры вводится имя файла и отобразить его размер.

Это мой код:

FILE *text; 
text=fopen("text.txt","r"); 
printf("Scan the number of letters of your file name"); 
int n; 
scanf("%d",&n); 
char s[++n]; 
printf("Scan the file name you are looking for: "); 
int i; 
    for(i=0;i<=n;i++) 
    { 
     scanf("%c",&s[i]); 
    } 
int l=0; 
char c[n]; 
char g; 
    while(!feof(text)) 
    { 
     if(l%2==1) {fgetc(text); fgetc(text); l++;} 
     if(l%2==0) 
     { 
     fgets(c,n,text); 
     fgetc(text); 
      for(i=0;i<n;i++) 
      { 
      printf("%c",c[i]); 
      } 
      l++; 
     } 
    } 

Очевидно, что это не правильно. Вы можете мне помочь? Я немного смущен.

+2

Первое наблюдение: 'feof' - это не способ сделать это [Почему« while (! Feof (file)) «всегда неправильно?» (Http://stackoverflow.com/questions/5431941/why- это-то время-feof-файлов всегда-неправильно). Путь к работе - это цикл, управляемый результатом «fgets», который читает одну текстовую строку за раз. 'while (fgets (...)! = NULL) {}', тогда вы анализируете строку, которая была прочитана. –

+0

'for (i = 0; i <= n; i ++) {scanf ("% c ", &s[i]);}' <--- Вы переполняете этот буфер. Остановите. В какой книге вы читаете? Что бы это ни было, это не работает для вас ... Вы хотели бы предложить книгу, которая обычно работает намного лучше? – Sebivor

ответ

1

Ugh! Пожалуйста, узнайте больше об основном вводе. Ваша программа имеет различные недостатки:

  • fgetc читает отдельные символы. Иногда это может быть полезно, но, очевидно, вы хотите прочитать целые строки. fgets делает это. Вы используете его один раз, но не рекомендуется смешивать их. Определите фронт, какую входную парадигму вы хотите использовать: char-wise (fgetc), по линии (fgets) или токен-мудрый (fscanf).
  • Пожалуйста, не вводите пользователя в число символов в имени файла. Быстро, сколько символов есть в MySpiffyDocument.txt? Это то, что должен делать компьютер.
  • Не используйте feof для управления входом yopur. Все входные функции имеют специальные значения возврата, указывающие, что либо конец файла был прочитан, либо произошла ошибка. Для fgets это возвращаемое значение составляет NULL, для fgetc это возвращаемое значение является специальной постоянной EOF. Функции feof и ferror полезны после того, как вы столкнулись с особыми возвращаемыми значениями для post mortem анализа двух конечных условий.
  • Ваш внутренний цикл, который отвечает за основную программную логику, не имеет никакого смысла. Например, для нечетного l, приращения l, а затем проверьте четность l –, который будет правдой, потому что вы только что ввели нечетное l. В таких случаях используйте else. И не помещайте вещи, которые все равно происходят в условных блоках: Приращение l один раз после блоков if/else.

Вот пример реализации:

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

int process(const char *filename) 
{ 
    char line[80]; 
    char name[80]; 
    int size; 
    int count = 0; 

    FILE *f = fopen(filename, "r"); 

    if (f == NULL) return -1; 

    while (fgets(line, sizeof(line), f)) { 
     if (count % 2 == 0) { 
      if (sscanf(line, "%s", name) < 1) continue; 
     } else { 
      if (sscanf(line, "%d", &size) < 1) continue; 
      printf("%12d %s\n", size, name); 
     } 

     count++; 
    } 
    fclose(f); 

    return 0;  
} 

int main() 
{ 
    char line[80]; 
    char name[80]; 

    puts("Please enter filename:"); 

    while (fgets(line, sizeof(line), stdin)) { 
     if (sscanf(line, "%s", name) == 1) { 
      process(name); 
      break; 
     } 
    } 

    return 0; 
} 

Things отметить:

  • Программа использует 80 символов макс. размер буфера; это означает, что ваши линии могут составлять до 78 символов. – содержание линии плюс новая строка '\n' плюс нулевой ограничитель '\0'. Это должно быть хорошо для многих случаев, но в конечном итоге линия может переполняться. (Таким образом, количество ваших писем с именами файлов имеет некоторые достоинства, но реальное решение здесь заключается в том, чтобы распределять память динамически. Я не буду открывать эту возможность червей сейчас.)
  • Код использует двойную стратегию: сначала прочитайте строки, затем сканируйте в эти строки с помощью sscanf, чтобы читать только первое слово в каждой строке.
  • Пустые строки пропускаются. Даже строки, которые не содержат допустимого числа, также пропускаются. Это небрежная обработка ошибок и может отключить подсчет нечетных/четных значений.
  • Чтение материала в интерактивном режиме с клавиатуры не очень просто в C. Конструкция awkward в main пытается обрабатывать случай, когда пользователь входит в пустую строку или вызывает сигнал конца файла через Ctrl-D/Z. Лучше и проще использовать аргументы командной строки через argc и argv.
  • Я переместил чтение файла в отдельную функцию.
+0

@chux: Да, вы правы, конечно. Исправлено. –

+0

@MOehm Большое вам спасибо! – ProgrammingFailure

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