Еще один вопрос о fopen в C от новичка - PullRequest
0 голосов
/ 12 июня 2011

Я новичок в C и в программировании в целом.Я хотел бы написать программу на C, которая будет читать содержимое текстового файла и выводить его на консоль.У меня есть текстовый файл с именем test.txt, который содержит строку «Привет».Я создал программу на C со следующим кодом:

#include <stdio.h>

main()
{
  FILE *myfile;
  myfile=fopen("test.txt", "r");
  printf("%s", myfile);
  fclose(myfile);
}

Эта программа компилирует OK (по крайней мере, с настройками по умолчанию), но когда я запускаю программу, строка «Привет» не появляется.Можете ли вы помочь мне увидеть, что я делаю не так?Спасибо.

Кроме того, есть ли у вас какие-либо справочные сайты C, которые вы бы порекомендовали?Я ищу сайт, который содержит спецификацию языка Си, возможно, включая примеры использования функций библиотеки.

Большое спасибо за ваше время.

Эндрю

Университет Карнеги-Меллона

Ответы [ 5 ]

4 голосов
/ 12 июня 2011

Вы пытаетесь напечатать строку в месте, указанном значением myfile, на консоль.Это явно неверно (если вы не знаете почему, это потому, что %s ожидает char*, а не FILE*, а FILE* не указывает на содержимое файла.).

Чтобы прочитать данные из файла, используйте fread:

char buf[80] = {0}; // fill buf with NULLs
fread(buf, sizeof(char), 2, myfile); // read 2 bytes 

Если вы хотите прочитать весь файл в буфер, все становится немного сложнее, потому что вы должны определить длинуфайл, а затем динамически распределять память в куче нужного размера для хранения файла.На странице fread есть хороший учебник на cplusplus.com .

1 голос
/ 12 июня 2011

Это самый безопасный способ сделать это.

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

main()
{
  FILE *myfile;
  char buf[80];
  myfile=fopen("test.txt", "r");
  while(!feof(myfile)){
    memset(buf, 0, 80);
    fread(buf, sizeof(char), sizeof(char)*79, myfile);
    printf("%s", buf);
  }
  fclose(myfile);
}

feof проверяет, что конец файла не достигнут. memset, устанавливает все в буфере на 0. fread будет читать до 79 символов из файла в буфер. Обратите внимание, что максимальный размер должен быть 79, а не 80, размер буфера. Это потому, что последнее место в массиве должно быть зарезервировано для нулевого символа '\ 0', который указывает C, что строка завершилась.

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

Если вы новичок в программировании в целом, я бы предложил изучить более дружественный для начинающих язык, такой как Python, до изучения C. Считается сложным для начинающих программистов, поскольку он не имеет автоматического управления памятью, объектно-ориентированного программирования функции или большая стандартная библиотека.

1 голос
/ 12 июня 2011

Для чтения строки имеет смысл использовать fgets, поскольку она читает до конца строки (\n).

char line[256]
fgets(line, sizeof(line), file);
printf("%s", line);
1 голос
/ 12 июня 2011

Это потому, что вы не читаете файл. Чтобы прочитать файл, вы можете использовать методы fread или fgets

0 голосов
/ 13 июня 2011

Проблема в том, что вы пытаетесь напечатать указатель ФАЙЛ вместо содержимого файла - вам нужна переменная для его хранения.

Было интересно увидеть другие подходы. Вот реализация с fscanf () -

#include <stdio.h>
#define FILENAME "test.txt"

int main(void)
{
    FILE *myfile;
    char string[81] = {'\0'};

    myfile=fopen(FILENAME , "r");
    if(myfile == NULL)
    {
        printf("The file test.txt could not be found! Exiting...\n");
        return -1;
    }
    while(fscanf(myfile, " %80[^\n]s", string) != EOF)
    {
        printf("%s\n", string);
    }
    fclose(myfile);

    return 0;
}

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

fscanf () возвращает количество успешных чтений (здесь будет 1 для 1 преобразования в строку) или EOF, если достигнут конец файла. Строка формата использует пробел в первую очередь для удаления любых предшествующих пробелов (новые строки, пробелы, табуляции) во входном потоке.

Использование спецификатора ширины поля (80) в функциях scanf () означает, что будет прочитано только это много символов, поэтому ввод не может пройти дальше выделенного пространства - полезно!

[^] означает, что поток будет читаться только до тех пор, пока не встретятся указанные символы. [^ \ n] - это способ получить строки с пробелами в них, так как семейство scanf () обычно только читает пробелы для строк. Обратите внимание, что символ новой строки не будет удален (он все еще первый в потоке).

Затем печатает строку с добавлением новой строки. Эта программа будет проходить через столько строк (до 80 символов, разделенных символами новой строки) в файле. Если вы хотите сохранить строки, вы можете сделать строку массивом массивов символов и увеличивать каждый раз. Здесь первый пробел в строке формата fscanf () пригодится, он удалит символ новой строки (и любой другой предшествующий пробел), который все еще находится в начале потока.

Я не нашел каких-либо окончательных учебных пособий для изучения C онлайн, но есть много доступных. Нынешний стандарт не подходит для начинающих, но черновая форма находится в свободном доступе: http://www.open -std.org / jtc1 / sc22 / wg14 / www / docs / n1124.pdf

Еще один хороший ресурс (но не учебник) - http://c -faq.com /

Лучшим справочным материалом для входов и выходов стандартных функций библиотеки, который я нашел, является справочное руководство Harbison & Steele C: A, но, к сожалению, оно не бесплатное.

...