Модераторы: Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C] Файлы 
V
    Опции темы
Гениальный123Робот
Дата 4.12.2006, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



В одном файле дан исходный текст программы на языке С, в другом – словарь ключевых слов этого языка. (33 слова)Преобразовать текст, записав все ключевые слова прописными буквами, а остальные конструкции (идентификаторы и т.д.) – строчными. 

Си
PM MAIL   Вверх
Alexeis
Дата 12.12.2006, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Не уверен, что это чистый С, но работает.
Код

#include "stdafx.h"
#include <string.h>
#include <ctype.h>

char *words[33] = {"auto","break","char","case","char","const","continue","default","do",
                "double","else","enum","extern","float","for","goto","if","int","long",
                "register","return","short","signed","sizeof","static","struct","switch",
                "typedef","union","unsigned","void","volatile","while"};

int main(int argc, char* argv[])
{
  FILE *f1, *f2;
  int i, j;
  char str[255], *aword;

  
  f1 = fopen("test.cpp", "r");
  f2 = fopen("result.cpp", "w");

  while (fscanf(f1, "%[^\n]s", str) != EOF)
  {
      getc(f1);

      for (i = 0; i < 33; i++)
      {
         aword = strstr(str, words[i]);
         while (int(aword) != 0)
         {
           for (j = 0; j < strlen(words[i]); j++)
              aword[j] = toupper(aword[j]);

           aword = strstr(str, words[i]);
         }
      }
      fprintf(f2, "%s\n", str);str[0] = '\0';
  }
  
  fclose(f1);
  fclose(f2);


    return 0;
}


Это сообщение отредактировал(а) alexeis1 - 12.12.2006, 15:17


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Гениальный123Робот
Дата 12.12.2006, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



Цитата(alexeis1 @ 12.12.2006,  15:12)
Не уверен, что это чистый С, но работает.

Очень благодарен. Дай пожму твою руку! Выручил. 

Только еще попрошу чуток пояснить хотя бы ключевые моменты:
1. Строка 1 - что это за инклюд? Для чего?... Точнее что конкретно в нем содержится важного для нас.
2. Ну и сам алгоритм:  25 - 32 строки

Остальное вроде все понятно. Кстати, красивое решение. Простое. Даже я почти все понял  smile  

СПАСИБО

Это сообщение отредактировал(а) Гениальный123Робот - 12.12.2006, 19:21
PM MAIL   Вверх
Alexeis
Дата 12.12.2006, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Цитата(Гениальный123Робот @  12.12.2006,  19:15 Найти цитируемый пост)
1. Строка 1 - что это за инклюд? Для чего?... Точнее что конкретно в нем содержится важного для нас.

 Это специальный заголовок в Visual C++ в данном случае он вообще пустой, но обычно требуется компилятором.
Код

  f1 = fopen("test.cpp", "r"); //исходный файл
  f2 = fopen("result.cpp", "w");//файл куда записывается результат


Код

  while (fscanf(f1, "%[^\n]s", str) != EOF) 
  {
      getc(f1);

читаем очередную строку из фала  до маркера конца строки, формат "%[^\n]s" говорит что в строку включаются все символы кроме символа конца строки. Когда достигаем конца строки результат функции равен EOF. getc(f1); - считывает из файла сам маркер конца строки.
Код

 for (i = 0; i < 33; i++) //ищем в строке каждое из ключевых слов
      {
         aword = strstr(str, words[i]); //ищем подстроку (ключевое слово), если нашли то результат адрес
                                                        //указатель на начало этой подстроки
         while (int(aword) != 0)          //если нет то результат NULL (в С- это вроде как 0)
         {
           for (j = 0; j < strlen(words[i]); j++) //поскольку знаем начало то переводим символы в верхний регистр
              aword[j] = toupper(aword[j]);//приведение символа к верхнему регистру.
           aword = strstr(str, words[i]); //но в строке это ключевое слово может повторяться, потому ищем 
         }//до тех пор пока находим, т.е. как только aword = 0 цикл while прервется и начнется поиск другого ключевого слова
      }


Код

 fprintf(f2, "%s\n", str);str[0] = '\0'; //записываем в файл всю строку целиком и символ конца строки.
//Присвоение нулевому символу значение '\0' обязательно поскольку если в первом файле идет серия //пустых строк, то содержимое str (fscanf - не меняет содержимое строки) остается неизменным и в //результирующий файл попадут дубликаты предыдущей строки.


Код

  fclose(f1);//закрытие файлов.
  fclose(f2);


Ну что ощутили прелести программирования на паскале  smile, все выбранные функции являются аналогами паскалевских.
 f1=fopen("test.cpp", "r");         - assign(f1, 'test.cpp');reset(f);
 f2 = fopen("result.cpp", "w");- assign(f2, 'test.cpp'); rewrite(f);
fscanf(f1, "%[^\n]s", str); getc(f1); - Readln(f1, s);
 fprintf(f2, "%s\n", str);                   - Writeln(f2, s);
aword = strstr(str, words[i]); - pos(words[i], str);
aword[j] = toupper(aword[j]); - aword[j] := upCase(aword[j]);



--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dov
Дата 12.12.2006, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 50
Всего: 88



Цитата(alexeis1 @  12.12.2006,  14:12 Найти цитируемый пост)
Не уверен, что это чистый С, но работает.

alexeis1, работать будет, но неправильно.  smile Вернее, не совсем правильно. Объясню почему. Если в программе будут идентификаторы такого вида, например: union_sovietic, autoService или, даже, printf(), то будет выведено: UNION_sovietic, AUTOService, prINTf().  smile 


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Alexeis
Дата 13.12.2006, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Dov, Ну если быть до конца строгим, то задача намного сложнее, я делал подсветку синтаксиса, и знаю, что это такое и знаю, что по хорошему тут без регулярных выражений не обойтись.
  Скажем тот же while может быть таким while (), а может таким while() или case : case: или case:while() или i = 5; continue или i = 5;continue, кроме того разделителем может выступать не пробел а знак табуляции. Текст в комментариях не типа // или /**/ не является ни идентификатором ни ключевым словом, а также текст в строках и а в строках еще могут встречаться кавычки которые могут означать конец строки а могут просто быть частью текста, аналогично и с комментами, в них могут содержаться другие комменты, а знак типа коммента может попадать еще и в строку (просто так), а есть текст еще и содержит ошибки так вообще усложняется т.д. и т.п. на врядли это все имелось ввиду когда просили сделать учебный пример. Нормально решенная задача может элементарно вырасти до 1000 строк и более.   
  Желаете? Пишите. У меня на решение задачи подсветки синтаксиса ушел не один день!


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 13.12.2006, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Не блин smile погорячился всего-то 530 строк на делфи, и без регулярок  smile, но правда используя высокоразвитые средства делфи, а не низкоуровневый С. Не тут точно вилы  smile . Такой функционал переделать на С не осилю.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Dov
Дата 13.12.2006, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 50
Всего: 88



alexeis1, чего ты так кипятишься? Здесь речь не о подсветке синтаксиса, а о том, что ф-ция strstr() не корректно находит ключевые слова. Как этого избежать? Если тебе это интересно, то можешь посмотреть эту тему. 


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Alexeis
Дата 13.12.2006, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Dov, хорошо допустим этот баг исправим, но тогда все равно программа будет на это
Код

{
  char *c = "... while ...."

 // break 

/* return value
   x 
*/
// или еще так 

  char *c = ""... while .... " 
}


давать вот это

Код

{
  CHAR *c = "... WHILE ...."

 // BREAK 

/* RETURN value
   x 
*/
// или еще так 

  CHAR *c = ""... WHILE .... " 
}


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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Oleg_Ci
Дата 13.12.2006, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Friend
**


Профиль
Группа: Участник
Сообщений: 485
Регистрация: 28.5.2006
Где: Новосиб.обл.

Репутация: 25
Всего: 30



прожка посложновастей.

сроку ->         char *words[33] = {"auto","break",
преобразует -> CHAR *words[33] = {"AUTO","BREAK",

но в этой строке оставляет в покое -> int
-> CHAR *c = "inti";
Код

#include <stdio.h>
#include <string.h>
#include <ctype.h>
    
//_________ MAIN_________________
int main(int argc, char *argv[])
{
    char *words[33] = {"auto","break","char","case","char","const","continue","default","do",
                "double","else","enum","extern","float","for","goto","if","int","long",
                "register","return","short","signed","sizeof","static","struct","switch",
                "typedef","union","unsigned","void","volatile","while"};

    FILE *f1, *f2;
    int i, j;
    char str[255], *begin, *end;
    char bad[] = ",./()[]{}\"\';`<>\\ \t\r"; // симолы разделители

    char *c = "inti";
      
    f1 = fopen("test.cpp", "r");
    f2 = fopen("result.cpp", "w");

    while (fscanf(f1, "%[^\n]s", str) != EOF)
    {
        getc(f1);
        end = str;
        while ( *end ){ // пока строка не прочитана
            for( begin = end; strchr( bad, *begin ) && *begin; begin++ ); // поис начала токена
            if( !*begin ) break; // если конец строки то выходим из цикла
            for( end = begin; !strchr( bad, *end ) && *end; end++ ); // поиск конца токена
            for (i = 0; i < 33; i++){ // перебираем ключевые слова - массива words
                if( end - begin != (int)strlen( words[i] ) ) continue; // длинна слов совпадает ?
                for( j=0; begin+j != end && words[i][j] == *( begin +j ); j++ ); // проверка символов
                if( begin+j == end ) // если достигли конца слова то слова равны
                    for ( j = 0; j < (int)strlen(words[i]); j++ ) // и делаем слово прописным
                        begin[j] = toupper(words[i][j]);
            }
        }
        fprintf( f2, "%s\n", str );
        str[0] = '\0';
    }
    fclose(f1);
    fclose(f2);

    getchar();
    return 0;
}

PM MAIL   Вверх
Dov
Дата 13.12.2006, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 50
Всего: 88



Ладно, alexeis1, попробую объяснить тебе это по-другому. Просто ты путаешь подсветку синтаксиса(реальную задачу) с простой учебной программой. В этой программе отделение (якобы) ключевых слов какого-то языка от (якобы)  идентификаторов - это чистая условность, придуманная каким-то преподом. Вот представь себе, что препод переформулировал задачу и теперь она звучит так. 
(пишу это просто для наглядности) 
Цитата
В одном файле дан исходный текст романа "Война и мир", в другом – список действующих лиц романа (туева хуча персонажей). Преобразовать текст, записав имена героев романа(встречающиеся в именительном падеже ед.числа) прописными буквами, а всё остальное  – строчными. 

Код
char *words[туева хуча персонажей] = {"андрей","наташа","пьер", ...}

Так вот. Если где-то в тексте встретится такое: "Робеспьер и сыновья." (спокойно, это для примера) или там встретится кто-то с фамилией, скажем, андрейченко, то сам понимаешь... Пощады от препода не жди.  smile Ну, а дальше, как хотите. Я своё слово сказал.  smile  





--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Гениальный123Робот
Дата 18.12.2006, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



alexeis1 , 
1. Unable to open include file 'STDAFX.H'.
2. В строке 44 ошибка о двух нигде не использующихся параметрах (argc и argv). Я конечно понимаю, можно их убрать, но не пострадает ли программа...?
3. Чего у тебя нет #include <stdio.h> в программе? Забыл, наверное, увлекшись ;)

Олег4, 
спасибо, сейчас протестю твое детище... ;)
PM MAIL   Вверх
Гениальный123Робот
Дата 18.12.2006, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 2.1.2006

Репутация: нет
Всего: нет



Олег, слушай, а как там точно адрес файлов прописать? Вот так, как ты написал, это подразумевает какой-то адрес? Может в том же каталоге...? 
PM MAIL   Вверх
Alexeis
Дата 18.12.2006, 21:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Гениальный123Робот, я в сях плохо разбираюсь, компилил в Visual C++, там этот код откомпилировался без ошибок...


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Oleg_Ci
Дата 19.12.2006, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Friend
**


Профиль
Группа: Участник
Сообщений: 485
Регистрация: 28.5.2006
Где: Новосиб.обл.

Репутация: 25
Всего: 30



Гениальный123Робот, файлы должны-быть в томже коталоге где и сама программа ( или исходники )
Вообще-то программа открывает один файл в котором находится тескт на языке 'C', и второй создаёт для записи туда результата, а ключевые слова программа НЕЧИТАЕТ из файла, а берёт из массива -  char *words[33], который 
alexeis1, изобрёл.

Такие-вот дела... smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0802 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.