Как читать файл построчно и получать указанные c символов или целых? - PullRequest
0 голосов
/ 08 марта 2020

У меня есть следующий входной файл:

3(3,3)
1(5,4)
2(7,7)
V
H

И у меня есть следующий код, чтобы напечатать все в нем:

      char const * const fileName = argv[1]; /* should check that argc > 1 */
      FILE *file = fopen(fileName, "r"); /* should check the result */
      char line[256];

      while (fgets(line, sizeof(line), file)) {
         printf("%s", line);
      }

      fclose(file);

Но я хочу получить только char или int от каждой строки, а не скобки. Как мне написать что-нибудь для этого?

Ответы [ 7 ]

1 голос
/ 08 марта 2020

Вы просто хотите проверить каждый символ и номер и принять только символы и цифры:

const char *fileName = "C:\\file.txt";
FILE *file = fopen(fileName, "r");
int c = 0;
while ((c = fgetc(file)) != EOF) {
    if (isdigit(c) || isalpha(c) || c == '\n')
        printf("%c", c);
}
fclose(file);

Результат:

1 голос
/ 08 марта 2020

Я хочу получать только char или int из каждой строки, а не скобки. Как я могу написать что-нибудь для этого?

После прочтения строки ввода в строку в line[], попробуйте проанализировать ее различными способами. Используйте "%n", чтобы записать смещение сканирования и определить, завершено ли сканирование.

Этот метод "%n" полезен для того, чтобы узнать, что 1(5,4) включает конечный ) и заканчивается там.

int index, x, y;
int n = 0;
sscanf(line, "%d (%d ,%d ) %n", &index, &x, &y, &n);
// Did scanning make it to the end and was there no extra junk at the end?
if (n > 0 && line[n] ==  '\0') {
  // Entire line scanned into index,x,y
  printf("index:%d, x:%d, y:%d\n", x, y, n);
} else
  char ch; 
  n = 0;
  sscanf(line, " %c %n", &ch, &n);
  if (n > 0 && line[n] ==  '\0') {
    // Entire line scanned into ch
    printf("ch:%c\n", ch);
  } else {
    printf("'%s' failed to scan into either\n", line);
  }
} 
1 голос
/ 08 марта 2020

Just The 1st Character

Если вы действительно просто хотите получить первый символ, тогда *line предоставит вам первый символ из каждой строки. Это эквивалентно line[0], и вы можете использовать любой из них взаимозаменяемо. Краткий пример:

#include <stdio.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */

int main (int argc, char **argv) {

    char buf[MAXC];
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    while (fgets (buf, MAXC, fp))
        printf ("'%c'\n", *buf);

    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);

Пример использования / Вывод

$ ./bin/fgets_sscanf_first dat/multivals.txt
'3'
'1'
'2'
'V'
'H'

Вы можете сохранить, а затем проверить, является ли первый символ ди git с isdigit(*line) (или как указано выше isdigit(*buf)). С одним di git вы можете вычесть '0', чтобы получить значение цифры c. См. Таблица ASCII

Разделение всех значений

Вы можете использовать sscanf для разделения одного или всех значений в строке, пытаясь проанализировать все 3 значения из строки, а затем проверка возврата , чтобы узнать, была ли у вас строка с круглыми скобками (возврат 3) или один символ (возврат 1). Вы можете использовать строку формата " %c(%d,%d" (пробел перед "%c" гарантирует, что начальные пробелы игнорируются). Вы можете использовать if/else или простой оператор switch для обработки различных случаев, например,

#include <stdio.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */

int main (int argc, char **argv) {

    char buf[MAXC];
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    while (fgets (buf, MAXC, fp)) {
        char c;
        int v1, v2;
        switch (sscanf (buf, " %c(%d,%d", &c, &v1, &v2)) {
            case 1 : printf ("single char/digit: '%c'\n", c);
                    break;
            case 3 : printf ("all values: %c  %d  %d\n", c, v1, v2);
                    break;
            default : fputs ("invalid line format\n", stderr);
        }
    }
    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);
}

Пример использования / Вывод

$ ./bin/fgets_sscanf_multival dat/multivals.txt
all values: 3  3  3
all values: 1  5  4
all values: 2  7  7
single char/digit: 'V'
single char/digit: 'H'

Там Есть много, много способов сделать это, и это только один. Просмотрите все ваши ответы и дайте мне знать, если у вас есть дополнительные вопросы.

0 голосов
/ 08 марта 2020

Если вы хотите отбросить все в строке после и включая первую (, просто выполните:

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

FILE * xfopen(const char *path, const char *mode);

int
main(int argc, char **argv)
{
        FILE* file = argc > 1 ? xfopen(argv[1], "r") : stdin;
        char line[256];
        while( fgets(line, sizeof line, file) != NULL ) {
                char *c = strchr(line, '(');
                if( c != NULL )
                        *c = '\0';
                printf("%s%s", line, c ? "\n" : "");
        }
        fclose(file);
        return 0;
}


FILE *
xfopen(const char *path, const char *mode)
{
        FILE *fp = strcmp(path, "-") ? fopen(path, mode) : stdin;
        if( fp == NULL ) {
                perror(path);
                exit(EXIT_FAILURE);
        }
        return fp;
}

Использование scanf слишком сложно, и нет необходимости копировать строки.

0 голосов
/ 08 марта 2020

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

while (fgets(line, sizeof(line), file)) {
char modified[256];
int j = 0;

for (int i = 0; line[i] != '\0'; i++) 
    if (line[i] != '(' && line[i] != ')')
        modified[j++] = line[i];
modified[j] = '\0';
printf("%s", modified);
}
0 голосов
/ 08 марта 2020

Я думаю, вы можете использовать fscanf(file, "%c", ch). затем используйте fgets, чтобы перейти к следующей строке.

0 голосов
/ 08 марта 2020

sscanf выполняет форматированный ввод, также как printf выполняет форматированный вывод.

const char *line = "1(5,4)";
int one;
int five;
int four;
sscanf(line, "%d(%d,%d)", &one, &five, &four);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...