2016-07-02 1 views
-2

Я новичок на языке C, и unix не имеют большого опыта в нем. Я пытаюсь подсчитать общие строки внутри файла с помощью системного вызова unix, но я не получаю никакого результата. Мой lineCount всегда выходит как 0 Я не знаю почему? Я хочу, чтобы кто-то, чтобы помочь мне выяснить линию засчитан, если possible.ThanksЧтобы подсчитать общее количество строк в файле, используя системный вызов Unix, в C

int lineCount = 0; 
while (*buffer != '\0') // to check the end of the file 
{ 
    read(in_fd, buffer, BUFFERSZ); 
    if (*buffer == '\n') 
    { 
     lineCount++; 
    } 
} 

printf("Linecount: %i \n", lineCount); 
+0

Unix системный вызов? что? – redFIVE

+0

Система @redFIVE Unix Вызывает, например. open, read, close, lseek и т. д. – bmalhi

+0

Почему бы не прочитать * символ по символу * используя 'getch()' и увеличить 'lineCount', когда вы сталкиваетесь с' \ n' :) – Cherubim

ответ

0

Ваш код проверяет только код *buffer для новых строк, который является первым символом каждого BUFFERSZ фрагмента, который вы читаете, то есть ваш код даже не смотрит на большую часть ввода. (Это также не проверяет, в случае конца файла правильно: вы должны смотреть на read «s возвращаемого значения для этого.)

Вот простое решение, которое эмулирует fgetc с помощью read:

size_t lines = 0; 
char c; 
while (read(in_fd, &c, 1) == 1) { 
    if (c == '\n') { 
     lines++; 
    } 
} 

printf("Linecount: %zu\n", lines); 

Если вы не можете использовать printf либо, быстро устранить проблему:

static void print_n(size_t n) { 
    if (n/10) { 
     print_n(n/10); 
    } 
    char c = '0' + n % 10; 
    write(1, &c, 1); 
} 

... 
write(1, "Linecount: ", strlen("Linecount: ")); 
print_n(lines); 
write(1, "\n", 1); 
+0

спасибо за помощь, в которой он работал наконец. – bmalhi

-1

Ссылка: Count number of line using C Используйте код

FILE *fp = fopen("myfile.txt"); 
int ch; 
int count=0; 
do { ch = fgetc(fp); 
if(ch== '\n') 
count++; 
}while(ch != EOF); 
printf("Total number of lines %d\n",count); 
0

Работа с open, read и write, на самом деле не сильно отличается от работая с fopen, fread и fwrite (или fgets и fprintf) за исключением любых конверсий, подсчета байтов и настроек созданных битов доступа к файлу, находящихся на вас. Когда write записывает в файл значение 1020, он записывает номер bytes, который вы укажете ему, чтобы написать, и номер будет существовать в файле с тем же контентом, как ваше оборудование.

Например, если у вас есть unsigned v = 1020; (0x3fc в шестнадцатеричном), а затем write (fd, &v, sizeof v);, когда вы смотрите на ваш файл с hexdump или od (или тому подобное), он будет содержать fc 03 00 00 (предполагая, что ваше оборудование прямой порядок байтов). Это ваши 4-bytes значения unsigned1020. Вы не можете открыть файл в текстовом редакторе и ожидать увидеть символы ASCII, потому что это не то, что было записано в файл.

Чтобы найти количество строк в файле с помощью open и read, вы в основном хотят open файл, прочитать файл в буфер некоторое разумное количество байт в то время, и сосчитать '\n' символов в файле.

(примечание: вы также хотите, чтобы проверить, если последний символ чтения из файла есть нечто иное, чем '\n' Если вы хотите добавить +1 к вашей линии отсчета для учета не-. POSIX конец финальной строки.)

Единственное другое предостережение - обратить внимание на mode (разрешения) для любого нового созданного вами файла open для записи. В противном случае вы окажетесь без доступа к вновь созданному файлу. Вот почему open предоставляет mode_t mode в качестве третьего аргумента в случае, если предусмотрен флаг O_CREAT.

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

Соединяя кусочки вместе, вы можете сделать что-то вроде следующего, оставаясь верным своему делу.В следующем коде имена infile и outfile указаны в качестве первых двух аргументов программы: infile65K bytes за один раз, подсчитывает '\n' s в файле, а затем записывает результат в outfile, в котором учтен любой конец строки, не относящейся к POSIX для файла , writeliteral предоставляется в качестве помощника для сообщений об ошибках:

#include <sys/stat.h> 
#include <fcntl.h> 
#include <unistd.h> 

enum { BUFFERSZ = 1 << 16 }; /* 65K buffer size */ 

void writeliteral (int fildes, const char *s); 

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

    if (argc < 3) { 
     writeliteral (STDERR_FILENO, "error: insufficient input.\n"); 
     writeliteral (STDERR_FILENO, "usage: progname infile outfile\n"); 
     return 1; 
    } 

    char buf[BUFFERSZ] = ""; 
    unsigned i = 0, nlines = 0; 
    ssize_t n = 0; 
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; 
    int fd = open (argv[1], O_RDONLY); 

    if (fd == -1) {    /* validate file open for reading */ 
     writeliteral (STDERR_FILENO, "error: infile open failed.\n"); 
     return 1; 
    } 

    while ((n = read (fd, buf, sizeof buf)) > 0) /* read 65k chars */ 
     for (i = 0; i < n; i++)   /* count newlines in buf */ 
      if (buf[i] == '\n') 
       nlines++; 
    if (buf[i - 1] != '\n')  /* account for non-POSIX line end */ 
     nlines++; 

    close (fd); /* close file */ 

    /* open outfile for writing, create if it doesn't exist */ 
    if ((fd = open (argv[2], O_WRONLY | O_CREAT, mode)) == -1) { 
     writeliteral (STDERR_FILENO, "error: outfile open failed.\n"); 
     return 1; 
    } 
    write (fd, &nlines, sizeof nlines); /* write nlines to outfile */ 

    close (fd); /* close file */ 

    return 0; 
} 

/** write a string literal to 'fildes' */ 
void writeliteral (int fildes, const char *s) 
{ 
    size_t count = 0; 
    const char *p = s; 

    for (; *p; p++) {} 
    count = p - s; 

    write (fildes, s, count); 
} 

Пример входного файла

$ nl -ba ../dat/captnjack.txt 
    1 This is a tale 
    2 Of Captain Jack Sparrow 
    3 A Pirate So Brave 
    4 On the Seven Seas. 

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

$ ./bin/readwrite_lineno ../dat/captnjack.txt ../dat/jacklines.dat 
$ hexdump -n 16 -C ../dat/jacklines.dat 
00000000 04 00 00 00          |....| 
00000004 

Посмотрите его и дайте мне знать, если у вас есть вопросы. Это показывает, почему вы можете оценить семейство спецификаторов формата еще больше, когда закончите.

+0

Благодарим вас за подробное объяснение системных вызовов. – bmalhi

+0

Конечно, рад это сделать. Теперь, «технически», вызовы 'open',' read' и 'write' - это просто функции libc. Хотя они могут иметь то же имя, что и системный вызов Linux, реализация в C - это только функция. Если вы программировали в сборке, тогда они были бы правильно названы * системными вызовами *, которые вы могли бы использовать с * системным прерыванием *, чтобы вызвать их. Они правильно упоминаются в C как функции * ввода-вывода * на нижнем уровне. Удачи вам в кодировании. Если это ответит на ваш вопрос, вы можете выбрать ответ, чтобы указать это, и помочь этому вопросу покинуть активный список. –

Смежные вопросы