Консультация № 181219
11.12.2010, 15:06
60.33 руб.
0 16 2
Здравствуйте, уважаемые эксперты! Прошу Вас ответить на следующий вопрос как можно скорее.Написать нужно на Си. В Dev-C++. Прокомментируйте пожалуйста

Написать программу,которая считывает текст из файла и выводит на экран только строки ,не содержащие двузначных чисел.
Оформить в виде функций законченные последовательности действий.Все необходимые данные для функций должны передаваться им в качестве параметров.Использование глобальных переменных в функциях не допускается.

Обсуждение

Неизвестный
11.12.2010, 21:12
общий
13.12.2010, 20:46
это ответ
Здравствуйте, Olgaa!

[b]Обратите внимание:
Для компиляции проекта необходима опция -std=c99.
Обработка исключительных ситуаций не предусмотрена.
[/b]


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

FILE *f;
char *str;
int file_size;

int check_two_digits(char *s)
{
for (int i=1; i<strlen(s); i++)
{
if (((s[i]>='0')&&(s[i]<='9'))&&
((s[i-1]>='0')&&(s[i-1]<='9')))
return(1);
}
return(0);
}

int main(int argc, char *argv[])
{
if (argc < 2)
{
printf ("Не указан файл\n");
return(1);
}

f=fopen(argv[1],"rb");
if (f)
{
fseek(f,0,SEEK_END);
file_size=ftell(f);
rewind(f);
str=(char *)malloc(file_size);

while((fgets(str,file_size,f))!=NULL)
{
if (check_two_digits(str)==0) printf("%s",str);
}

free(str);
fclose(f);
}

return(0);
}
Неизвестный
12.12.2010, 12:40
общий
Задача не работает
Неизвестный
12.12.2010, 15:00
общий
это ответ
Здравствуйте, Olgaa!
Программа. C. Компилировал GCC.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define DIGITS 2

void error(const char* const msg);
char* getLine();
bool isValidLine(const char* line);

/*
*
*/
int main()
{

char* line = 0;

// Читаем построчно
while (line = getLine())
{
// Если строка удовлетворяет условию
if (isValidLine(line))
{
printf("%s", line);
}

// Освободим память
free(line);
}

return EXIT_SUCCESS;
}

// Выводит сообщение об ошибке

void error(const char* const msg)
{
fprintf(stderr, "%s\n", msg);
exit(EXIT_FAILURE);
}

// Читает строку

char* getLine()
{
// Буфер
char buffer[BUFSIZ];
char* result = 0, *tmp = 0;
size_t size = 0;

while (true)
{
// Читаем
if (!fgets(buffer, sizeof (buffer), stdin))
{
// Если конец файла
if (feof(stdin))
{
return result;
}
else
{
error("Ошибка ввода/вывода");
}
}

// Добавим к длине строки
size += strlen(buffer);

// Попытка выделить память
if (!(tmp = realloc(result, size + 1)))
{
error("Не могу выделить память");
}

// Копируем из буфера
if (!result)
{
strcpy(tmp, buffer);
}
else
{
// Присоединяем, если не первый раз
strcat(tmp, buffer);
}

result = tmp;

// Если прочли до конца строки, то выход
if (size && result[size - 1] == '\n')
{
return result;
}
}
}

// Проверка строки на соответствие условию

bool isValidLine(const char* line)
{
if (!line)
{
return false;
}

size_t cnt = 0;
// Идем посимвольно
while (*line)
{
// Если цифра
if (isdigit(*line++))
{
// Увеличим счетчик
++cnt;
}
else
{
// Если не цифра и к-во цифр совпало с условием
if (cnt == DIGITS)
{
break;
}
// Иначе обнулим счетчик
cnt = 0;
}
}
return cnt != DIGITS;
}

Пример исходного файла:
Код:
> cat ./test.txt 
valid string
not valid string 12
123456
11

Пример работы:
Код:
> ./181219 < test.txt 
valid string
123456


Программа читает данные из стандартного потока вода(stdin) и выводит на стандартный поток вывода(stdout). Для того, чтоб использовать ее для обработки любого файла необходимо использовать перенаправление ввода/вывода. Т.е запускать так: "имя программы" < "входной файл". Что и продемонстрировано в примере.
5
Неизвестный
12.12.2010, 20:15
общий
Чье решение не работает: мое или Micren?
Что именно не работает и как это проявляется, можно подробней?
Неизвестный
12.12.2010, 22:26
общий
Ваша программа точно не работает. Т.к. она и 123 воспримет как 2х значное число. Да и стандарт С99 далеко не у всех компиляторов выбирается по умолчанию. А именно ему Ваша программа соответствует.

Кстати. А если файл будет, скажем, 4Гб, нормально Ваша программа отработает? Кроме того, в разных ОС, не все, что кажется файлом имеет размер.
Неизвестный
13.12.2010, 06:35
общий
Отвечу по-порядку:
1. В задании сказано не выводить строки, не содержащие двузначных чисел. А строка "123" как раз содержит два двузначных числа "12" и "23". Здесь нужно уточнение задания.
2. В задании не указано под какой стандарт нужен код, просто сказано на С. Опять же нужно уточнение задания.
3. По поводу 4Гб, да, согласен, что для серьезных коммерческих решений, необходимо учитывать такие моменты. Но я вижу, что это обычная "лабораторная работа" и файлы для тестирования там используются небольшие.
4. Опять же по поводу открытия "не текстовых файлов" в различных ОС могу сослаться на то, что обработка данного варианта могла бы иметь место только для серьезных коммерческих решений. Здесь во-первых, указано, что из файла должен считываться текст, то есть заранее известно, что файл имеет размер и он текстовый.
давно
Старший Модератор
17042
808
13.12.2010, 07:28
общий
На будущее:
1. Комментируйте код своего ответа. Во-первых, это является правилом в данной рассылке. Во-вторых, автор вопроса об этом прямо просит.
2. Если Вы считаете, что вопрос требует уточнений, то Вы должны обратиться к автору вопроса в мини-форуме или в личном сообщении (пейджер портала) до подачи ответа.
3. Поскольку в качестве среды разработки указан Dev-C++, компилятором по умолчанию для которого является GCC, то одно из уточнений отпадает: хотя GCC и поддерживает стандарт c99, но последний не является ещё полностью совместимой реализацией и не используется по умолчанию. Т.е. Вы должны были хотя бы дать рекомендацию автору вопроса добавить в опции проекта -std=c99... Потому, собственно, она и пишет, что "Задача не работает".
Об авторе:
We have but faith: we cannot know;
For knowledge is of things we see;
And yet we trust it comes from thee,
A beam in darkness: let it grow.
-----
https://www.linkedin.com/in/andreynkuznetsov
https://www.researchgate.net/profile/Andrey_Kuznetsov11
http://www.researcherid.com/rid/K-8824-2014
Неизвестный
13.12.2010, 07:46
общий
  • 1. Хм. Интересное мнение. Но не более того. 123 логичнее считать 3х значным.
  • 2. Интересно. Какой IDE Вы пользуетесь? Чего то мне кажется(может я и неправ), что файл Ваш имеет расширение типа .cpp, .cc ...
  • 3,4. Не текстовые файлы(напр. очереди fifo в linux) можно обрабатывать точно так же как и поток. И для этого не надо писать под "коммерческое решение". Достаточно не привязываться к размеру файла. Да и не обязательно брать файл размером 4Гб. Ресурсы системы желательно экономить в любом случае.


Так же, ради интереса, потестируйте на таком файле: https://rfpro.ru/upload/3999
Неизвестный
13.12.2010, 07:55
общий
Я не буду спорить и доказывать что-то... Вы меня не убедили ни по одному пункту, задание не уточняет многих моментов, поэтому я сделал, как посчитал правильным.
Вот замечания "Андрей Кузнецов aka Dr_Andrew" действительно дельные. Учту.
Неизвестный
13.12.2010, 08:27
общий
Да я и не обязан Вас убеждать. Автор вопроса Вам в 1м посте и так написал свое мнение. Или Вы для самого себя программы пишете? Пишите качественный код и тогда не надо будет Вас ни в чем убеждать. Тем более в очевидных, для программиста, вещах.

В программе есть ошибки. Пример для теста в прошлом моем посте. Если уж и это не убеждает... То же самое по вопросу 181220. Можете исправить и выложить в мини-форуме с обращением к модераторам исправить в ответе.
Неизвестный
13.12.2010, 09:07
общий
По поводу того, что программа не работает, уже есть ответ: добавить опцию -std=c99.
На качество кода это никак не влияет.
А в прошлом посте Вы прикрепили пустой файл. У Вас крайности... либо 4Гб, либо пусто.
Давайте рассматривать реальные текстовые файлы.
Неизвестный
13.12.2010, 09:17
общий
Ну файл размером 1байт это не пустой файл. Да и логика мне непонятна. Т.е. виноват в ошибках "пустой"("не реальный") файл, а не программист.
Цитата: 351298
У Вас крайности... либо 4Гб, либо пусто.
У меня, как раз, с этим делом все в порядке.
Неизвестный
13.12.2010, 09:20
общий
Еще раз повторю, что если бы это была серьезная программа, то я бы естественно не так ее писал, с обработкой всех возможных ситуаций. А здесь это ни к чему! И преподаватель студенту не будет в данном случае на вход программе подавать файл (не текстовый) размером 16 байт.
Неизвестный
13.12.2010, 09:24
общий
Цитата: 351298
с обработкой всех возможных ситуаций.
Каких ситуаций? Ситуация там одна: неверно считается размер буфера.

И чем это мой файл не соответствует условию задачи?

Цитата: 351298
И преподаватель студенту не будет в данном случае на вход программе подавать файл (не текстовый) размером 16 байт.
Откуда знаете? Я бы подал. Вот попадется такой противный как я и что тогда? Тем более файл текстовый. Содержит LF.

Кстати. Подпись у Вас хорошая("Внимательное изучение каждого вопроса и профессиональный подход к ответам").
Неизвестный
13.12.2010, 19:15
общий
Многоуважаемый, Micren! Я конечно понимаю, что Вы нашли исключительные и нереальные ситуации, при которых мой код работать не будет. Я полностью согласен с Вами, что они имеют место быть. Но, по-прежнему считаю, что для реальной жизненной ситуации, а именно для лабораторной работы, этого вполне достаточно. Также могу Вас заверить, что, если понадобилось бы, я бы обработал их вполне адекватно и, заметьте, не только их, но и массу других ситуаций, которые могут возникнуть, в том числе те, которые и у Вас не учтены коде.
Неизвестный
13.12.2010, 20:43
общий
To All:
Давайте заканчивать тут спор. Продолжение если только по личной почте.
По ответу Павла Юрьевича: мы ещё до начала обсуждения здесь по личной почте договорились, что он добавит комментарии, если этого потребует спрашивающий, и в будущем будет давать комментарии. Про стандарт я не знала, потому что не работаю ни с gcc, ни с dev-c++, хотя оба видела, надеюсь, Павел Юрьевич учтёт это замечание и будет указывать подобные ньюансы в дальнейшем. По поводу обработки исключительных ситуаций - да, код не лучший, но, в принципе, вполне допустимый.
Форма ответа