В Си, сохранить один символ за раз - PullRequest
1 голос
/ 29 сентября 2011

Я обрабатываю строку, в которой каждое слово разделено пробелами.<Указывает, что это перенаправление ввода, а> указывает, что это перенаправление вывода.Пример:

< Hello > World

Я хочу сохранить слова в разных переменных (char * in, char * out) Как я могу это сделать?Я просмотрел библиотеку строк, и, похоже, ни одна из них не справилась с этой задачей.

Вот что у меня есть по этому вопросу.

char buff[MAXARGS];
char *str;
char *in;
char *out;

if( strchr(buff, '<') != NULL )
{
  str = strchr(buff, '<');
  str++;
  if( *str == ' ' || *str == '\0' || *str == '\n'  || *str == '\t' )
  {
     fprintf( stdout, "User did not specify file name!\n" );
  }
  else
      in =  str; // This will save Hello > World all together. I don't want that. 
}

Большое спасибо.

Ответы [ 4 ]

0 голосов
/ 29 сентября 2011

Вам нужно решить, где будет выделено хранилище для двух имен файлов, и как вы узнаете, сколько места предоставляется.

static void find_filename(const char *str, char *name)
{
    char c;
    while ((c = *str++) != '\0' && isspace((unsigned char)c))
        ;
    if (c != '\0')
    {
        *name++ = c;
        while ((c = *str++) != '\0' && !isspace((unsigned char)c))
            *name++ = c;
    }
}

int find_io_redirection(const char *str, char *in, char *out)
{
    const char *lt = strchr(str, '<');
    const char *gt = strchr(str, '>');
    if (lt != 0)
        find_filename(lt+1, in);
    if (gt != 0)
        find_filename(gt+1, out);
    return(lt != 0 && gt != 0);
}

Этот код просто предполагает, что вы предоставляете достаточно большие строки для in и out.Если вы хотите быть более безопасным, то вы сообщаете функции (ам), насколько велика каждая целевая строка.Вы можете сжать этот код.Вы можете решить, что хотите вернуть количество перенаправлений.Вы можете решить, что вам следует знать о двойном перенаправлении вывода или двойном перенаправлении ввода.Вы можете решить, что должны вернуть битовую маску, указывающую, какие перенаправления присутствовали.Со значительно более сложным интерфейсом вы могли бы указать, какие части строки ввода представляют перенаправление ввода / вывода;это поможет вызывающей функции решить, какие части строки теперь следует игнорировать.

Вы бы использовали приведенный выше код, например, так:

char buffer[MAXCMDLEN];
char in[MAXFILENAMELEN];
char out[MAXFILENAMELEN];

if (fgets(buffer, sizeof(buffer), stdin) != 0)
{
    if (find_io_redirection(buffer, in, out))
        ...process buffer know that I/O redirection is present...
    else
        ...witter about missing I/O redirection...
}
0 голосов
/ 29 сентября 2011

при условии, что ваш входной шаблон зафиксирован как < input_name > output_name, и вы хотите иметь возможность извлекать input_name и output_name соответственно.

Одним из решений является разделение строки с помощью «<>». Следующий код распечатает Hello, World последовательно. Сохранение их в in и out оставлено для вас в качестве упражнения:)

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

int main ()
{
  char str[] ="< Hello > World";
  char *in;
  char *out;
  char *pch;
  char *del=" <>";
  pch = strtok (str,del);
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, del);
  }
  return 0;
}
0 голосов
/ 29 сентября 2011

Для начала, вот как вы можете это сделать, если вам разрешено изменять buff, и при условии простого случая (максимум один < и максимум один >).

Сначала получите позицию < и >

in  = strchr(buff, '<');
out = strchr(buff, '>');

Затем вы искусственно разбиваете строку:

if (in) {
  *in = 0;
  in++;
}
if (out) {
  *out = 0;
  out++;
}

В этот момент buff указывает наС-концевая строка, которая не имеет < или >.in является либо null, либо указывает на строку, которая следует за < и не содержит >.То же самое для out.

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

Вам понадобится целоемного логики, чтобы все случаи были правильными, включая отклонение неверного ввода.

0 голосов
/ 29 сентября 2011

Вы можете использовать это ..

char filename[max_path]
 str1 = strchr(buff, '<');
 str2 = strchr(buff, '>');

 memcpy( filename , str1+1 , str2-str1-1 ); 

поэтому путь между <и> будет в имени файла.

и

 output = str2 + 1;
...