Разбить строку на любое количество пробелов в C - PullRequest
0 голосов
/ 12 мая 2018

У меня есть файл, в котором каждое имя пользователя и пароль разделены разным количеством пробелов.

bob    passowrd1
saly password2
sam      password2

void parse()
{
    FILE*open;
    open = fopen("file.txt");
    char line[101];
    char*name;
    char*password;

    while(fgets(100,line,open)!=NULL)
    {
       name = strtok(line,"*\\s");
       password = strtok(NULL,"*\\s");
       printf("username : %s",name);
       printf("password : %s",password); 
    }
}

Я пытаюсь разбить строку, используя strtok, но он не принимает регулярное выражение в качестве разделителя.Единственный другой способ, которым я могу думать об этом, - это грубое принуждение путем наклона над строкой и создания 2 новых отдельных строк после пробелов.какие-либо предложения?

Ответы [ 3 ]

0 голосов
/ 13 мая 2018

Если доступно, вы можете использовать strsep (отдельная строка).strsep принимает набор разделителей и будет проходить через строку, разделяющую его на поля.Он превосходит strtok, поскольку не сохраняет скрытое глобальное состояние.

void split_fields_strsep( char *string ) {
    char *field;
    const char *delimiters = " \t\n";

    while( (field = strsep(&string, delimiters)) != NULL ) {
        // Multiple spaces will show up as multiple empty fields.
        // Skip them.
        if( *field == '\0' ) {
            continue;
        }

        printf("field: '%s'\n", field);
    }
}

Обратите внимание, что каждый field является указателем на исходный string.strsep разделит строку на поля, поместив нулевые байты в конце каждого поля.Если string равно foo bar baz \0, вы закончите с foo\0bar\0 baz\0 \0.Поэтому обязательно strdup строка, если вы хотите сохранить ее.


Если strsep недоступен, будет работать стандарт strtok.Он работает аналогично strsep и изменит исходную строку, добавив нулевые байты.

void split_fields_strtok( char *string ) {
    const char *delimiters = " \t\n";

    for(
        char *field = strtok(string, delimiters);
        field != NULL;
        field = strtok(NULL, delimiters)
    ) {
        printf("field: '%s'\n", field);
    }
}
0 голосов
/ 14 мая 2018

Разделение строки на любое количество пробелов в C

"*\\s" указывает на неправильное понимание того, как кодировать символы токена."*\\s" ищет 3 символа *, \ и s в качестве токенов, ни один из них не указывает пробелы при использовании с strtok().


Анализ строки ввода для белого-пространство с явным списком.Обязательно учитывайте в конце '\n' строки ввода или другие пробелы .

Пробелы в C включают в себя несколько символов:

Стандартными символами пробела являются следующие: пробел (' '), перевод формы ('\f'), новая строка ('\n'), возврат каретки ('\r'),горизонтальная табуляция ('\t') и вертикальная табуляция ('\v').
C11dr §7.4.1.10 2

// while(fgets(100,line,open)!=NULL)
while(fgets(line, sizeof line, open)) {  // Destination array is first argument

  const char *standard_white_space = " \f\n\r\t\v";
  name = strtok(line, standard_white_space);
  password = strtok(NULL, standard_white_space);
  printf("username : <%s>\n",name);
  printf("password : <%s>\n",password); 

}

В качестве альтернативы используйте isspace() или a " " в sscanf().


Совет. Чтобы код не содержал пробелов в username, password, напечатайте строку с символами часового типа, такими как <>, чтобы упростить обнаружение ошибок кодирования.

  char line[] = "bob    passowrd1\n";
  char*name = strtok(line, " ");
  char* password = strtok(NULL, " ");
  printf("username : <%s>\n", name);
  printf("password : <%s>\n", password);

Это выводит

username : <bob>
password : <passowrd1    <-- Oops
>
0 голосов
/ 12 мая 2018

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

name = strtok(line," ");
password = strtok(NULL," ");

будет делать именно то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...