Як отримати значення покажчика файлу, не переходячи до наступного розташування вказівника файлу (в C)

Чи є спосіб знайти символ, який зберігається у файловому покажчику без fgetc. Скажімо, у мене є слово "steve jobs" у файлі під назвою apple.txt є щось подібне

int main(int argc,char *argv[])
  {
   FILE *fp=fopen("apple.txt","r");
   if(fp=='s'&&(fp+2)=='e')
     printf("steve is there");
   else
     printf("Steve not there");
   fclose(fp);
  }

Зрозуміло, це насправді не працює! Це просто друкує щось на зразок C забороняє порівняння b/n pointer n int. Навіть я спробував додати * перед (fp + 2) і fp, він сказав, що немає відповідності для оператора ==

Я вважаю, що функція fgetc (FILE *) працює таким чином, що вона отримує непідписаний символ, а потім переміщує покажчик до наступного розташування. Чи є яка-небудь функція, щоб просто отримати символ, не переміщаючи покажчик, а також вищезазначений код можна будь-яким іншим способом ?!

0
Він хоче C-код, але складається як C ++. @ user997147: stdio.h є обома мовами.
додано Автор Mooing Duck, джерело
Ваше запитання говорить: "немає відповідності для оператора ==", але ви помітили його. Що з цим?
додано Автор Carl Norum, джерело
Я б запропонував, можливо, підручник з файлу IO. Ваше запитання досить безглуздо; fp - це дескриптор файлу . Вам потрібно буде прочитати далі, використовуючи будь-які функції IO, а потім fseek повернутись до початкової позиції.
додано Автор Brian Roach, джерело
насправді я використовую блоки коду .. але так, це було сказати, що! адже я використовував файл бібліотеки stdio.h. Це означає, що праворуч C: D
додано Автор Saifur Rahman Mohsin, джерело
@BrianRoach Це не зовсім правильно. fp не є дескриптором файлів, але структура FILE зберігає безліч метаданих, включаючи поточну позицію голів читання/запису, і, найважливіше, покажчик на буфер. Libc робить деякий неявний повтор, коли ви відкриваєте чи читаєте файл, і тому може бути дуже можливо зробити те, що він просить. Я нічого не кажу про портативність або ремонтопридатність, проте!
додано Автор proc-self-maps, джерело

2 Відповіді

"Символ, який зберігається в покажчику файлів" - це не важлива справа. У FILE не обов'язково будь-який символ зберігається . Наприклад, stdin і stdout часто є каналами зв'язку, а не файлами на диску, і взагалі вони взагалі не буферизуються.

Що робити замість цього, якщо ви знаєте , FILE стосується фактичного файлу на диску, а не каналу зв'язку, читається кілька символів, а потім використовується fseek , щоб повернутися до того місця, де ви були перед тим, як прочитати їх. Ваш приклад програми, переписаний для цього, буде виглядати приблизно так:

int main(void)
{
    FILE *fp = fopen("orange.txt", "r")
    if (!fp)
    {
        perror("fopen(orange.txt)");
        return 1;
    }

    if (getc(fp) == 'b' &&
        getc(fp) == 'a' &&
        getc(fp) == 'n' &&
        getc(fp) == 'a' &&
        getc(fp) == 'n' &&
        getc(fp) == 'a')
        puts("orange has a banana");
    else
        puts("orange has no bananas");

    /* return to the beginning of the file */
    if (fseek(fp, 0, SEEK_SET))
    {
        perror("fseek(orange.txt)");
        return 1;
    }

    /* do something else with `fp` here */

    /* all files are automatically closed on exit */
    return 0;
}

Якщо ви працюєте з файлом, природа якого ви не знаєте, - наприклад, будь-який файл, наданий користувачеві, - ви повинні бути готові до fseek , щоб завершити помилку, і встановіть errno на ESPIPE , що означає, що "це не файл, тобто потік даних, ви не можете перестрибнути в нього".

4
додано

Ви можете використовувати getc та ungetc . Прочитайте документацію про це (у вас може бути лише один символ віджимання).

У деяких системах (зокрема системах Posix, таких як Linux) у вас є можливість вказувати в пам'ять частину файлу. Дізнайтеся більше про системний виклик mmap , який дає змогу переглянути частина файлу як сегмент пам'яті. ( mmap не можна використовувати в небажаних файлах, таких як труби або сокети, він в основному працює з файлами "диска").

4
додано
Пояснення: ви можете викликати ungetc один раз між будь-якою парою операцій з читання. Або, мабуть, краще сказати (як ви це зробили у вашій оригінальній відповіді), що ви можете лише зняти один символ в будь-який момент часу.
додано Автор zwol, джерело
Остерігайтеся, що ви можете дзвонити за один раз тільки ungetc для кожного персонажа, отриманого з getc. Але деякі системи або бібліотеки (можливо, Glibc на Linux) іноді можуть дати вам більше. Я не буду залежати від такої поведінки. І, звичайно, деякі файли (але не всі, наприклад, не розетка або труба) є доступними, з fseek і ftell
додано Автор Basile Starynkevitch, джерело
Вау .. це допомагає. Незабутньою річчю було те, що я шукав. Дякую. І я також подивимось на MMAP теж. Дуже дякую
додано Автор Saifur Rahman Mohsin, джерело