Удалить начальные строки из текстового файла с помощью c - PullRequest
0 голосов
/ 30 апреля 2019

У меня есть код назначения в C, пытающийся удалить начальные пробелы из файла, используя C вместо оболочки.В настоящее время у меня есть программа, которая удаляет все пробелы из программы.Я просто не могу понять, как, кому это сделать, убрать только пробелы в начале строки перед фактическим текстом.Очень плохо знаком с кодированием на c, поэтому мне жаль, если это кажется простым вопросом.Также у меня есть жестко запрограммированный файл, но я бы хотел иметь возможность передавать любой текстовый файл.Для пояснения я только пытаюсь удалить начальные пробелы и пытаюсь сделать это из тестового файла, который передается через командную строку.Я не использую строку.


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

void main() {
   FILE *fp;
   char p;


   fp = fopen("mountainList.txt", "r");

   while((p=getc(input))!=EOF) {
     if(p != 32) 

   printf("%c",p);

   }
     fclose(input);

}


Example text file:

           this is a test file
    this is a file of text
              text is in this file
Example output:

this is a test file
this is a file of text
text is in this file

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Ты почти у цели.Просто нужно немного больше кода в цикле.Вот как я могу это сделать (ваш стиль кодирования может отличаться - например, условия Yoda):

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

int main() {
   FILE *fp;
   int p;
   int at_start = 1;

   fp = fopen("mountainList.txt", "r");

   while (EOF != (p = getc(input))) {
     if (at_start && ' ' == p) continue;
     putc(p);
     at_start = ('\n' == p);
   }
   fclose(input);
}
0 голосов
/ 30 апреля 2019

Пара замечаний по кодированию.Не используйте жестко закодированные имена файлов или числа (называемые «магическими числами» ), например,

fp = fopen("mountainList.txt", "r");
...
if(p != 32)

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

Если вам нужна числовая константа или строкаконстанта, #define их в начале вашего кода.Это обеспечивает единственное удобное расположение для внесения одного изменения, если в дальнейшем понадобятся изменения.

Хотя в использовании getc (fgetc) нет ничего плохого, рассмотрите возможность использования строчно-ориентированного функция ввода для чтения строки ввода за один раз, например fgets() или POSIX getline().Затем вы можете использовать строковые функции, которые могут автоматически сообщать о количестве пробельных символов, которые должны быть удалены.

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

Например, следующееимя файла для чтения в качестве первого аргумента программы (или чтение из stdin по умолчанию, если имя файла не задано), а затем после проверки файл открыт для чтения, читает строку-на-a-time, передавая строку strspn вместе со строкой, содержащей пробельные символы " \t" (пробел, табуляция).Возвращаемое значение strspn - это начальное количество символов, состоящее полностью из символов в строке пробела, которое вы затем можете использовать в качестве смещения (или индекса) для печати вашей строки, пропуская начальный пробел, например,

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

#define MAXC 1024       /* if you need a constant, #define one (or more) */
#define WS " \t"        /* leading whitespace characters to remove */

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

    char line[MAXC];    /* buffer to hold line (don't skimp on buffer size) */
    /* 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 (line, MAXC, fp))                  /* read each line */
        printf ("%s", &line[strspn (line, WS)]);    /* output w/o leading ws */

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

    return 0;
}

Или, если вы предпочитаете печать с использованием указателя и смещения, вы можете заменить вызов на printf на:

        printf ("%s", line + strspn (line, WS));    /* output w/o leading ws */

( note: , если вы хотите удалитьстрок, содержащих все пробелы, проверьте наличие конца строки при смещении, возвращаемом strspn и просто пропустите печать строки)

Использование вашего примера ввода приведет к следующему:

$ /bin/removews <dat/wslines.txt
this is a test file
this is a file of text
text is in this file

Как упоминалось в начале, нет ничего плохого в подходе для чтения файла с getc, но знайте другой вариант подходе , ориентированном на строкичтение всей строки в буфер может затем сделать функции из string.h доступными для использования в самом буфере.

Посмотрите вещи и дайте мне знать, если у вас есть дальнейшиевопросы.

0 голосов
/ 30 апреля 2019
#include <ctype.h>
#include <string.h>
#include <stdio.h>

char *trimLeading(char line[])
{
    char *p;

    for (p = line; *p && isspace(*p); ++p) ;

    return p;
}

void printTrimmedLns(FILE *fp)
{
    char line[MAXLINE];

    while (fgets(line, MAXLINE, fp))
        printf("%s", trimLeading(line));
}

Звоните так:

printTrimmedLns(stdin); /* or whatever input stream you need */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...