2013-08-12 3 views
0

Простой вопрос:сканирование из входного файла в C до достижения определенного символа (#)?

Если у меня есть строка во входном файле, который выглядит как выглядит:

Hello#Great#Day#Today 

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

+0

Я бы начать с написания алгоритма (проверки), а затем некоторые * код *. если это не сработает, принесите его сюда, и мы увидим, что мы можем сделать, чтобы помочь. – WhozCraig

+0

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

+1

Ну вот кикстарт. 1. Найдите размер файла (см. 'Fseek()' и 'ftell()'). 2. Выделите один буфер, достаточно большой для всего файла +1 для нуль-termiator (см. 'Malloc()'). 3. Прочитайте весь файл в буфер (см. 'Freed()'). 4. Установите терминатор '0' в * конец * буфера. И, наконец, перейдем к буфере с помощью 'strtok()' using '" # "' как ваш разделитель. Когда закончите, не забудьте освободить * просто * исходный блок памяти, выделенный в (2) выше. Просмотрите все те API, которые только что упомянуты, и сформулируйте свой план. Удачи. – WhozCraig

ответ

2

Предполагается, что вы читаете stdin. Определенно взгляните на подход @Whoz kick start (очень похожий на этот).


То, что вы хотели бы сделать, это создать динамический массив и заполнить его каждый байт читать через stdin. Затем вы захотите создать массив указателей на символы, которые будут указывать на первый символ в каждом «слове», где вы определяете слово как каждый символ перед символом (разделитель). Затем вы перебираете этот массив символов и заполняете массив указателей символов адресами памяти первого символа в каждом слове.

+0

* "... arr указывает только на первый символ каждого слова." * Нет, это не так. Это сохраняет адрес переменной области цикла ('byte' в массиве char. Это неопределенное поведение **, чтобы разыменовать этот указатель после выхода из цикла. Если вы хотите сделать это, буфер с полным файлом с каждым «#» заменен на «0», будет значительно лучше (не говоря уже о том, что вы с меньшей вероятностью сможете скомпрометировать ваш процесс). – WhozCraig

+0

@WhozCraig, теперь я понимаю, как неправильно мое решение - не знаю, что я думал –

+1

Thats значительно лучше. Ваш ответ и команда Magn3s1um в основном изложили кикстарт, о котором я упомянул в общем комментарии. – WhozCraig

2

Используйте strtok(), чтобы токенизировать ваш ввод указанным символом.

http://www.cplusplus.com/reference/cstring/strtok/

char str[] ="- This, a sample string."; 
char * pch; 
printf ("Splitting string \"%s\" into tokens:\n",str); 
pch = strtok (str,"#"); 
    while (pch != NULL) 
{ 
printf ("%s\n",pch); 
pch = strtok (NULL, "#"); 
} 
0

В два этапа, я использовал что-то вроде этого:

#include <ansi_c.h> 

//tokenizing a string 
int GetCount(char *in, char *delim, int *m); 
int GetStrings(char *in, char *delim, int count, char **out); 


void main(void) 
{ 
    int count, maxlen, i; 
    char inpString[]={"Hello#Greatest#Day#Today"}; 
    char *resultBuf[10]; 

    //get a count of strings to store 
    count = GetCount(inpString, "#", &maxlen); 

    for(i=0;i<10;i++) 
    { 
     resultBuf[i] = calloc(maxlen+1, sizeof(char)); 
    } 

    //Store strings in arrays 
    GetStrings(inpString, "#", count, resultBuf); 

    for(i=0;i<count;i++) 
    { 
     printf("%s\n", resultBuf[i]); 
     free(resultBuf[i]; 
    }    

} 
    //Gets count of tokens (delimited strings) 
int GetCount(char *in, char *delim, int *m) 
{ 
    char *buf=0; 
    char temp1[10]={0}; 
    char *inStr; 
    int count = 0; 
    int max = 0, keepMax = 0; 
    if(in) 
    { 

     inStr = calloc(strlen(in)+1, sizeof(char)); 
     strcpy(inStr, in); 
     if(strlen(inStr) > 1) 
     { 
      count = 0; 
      buf = strtok(inStr, delim); 
      while(buf) 
      { 
       strcpy(temp1, buf); 
       max = strlen(temp1); 
       (max > keepMax)?(keepMax = max):(keepMax == keepMax); 
       count++; 
       buf = strtok(NULL, delim); 
      } 
      *m = keepMax; 
     } 
     free(inStr); 
    } 
    return count; 
} 
    //Gets array of strings 
int GetStrings(char *in, char *delim, int count, char **out) 
{ 
    char *buf=0; 
    char *inStr; 
    int i = 0; 
    if(in) 
    { 

     inStr = calloc(strlen(in)+1, sizeof(char)); 
     strcpy(inStr, in); 
     if(strlen(inStr) > 1) 
     { 
      buf = strtok(inStr, delim); 
      while(buf) 
      { 
       strcpy(out[i], buf); 
       buf = strtok(NULL, delim); 
       i++; 
      } 
     } 
     free(inStr); 
    } 
    return 0; 
}