2013-07-26 2 views
0

Так что это как текст в файле выглядит следующим образом:как сканировать текстовый файл с помощью fscanf с помощью разделителей?

locked y 
    locked n 
    position 90 
    position 2 
    audio-language "english" 
    audio-language "spanish" 

каждый текстовый файл содержит только один вид настроек, показанных выше, разница вариант (у или п, 1 до 999, «английский «« испанский »« все остальное ») у него есть 4 белых пространства впереди и новая строка в конце каждой строки, поэтому мне нужен fscanf, который будет извлекать параметр в строке массива символов, но я не могу понять, как для правильного использования разделителей. Я должен сделать программу, которая может сканировать этот файл и распечатать различные настройки и сколько раз они встречаются в файле, например:

audio-language is found with setting: "spanish" 40 times 

audio-language is found with setting: "english" 78 times 

всех вас за ваши ответы! Здесь я могу показать вам, как я сделал это работа:

1 - Во-первых, когда вы используете несильно (который я нашел в Интернете), что устраняет пробелы перед настройками:

char* ltrim(char* s) 
{ 
    char* newstart = s; 

    while (isspace(*newstart)) { 
    ++newstart; 
    } 

    // newstart points to first non-whitespace char (which might be '\0') 
    memmove(s, newstart, strlen(newstart) + 1); // don't forget to move the '\0' terminator 

return s; 
} 

2 - Тогда fscanf не имеет проблем с получением права строки:

while(!feof(fpoo)) { 
    fscanf(fpoo,"%s %[^\n]",&first, &sec); 

3 - Тогда вы сравнить те fscanf получили с теми, пользователь ввел

Вот и все, видимо, вся проблема с fscanf была из-за белых пробелов перед каждой строкой.

+1

Пожалуйста ** ** показать ваши попытки ... –

+0

Я думаю, что она будет решена с помощью 'strtok' – phoxis

+0

Для решения C, я рекомендую использовать [' fgets'] (HTTP://en.cppreference.com/w/c/io/fgets), чтобы получить каждую строку, а затем сделать 'sscanf', чтобы получить ключ и значение. Если значение должно быть числовым, используйте, например, ['strtol'] (http://en.cppreference.com/w/c/string/byte/strtol) после сканирования, чтобы преобразовать его. Используйте «strcmp» на ключе, чтобы узнать, какой именно ключ. –

ответ

2

Я скомпилировал thi и его протестировали. Работает отлично. Вы можете проверить это тоже :)

int main() 
{ 
    int bytes_read = 0, english_count = 0, spanish_count = 0; 
    char file_buffer[256], setting[127], option[32], fileName[32] = "FileName.txt"; 
    FILE *fp; 
    if((fp = fopen("FileName.txt", "rb")) <=0) 
    { 
     printf("Unable to open the File\n"); 
    } 
    //rewind(fp); 
    while(fgets (file_buffer, 50, fp)) 
    { 
     sscanf(file_buffer,"%s %s",setting,option); 
     printf("Setting: "); 
     printf("%s",setting); 
     printf("\nOption: "); 
     printf("%s",option); 
     printf("\n\n"); 
     if(memcmp(setting,"audio-language",14) == 0) 
     { 
      if(memcmp(option,"english",7) == 0) 
      { 
       english_count = english_count+1; 
      } 
      if(memcmp(option,"spanish",7) == 0) 
      { 
       spanish_count = spanish_count+1; 
      } 
     } 
      //you can add more checks here. 
     } 
    printf("\naudio-language is found with setting: english "); 
    printf("%d",english_count); 
    printf("\naudio-language is found with setting: spanish "); 
    printf("%d",spanish_count); 
    printf("\n"); 

return 0; 
} 
+0

Это решит вашу проблему: – Ayse

+1

Спасибо за ваше время, что будет работать отлично, но я должен заставить его работать на всех возможных языках и не только, но и все другие настройки, и если я сделаю это, это будет одна длинная программа. –

0

проверить алгоритм и вы должны кодировать

  1. Прочитайте файл построчно е, г сказать 1024 байт за один раз.
  2. Затем сканируйте нужную строку, например, в вашем случае аудио-язык «английский» или аудио-язык «испанский».
  3. Получить строку для типа языка
  4. Затем подсчитайте, сколько раз вы нашли эту строку.

Я думаю, что это решает вашу проблему.

+0

Да, я сделал 1. и 2. до сих пор, но у меня проблемы с 3. и 4. потому что существует много разных вариантов не только на английском, но и на испанском, может быть 50 разных языков или позиций от 1 до 999, а я просто не знаю, как их подсчитать и распечатать, я могу распечатать их либо на экране, либо в файле frpintf. –

+0

Очень просто, если формат строки «case audio-language» english «». Просто найдите первый символ, используя любую стандартную функцию.e, g strstr() для символа в одиночку, а затем, если найдете, вы можете получить указатель на начало этой строки (strstr() возвращает), а затем прочитать до следующего "символа, а затем вы можете получить тип языка. – pradipta

+0

Дело в том, что я должен заставить его работать со всеми различными вариантами, а некоторые из них не имеют "" как = заблокировано y или позиция 100. Я не знаю, может быть, мне нужно набрать отдельный код для всех случаев. –

0

Вы можете сначала прочитать в строках, как:

scanf("%[^\n]s",buffer) 

Теперь вы можете использовать Tokenizer в C, чтобы получить значение языка с помощью strtok

char *token="\n"; 
token = strtok(line, token); 

Теперь токена содержат все раздвоенные слова, которые вы можете сравнить с strcmp с возможными языками и поддерживать счет

+0

Могу ли я как-то игнорировать первые 4 пробела и первую строку и хранить только вторую строку, ведьма может быть словом или числом, и все, что только с использованием разделителей в scanf с используя strtok? –

+0

Вы можете указать для этого регулярное выражение. Прочтите это: http://www.peope.net/old/regex.html –

+1

s/'"% [^ \ n] s "'/'"% [^ \ n] "'/... и 'fscanf 'не использует такое регулярное выражение. В каком руководстве вы читали? – Sebivor

0

Люди в ваших комментариях правы. Вы действительно должны были показать нам свою попытку. Если это домашнее задание, то вы не можете обманывать, потому что ваши преподаватели могут напасть на вас простым поиском google.Расточительно ожидать, что мы угадаем ваше понимание здесь и рассмотрим контент, который вы уже рассмотрели, поэтому покажите нам, что вы сделали.

qsort, bsearch и strcmp обеспечивают легкий, относительно эффективного рода & механизм поиска для всего, что начинается со строки (например. Струнно-приставкой структуры). Пробел в строке формата сообщает fscanf, чтобы максимально использовать пробелы. fscanf возвращает значение, указывающее режимы успеха и сбоя, что означает, что вам не обязательно читать каждую строку в массиве символов, чтобы проверить, соответствует ли вход определенного формата. Однако вам необходимо позаботиться о разработке файла, чтобы ни одна из команд не имела общих префиксов для других команд. В этом случае вы в безопасности.

Вот моя попытка. Счастливые отладки :)

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

struct language_table { char language[64]; size_t count; }; 
struct language_table *parse(FILE *f, size_t *s); 

int main(void) { 
    size_t s; 
    struct language_table *t = parse(stdin, &s); 

    while (s-- > 0) { 
     printf("audio-language is found with setting: %s %zu times\n", t[s].language, t[s].count); 
    } 

    free(t); 
} 

struct language_table *parse(FILE *f, size_t *s) { 
    char locked, language[64]; 
    unsigned int position; 

    int c = 0; 

    struct language_table *table = NULL, *entry; 
    size_t size = 0; 

    do { 
     if (fscanf(f, " locked %c", &locked) == 1 && strchr("ynYN", locked)) { 
      /* XXX: Do something with locked. */ 
     } 
     else if (fscanf(f, " position %u", &position) == 1) { 
      /* XXX: Do something with position. */ 
     } 
     else if (fscanf(f, " audio-language %63s", language) == 1) { 
      /* search for the language in table. */ 
      entry = bsearch(language, table, size, sizeof *table, strcmp); 

      /* insert the language if it's not found. */ 
      if (entry == NULL) { 
       if ((size & (size + 1)) == 0) { 
        void *new = realloc(table, (size * 2 + 1) * sizeof *table); 
        if (new == NULL) { 
         fprintf(stderr, "failed to allocate new entry for %s\n", language); 
         free(table); 
         return NULL; 
        } 
        table = new; 
       } 

       entry = table + size++; 
       strcpy(entry->language, language); 
       entry->count = 0; 

       /* sort & search */ 
       qsort(table, size, sizeof *table, strcmp); 
       entry = bsearch(language, table, size, sizeof *table, strcmp); 
      } 

      entry->count++; 
     } 
     else { 
      /* consume an invalid line */ 
      do { 
       c = fgetc(f); 
      } while (c >= 0 && c != '\n'); 
     } 
    } while (c >= 0); 

    *s = size; 
    return table; 
} 
Смежные вопросы