Использование регулярного выражения для проверки файла .dat

Я читаю файл, используя fgets. Мне нужно проверить каждую строку файла на соответствие регулярному выражению. Если есть небуквенно-цифровой символ, необходимо выйти из программы с отображением номера строки и «плохого» символа. То, что происходит, это выталкивание перед «плохим» персонажем. Вот мой файл .dat:

howard jim dave 
joe
(
Maggie

Мой вывод программы:

file opened
Digit: howard jim dave 
is not alphanumeric on line: 1
Exiting program!
File closed

То, что должно произойти, должно произойти в строке 3, поскольку вы можете видеть, что этого не происходит.

Вот мое регулярное выражение, которое находится в моем файле main.h:

#ifndef MAIN_H
#define MAIN_H

#ifdef  __cplusplus
extern "C" {
#endif

#define BUFF 1024
#define to_find "^[a-zA-Z0-9]+$"

Вот мой файлCheck.c

#include "main.h"

int fileCheck(FILE *fp)
{

    int ret_val;
    int line_count = 0;
    char file[BUFF];
    regex_t regex;

    if (regcomp(&regex, to_find, REG_EXTENDED) != 0)
    {
        fprintf(stderr, "Failed to compile regex '%s'\n", to_find);
        return EXIT_FAILURE;
    }

    if (fp != NULL)
    {
        while (fgets(file, BUFF, fp))
        {
            line_count++;

            if ((ret_val = regexec(&regex, file, 0, NULL, 0)) != 0)
            {
                printf("Digit: %s is not alphanumeric on line: %d\n", file, line_count);
                printf("Exiting program!\n");
                return EXIT_FAILURE;
            }
        }
    }

}

Я не уверен, является ли проблема символом "\n" или нет. Я так не думаю. Я хорошо знаю, если isalnum(), но мне поручено регулярное выражение. Каким может быть возможное решение этой проблемы? Спасибо вам за ваши предложения.

РЕДАКТИРОВАТЬ: я хотел упомянуть, что когда я использовал fscanf вместо fgets, указанное выше регулярное выражение работало нормально. Причина изменения в том, что мне нужно подсчитать каждую строку. Если я прав, fscanf игнорирует символ новой строки. Мне нужен способ подсчета новой строки. Можно ли считать новый с помощью fscanf? Мой исходный цикл чтения файла был:

while (fscanf(fp, "%11023s", file) != EOF
{
    line_count++;
    if (regexec(&regex, file, 0, NULL, 0) != 0)
    {
        printf("%s%d wrong:\n, file, line_count);
        return EXIT_FAILURE;
    }
}

person Clint    schedule 15.09.2013    source источник
comment
У меня было что-то на уме, но я не был уверен, и теперь кажется более вероятным, что первое регулярное выражение не работает. Я не разбираюсь в C, но действительно ли работает if ((ret_val = regexec(&regex, file, 0, NULL, 0)) != 0)? Разве это не должно быть if (regexec(&regex, file, 0, NULL, 0) != 0)?   -  person Jerry    schedule 15.09.2013
comment
@ Джерри, ты прав, у меня был ret_val в более старой версии, но даже это изменение не имело значения. Я все еще получаю свою исходную ошибку.   -  person Clint    schedule 15.09.2013
comment
Вы также используете регулярное выражение ^[a-zA-Z0-9 ]+$? (я думаю, что в этом случае лучше иметь \\s) В противном случае, я думаю, что это больше о чтении построчно, чем о регулярном выражении, и я не могу здесь особо помочь :( Если, возможно, это ответ может помочь?   -  person Jerry    schedule 15.09.2013


Ответы (1)


howard jim dave содержит пробелы.

Edit3:
Причина, по которой я сосредоточился на поиске только допустимых строк, заключалась в том, что вы,
использовали простой тестовый сценарий, который позже станет более сложным.
Однако, если это именно то, что вам нужно если вам это нужно, реальное решение состоит в том, чтобы просто искать
небуквенно-цифровой символ без пробелов.
Если используемая разновидность регулярного выражения требует совпадения от начала до конца,
это не сработает. .

  #define to_find "[^a-zA-Z0-9\\s]" 
     or, 
  #define to_find "[^a-zA-Z0-9\\ \\t\\f\\r\\n]"

   . . .
     Then down here if the regex matches, it found non alpha numeric

  if ( regexec(&regex, file, 0, NULL, 0)) == 0 )
  {
      printf("Digit: %s is not alphanumeric on line: %d\n", file, line_count);
      printf("Exiting program!\n");
      return EXIT_FAILURE;
  }

Edit2:
Это движок Posix? Какой код ошибки возвращает функция regcomp()? Вы должны установить REG_EXTENDED в качестве одного из параметров cflag.
К сожалению, конструкция (?: pattern ) является расширенной спецификацией.

С таким же успехом можно бросить в него кухонную раковину
REG_EXTENDED | REG_NEWLINE

Попробуйте эти flaqs и введите
"^\\s*[a-zA-Z0-9]+(?:\\s+[a-zA-Z0-9]+)*\\s*$" непосредственно в regcomp().

Это может помочь с кодом ошибки:

 int res_compile = 0;
 if ( (res_compile=regcomp(&regex, to_find, REG_EXTENDED) ) != 0)
 {
   fprintf(stderr, "Failed to compile regex '%s'\nError code:  %d\n", to_find, res_compile);
 }

Оригинал: Может быть, вам нужно

 # ^\s*[a-zA-Z0-9]+(?:\s+[a-zA-Z0-9]+)*\s*$

 ^ 
 \s* 
 [a-zA-Z0-9]+ 
 (?: \s+ [a-zA-Z0-9]+ )*
 \s* 
 $

Or

 # \A[^\S\r\n]*[a-zA-Z0-9]+(?:[^\S\r\n]+[a-zA-Z0-9]+)*\s*\z

 \A 
 [^\S\r\n]* 
 [a-zA-Z0-9]+ 
 (?: [^\S\r\n]+ [a-zA-Z0-9]+ )*
 \s*
 \z
person Community    schedule 15.09.2013
comment
Я ценю ваш ответ, однако я получаю warning: unknown escape sequence '\s', и когда я запускаю программу, регулярное выражение не компилируется. - person Clint; 15.09.2013
comment
@Clint Попробуйте избежать обратной косой черты. Если есть \, поставьте вместо него \\. - person Jerry; 15.09.2013
comment
@ Джерри, я только что сделал это и все равно получаю Failed to compile regex '^\s*[a-zA-Z0-9]+(?:\s*[a-zA-Z0-9]+)*\s*$' - person Clint; 15.09.2013
comment
@Clint Как насчет более простого: ^[a-zA-Z0-9\\s]+$? - person Jerry; 15.09.2013
comment
@ Джерри Нет, я ценю помощь каждого. Это дает мне исходную ошибку, которую я указал в своем посте. - person Clint; 15.09.2013
comment
@Clint - это движок Posix? Какой код ошибки возвращает функция regcomp()? Вы должны установить REG_EXTENDED в качестве одного из параметров cflag. К сожалению, конструкция (?: pattern ) является расширенной спецификацией. Попробуйте этот flaq и вставьте "^\\s*[a-zA-Z0-9]+(?:\\s+[a-zA-Z0-9]+)*\\s*$" прямо в regcomp(). - person ; 16.09.2013