Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464

Количество слов в файле

10.04.2014, 16:30. Показов 3007. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В программе на Си есть необходимость узнать количество слов в файле.
В консоле данную задачу можно решить при помощи команды:
Bash
1
wc filename -w
Скажите, как воспользоваться этой командой в Си? При этом меня интересует не просто вывод на экран значения, а именно число (т.е. ответ - количество слов в файле), которое необходимо сохранить в переменную. Скажите, возможно ли это или легче самому написать функцию?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.04.2014, 16:30
Ответы с готовыми решениями:

Количество слов в файле
В программе на Си есть необходимость узнать количество слов в файле. В консоле можно узнать при помощи команды: wc -l file Как...

Найти в файле предложения, содержащие заданное количество слов
Помогите, пожалуйста, разобраться в программе: #include <string.h> #include <stdio.h> #include <conio.h> #include...

Подсчитать в текстовом файле количество слов и количество цифр
Дан файл, содержащий текст. Сколько слов в тексте? Сколько цифр в тексте?

11
923 / 639 / 198
Регистрация: 08.09.2013
Сообщений: 1,693
10.04.2014, 17:46
Цитата Сообщение от galaid Посмотреть сообщение
Скажите, возможно ли это или легче самому написать функцию?
В данном случае, похоже, написать самому будет немного легче.
А способы реализации, конечно, есть.
1. Кустарный - через system вызывается "wc file -w > tmpfie", потом читается временный файл.
2. Стандартный
а) создаются каналы обмена (pipe)
б) вызываtтся fork()
в) в дочерней программе перенавравляется stdout в созданный pipe_out через вызов dup2()
г) в дочернем процессе вызывается что-то из семейства exec ("wc ...",.....)
д) в основной программе читаются данные с другого конца канала.
е) все неиспользованные, п потом и использованные дискрипторы каналов закрываются во всех процессах.
0
209 / 183 / 114
Регистрация: 15.03.2014
Сообщений: 398
10.04.2014, 18:34
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

galaid, нужно оценить все плюсы и минусы в конкретной Вашей ситуации.
С одной стороны - написать самому хорошее решение.
С другой стороны использовать готовый функционал утилиты wc - тоже неплохо.

Вот вариант с использованием утилиты wc

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
int main( int argc, char **argv ) {
 
    FILE *read_fp; // файловый поток - в него перенаправим вывод команды
    char buffer[ BUFSIZ + 1 ]; // сюда будем считывать вывод команды
    int chars_read; // количество считанных символов
 
    memset( buffer, '\0', sizeof( buffer ) ); // заполним нулями строку
 
    read_fp = popen( "wc -w textfile", "r" ); // вывод команды в файловый поток read_fp
 
    // popen возвращает NULL, если вызовы fork() или pipe() завершились ошибкой
    if ( read_fp != NULL ){ // или если невозможно выделить необходимый для этого объем памяти.
        // пробуем считать данные из фалового потока в ПЕРЕМЕННУЮ СТРОКУ buffer
        chars_read = fread( buffer, sizeof( char ), BUFSIZ, read_fp );
 
        // если в потоке вывода нет данных (fread() возвращает значение 0), значит произошла ошибка
        if ( chars_read > 0 ) // если считали что-то, то строка buffer непустая
            printf( "Содержимое строки buffer = %s\n", buffer );
 
 
        pclose( read_fp ); // не забываем закрыть файловый поток
 
        // осталось обработать саму строку buffer как Вам нужно.
 
        return EXIT_SUCCESS;
    }
 
 
    return EXIT_FAILURE;
}
Данный пример взят из книги Нэйл Мэтью, Ричард Стоунс. Основы программирования в Linux. 4-е издание 2009. Рекомендую к прочтению.
Начало 13 главы - Связь между процессами: каналы.
0
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464
10.04.2014, 18:41  [ТС]
Спасибо за ответы. Наверное все таки напишу функцию...
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
10.04.2014, 18:43
Кроме писать самому или вызвать процесс с wc, можно посмотреть как это сделано собственно в wc. Например в OpenBSD (т.к. там обычно самые простые исходники среди «никсов»).
1
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464
18.04.2014, 16:46  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Например в OpenBSD (т.к. там обычно самые простые исходники среди «никсов»)
Решил воспользоваться данным исходником. Переработал немного функцию под себя. В результате получилось вот что:
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int CountWords(char filename[])
{   int c;
    int wcount=0, t=0;
    FILE *input;
    input=fopen(filename, "r");
    if(input==NULL)
        fprintf(stderr, "Ошибка при открытии файла %s\n", filename);
    while(!feof(input))
    {
        c=fgetc(input);
        if(isspace(c))
            t=1;
        else
            if(t==1)
            {
                wcount++;
                t=0;
            }
    }
    if(fclose(input)==-1)
        fprintf(stderr, "Ошибка при закрытии файла %s\n", filename);
    return wcount;
}


Возникла проблема. Тестировал функцию на двух каталогах: /etc и /usr.
Так вот, для первого каталога результат нормальный (сходится с wc), но для второго каталога результат неверный. Функция для него возвращает количество слов большее, чем wc. Скажите в чем проблема?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
18.04.2014, 17:08
Цитата Сообщение от galaid Посмотреть сообщение
Возникла проблема. Тестировал функцию на двух каталогах: /etc и /usr.
Так вот, для первого каталога результат нормальный (сходится с wc), но для второго каталога результат неверный. Функция для него возвращает количество слов большее, чем wc. Скажите в чем проблема?
В какой ОС тестировал? Может есть отличия в реализациях. Кроме того, у тебя количество слов int, а в оригинале -- int64_t, а в /usr лежат всякие разные файлы, так что может быть элементарно переполнение int.
0
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464
18.04.2014, 19:08  [ТС]
korvin_, Ubuntu 12.04.
С int64_t аналогичный результат.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
19.04.2014, 12:13
А покажи как ты вызывал программы для тестирования.
0
 Аватар для galaid
289 / 34 / 6
Регистрация: 20.09.2011
Сообщений: 464
19.04.2014, 12:27  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
А покажи как ты вызывал программы для тестирования.
В ходе программы идет подсчет кол-ва слов в файлах каталога.
Результат перенаправил в текстовый файл, где каждая строка представляет собой: путь к файлу и кол-во слов в нем.
Сначала тестировал для /etc. Выбирал рандомные файлы из моего файла и сверял с wc. Результат сходился. Для /usr почему-то нет.
Заметил, что ошибка в подсчете наблюдается только в бинарных файлах (хотя может быть и еще где-нибудь).
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
19.04.2014, 12:41
Ага
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
~/prog/c $ wc -w /usr/bin/z*
    1623 /usr/bin/zcat
     548 /usr/bin/zcmp
     548 /usr/bin/zdiff
     801 /usr/bin/zegrep
     801 /usr/bin/zfgrep
     240 /usr/bin/zforce
     801 /usr/bin/zgrep
    9361 /usr/bin/zip
    3349 /usr/bin/zipcloak
     117 /usr/bin/zipdetails
    6289 /usr/bin/zipdetails5.16
     192 /usr/bin/zipgrep
    5833 /usr/bin/zipinfo
    3158 /usr/bin/zipnote
    3291 /usr/bin/zipsplit
     352 /usr/bin/zless
     352 /usr/bin/zmore
     582 /usr/bin/znew
    1490 /usr/bin/zprint
   39728 total
~/prog/c $ ./wordscount /usr/bin/z*
    1224 /usr/bin/zcat
     548 /usr/bin/zcmp
     548 /usr/bin/zdiff
     585 /usr/bin/zegrep
     585 /usr/bin/zfgrep
     240 /usr/bin/zforce
     585 /usr/bin/zgrep
    7634 /usr/bin/zip
    2652 /usr/bin/zipcloak
     117 /usr/bin/zipdetails
    6289 /usr/bin/zipdetails5.16
     192 /usr/bin/zipgrep
    4196 /usr/bin/zipinfo
    2505 /usr/bin/zipnote
    2600 /usr/bin/zipsplit
     352 /usr/bin/zless
     352 /usr/bin/zmore
     582 /usr/bin/znew
    1145 /usr/bin/zprint
   32931 total
~/prog/c $
Ну фиг знает, в чем проблема.
0
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
20.04.2014, 10:33
http://www.gnu.org/software/cf... mmand.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.04.2014, 10:33
Помогаю со студенческими работами здесь

Посчитать и вывести на экран количество слов в файле, первую половину слов вывести в другой файл
3. Открыть файл, имя которого задается с клавиатуры. Посчитать и вывести на эк-ран количество слов в этом файле. Первую половину слов...

Количество слов в файле!
Как реализовать цикл по подсчёту кол-ва слов в файле?:help:

Количество слов в файле
Добрый день! Есть текстовый файл. Пример: Фамилия;Имя;Отчество;Страна;Национальность;Лет ...

Количество слов в файле. С++
Здравствуйте. Требуется посчитать количество слов в файле. Искала по темам, но что ни делаю - выдаёт ошибки. Пишу строковую переменную ...

Посчитать количество слов в файле
Нужно у файле посчитать количество слов. Кажеться правильно сделал, но ответ не правильный. Где ошибка? void Ex() { const char*...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru