2016-05-08 5 views
-3

Здравствуйте, я написал этот код для следующего вопроса: Напишите программу на C, которая читает текстовый файл в массив символов. Вы можете предположить, что файл содержит не более 1000 символов. Но код печатает только первый символ текста. Где я могу ошибаться?Чтение текстового файла

FILE *wse; 
char a[1000]; 
int i; 

    wse=fopen("21e.txt","r"); 

    for(i=0;i!=100;i++); 
    { 
    fscanf(wse,"%c",&a[i]); 
    printf("%c",a[i]); 
    } 
+0

Почему бы вам не попробовать fgets напрямую так как вы уже выделили предполагаемое пространство для него, так как fscanf останавливается в первом soace? – Kiloreux

+1

Или просто 'fread' весь файл. Кажется, нет никакой причины использовать какую-либо функцию токенизации. – Olaf

+2

Ваш цикл 'for' имеет пустое тело. Удалите точку с запятой после 'for (i = 0; i! = 100; i ++)' - также 'i <100' будет более безопасным ... (-: – user3078414

ответ

1

Отстранитесь минуту и ​​изучить альтернативные варианты у вас есть для ввода в C. У вас есть характер ориентированных функции ввода (getchar(), fgetc() и т.д ..), который будет читать файл из одного символа-на-времени , После этого у вас линии ориентированных на входных функций (например, fgets и getline), который читает строки ввода в то время, и, наконец, у вас есть блок-ориентированные входных функций, такие как fread и read, которые вы можете использовать, чтобы прочитать все файл в один блок памяти. (есть и другие инструменты для копирования и доступа к памяти, такие как sendfile и mmamp, которые также могут быть использованы, но, вероятно, здесь не предназначены. Семейство функций scanf, хотя они и есть, не предназначено для чтения различных значений по нескольким линий.

Ваш основной подход должен быть либо характер ориентированных на вход или строкового входа для чтения файла в массив. Более легкие или два, вероятно, были бы ориентированным на линию адресом, в котором вы читали бы всю строку, а затем tokenize строку в отдельные слова с strtok (или с помощью указателя начала и конца, чтобы пройти вниз по каждой строке после того, как он читать разделительные слова).

Возьмите удар по выбранному вами подходу и отправьте сообщение, когда вы застрянете. Мы будем рады помочь.

Краткий пример использования fgets для прочтения каждой строки, следующей за strtok, чтобы разделить каждую строку на слова, может быть чем-то вроде следующего. примечание: программа будет считывать из файла заданного в командной строке (или из stdin по умолчанию, если имя не задано)

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

enum {MAXC = 1000}; 

int main (int argc, char **argv) { 

    char buf[MAXC] = ""; 
    char *delims = " \t\n.,:;"; /* word separators for strtok */ 
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; 

    if (!fp) { /* always validate file is open for reading */ 
     fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); 
     return 1; 
    } 

    while (fgets (buf, MAXC, stdin)) { /* read each line into buf */ 
     char *p = buf; 
     printf ("\n line: %s\n tokens:\n", buf); 
     /* tokenize buf into words with strtok */ 
     for (p = strtok (buf, delims); p; p = strtok (NULL, delims)) 
      printf (" %s\n", p); 
    } 
    if (fp != stdin) fclose (fp); /* close if not reading stdin */ 

    return 0; 
} 

Пример ввода

$ cat dat/captnjack.txt 
This is a tale 
Of Captain Jack Sparrow 
A Pirate So Brave 
On the Seven Seas. 

Пример/Выход

$ ./bin/strtok_fgets_file <dat/captnjack.txt 

line: This is a tale 

tokens: 
    This 
    is 
    a 
    tale 

line: Of Captain Jack Sparrow 

tokens: 
    Of 
    Captain 
    Jack 
    Sparrow 

line: A Pirate So Brave 

tokens: 
    A 
    Pirate 
    So 
    Brave 

line: On the Seven Seas. 

tokens: 
    On 
    the 
    Seven 
    Seas 
1

Просто используйте fgetc и putchar, так как вы читаете символ-персонажем

int c; 
while ((c = fgetc(fp)) != EOF) 
    putchar(c); 

Кроме того, проверьте возвращаемое значение fopen. Он возвращает NULL при сбое.

+0

Поскольку цель состоит в том, чтобы прочитать файл в массиве 'char', печать, указанная в вопросе, вероятно, просто диагностическая проверка (хорошая идея). Это пропустит проблему с кодом в вопросе , который [был указан правильно] (https://stackoverflow.com/questions/37105074/reading-a-text-file#comment61752805_37105074) пользователем [user3078414] (https://stackoverflow.com/users/3078414/user3078414) –

2

У вашего кода есть логическая ошибка, которая делает ее сломанной - очень легко исправить.

  • Ваш цикл имеет пустое тело - вот почему он печатает только первый символ. Точка с запятой удалена.

Существует также проблема стиля в проверке значения счетчика:

  • Хотя проверкиi против не будучи 100 не сделает ваш код потерпеть неудачу, если все остальное в порядке, он более распространен и соответствует вашей спецификации задачи, чтобы проверить его значение за менее100, или какую бы константу вы ни хотели.

Хотя это может быть не самым элегантным способом завершения такой задачи, это переделки вашего чтения по-характер кода метода:

#include <stdio.h> 

int main(void) 
{ 
FILE *wse; 
char a[1000]; 
int i; 

    if((wse=fopen("3.txt","r")) == NULL)//always check for file errors! 
     return 1; 

    for(i=0 ; i<100 ; i++) 
    { 
     if(fscanf(wse,"%c",&a[i]) != 1) //check against end of file! 
      break; 
     printf("%c",a[i]); 
    } 
    fclose(wse); 
return 0; 
} 
+0

@chux - ваше предложение очень ценно - я улучшил свой ответ на него - спасибо! – user3078414

1

Пожалуйста, найдите исправленный код:

FILE *wse; 
char a[1000]; 
int i=0; 

wse=fopen("21e.txt","r"); 

while(fscanf(wse,"%c",&a[i]) == 1) 
{ 
    printf("%c",a[i]); 
    i++; 
} 

Во-первых, я исправил код, удалив точку с запятой после цикла for. А во-вторых, заменить на цикл while так, чтобы он читал до конца файла. Это связано с тем, что если цикл пересекает EOF (конец файла), он может упасть.

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