Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Помогите написать программу на "Си"


Автор: Эпсилон 3.1.2007, 22:13
Помогите пожалуйста написать программу на "Си", не на "С++". 

"Выравнивание строк: в тексте из N строк выровнить строки так, чтобы каждая строка имела длину 65 символов. Выравнивание произовится за счёт вставки дополнительных пробелов."

Ход действий я знаю: нужно открыть текстовый документ FILE *IN, его просто прочитать(rt), совершить над ним выравниваение с помощью цикла добавить пробелы, подсчитать длину строки, если нет 65 то ещё добавить пробелы, опять подсчитать длину строки, до тех пор пока не будет 65символов в строке, и сохранить уже в новый текстовый документ только в FILE *OUT. Но реализовать в Си коде не смог, помогите написать, взаранее спасибо.

Автор: Rockie 3.1.2007, 22:28
Цитата(Эпсилон @  3.1.2007,  22:13 Найти цитируемый пост)
 подсчитать длину строки, если нет 65 то ещё добавить пробелы, опять подсчитать длину строки

Не обязательно. 
Считываешь строку. Считаешь, сколько пробелов в строке. Если длина строки больше 65 или нет пробелов - каким-то образом обрабатываешь эту ситуацию. 

Если все нормально - считаешь, сколько нужно добавить к этим существующим пробелам:

x = (65 - длина_строки) / кол-во_пробелов_в_строке

Пишешь в OUT файл, добавляя x пробелов к уже существующим. 

ИМХО

Добавлено @ 22:30 
А вообще такая задача была и не раз, копайся в http://forum.vingrad.ru/act-Search/f-92.html


Автор: Эпсилон 3.1.2007, 23:10
Спасибо большое всё получилось, только не то, я же подсчитал сколько длина строки, а как подсчитать сколько пробелов? и если можно то как это в коде выглядит, "Си" недавно начал изучать.

Автор: _hunter 4.1.2007, 11:25
проходиш по всем элементам массива символов, если текущий символ == ' ' -- увеличиваеш счетчик на 1.
в чем тут может быть проблема -- не понимаю...

Автор: Эпсилон 4.1.2007, 15:22
Вот написал только пишет две ошибки: 
Код

#include <stdio.h>
#include <string.h>
const int LINE_LEN = 65;
void main()
{
  char text[100];
  FILE *in = fopen("text_in.txt", "rt");
  if (!in) { printf("error open text_in.txt\n"); return; }
  FILE *out = fopen("text_out.txt", "wt");
  while (fgets(text,sizeof(text),in))
  {
    int len = strlen(text);
    if (text[len-1] == '\n') text[--len] = 0;
    while (len < LINE_LEN) text[len++] = ' ';
    text[len++] = '\n';
    text[len] = 0;
    fputs(text, fout);
  }
  fclose(out);
  fclose(in);
}


Первая ошибка когда открываю файл:
Код

 FILE *out = fopen("text_out.txt", "wt");
 ( "*" светится как ошибка):
Error C:\____\zadacha.c 9: Improper use of a typedef symbol in function main
Вторая ошибка тоже в File *out:
("out" светится как ошибка):
Error C:\____\zadacha.c 9: Undefined symbol  ' out '  in function main.

Автор: frenchman 4.1.2007, 15:27
Эпсилон, 

Цитата

а как подсчитать сколько пробелов?


Код

int p = 0; // счетчик пробелов
for(int i = 0; i < SIZE; i++)
{ if(stroka[i] == " ") p++;
}


SIZE - это длина строки.

Автор: Rockie 4.1.2007, 15:44
Цитата(Эпсилон @  3.1.2007,  23:10 Найти цитируемый пост)
 а как подсчитать сколько пробелов?


Цитата(_hunter @  4.1.2007,  11:25 Найти цитируемый пост)
проходиш по всем элементам массива символов, если текущий символ == ' ' -- увеличиваеш счетчик на 1.

Код

  char* s = "Some string with some words";
  int spaces = 0, len = strlen(s);

  for(int i=0;i<len;i++)
    if(s[i]==' ') spaces++;





Автор: _hunter 4.1.2007, 15:48
студия 7.1 компилит...

Автор: Rockie 4.1.2007, 15:49
Цитата(Эпсилон @  4.1.2007,  15:22 Найти цитируемый пост)
   if (text[len-1] == '\n') text[--len] = 0;

imho это лишнее
Цитата(Эпсилон @  4.1.2007,  15:22 Найти цитируемый пост)
 while (len < LINE_LEN) text[len++] = ' ';

тут если честно, полета мысли не понял. Тебе вроде бы алгоритм дан..
Цитата(Эпсилон @  4.1.2007,  15:22 Найти цитируемый пост)
Improper use of a typedef symbol in function main

поменяй out на myOut или что-нибудь еще


Автор: Rockie 4.1.2007, 16:35
Нужно еще добавить проверки
Цитата(Rockie @  3.1.2007,  22:28 Найти цитируемый пост)
 Если длина строки больше 65 или нет пробелов - каким-то образом обрабатываешь эту ситуацию. 

ну и погрешность деления при расчете кол-ва пробелов. А так - держи, с выводом на экран.
Код

#include <stdio.h>
#include <conio.h>
#include <string.h>
const int LINE_LEN = 65;

int main()
{
  char text[80];
  FILE *in = fopen("text_in.txt", "rt");
  if (!in) { printf("error open text_in.txt\n"); return 0; }

  while (fgets(text,sizeof(text),in))
  {
     int len = strlen(text);
     int spaces = 0, addSpaces = 0;

     for(int i=0;i<len;i++)       // посчитали существующие пробелы
       if(text[i]==' ') spaces++;

     if(spaces==0) return 0;       // избегаем деления на ноль ниже

     addSpaces = (LINE_LEN - len) / spaces;

     for(int i=0;i<len;i++)
      {
        if(text[i]==' ')            // встретили пробел
         { 
             for(int j=0;j<addSpaces;j++)
                putc(' ',stdout);
         }
        putc(text[i],stdout);
      }

   }

  fclose(in);
  getch();
  return 0;
}



Автор: Эпсилон 5.1.2007, 03:21
Спасибо большоё всё работает, но нужно чтобы результат, выровненный текст, нужно записать в другой файл. А когда я добавляю FILE *out, то выходят опять те же ошибки. 

Автор: Rockie 5.1.2007, 03:36
Цитата(Эпсилон @  5.1.2007,  03:21 Найти цитируемый пост)
 А когда я добавляю FILE *out, то выходят опять те же ошибки. 

Эпсилон, по форматировнию кода видно, что out это зарезервированное слово(оно жирное). поэтому я и написал двумя постами выше  smile 
Цитата(Rockie @  4.1.2007,  15:49 Найти цитируемый пост)
поменяй out на myOut или что-нибудь еще


imho потом останется заменить 
Код

   putc(' ',stdout);

на что-нибудь вроде
Код

   putc(' ',myOut);



Автор: apook 5.1.2007, 09:28
Код

if( spaces==0 ) return 0;         // избегаем деления на ноль ниже

Если в в какой-то строке нет пробела программа благополучно завершилась
Зачем так категорично

Автор: Rockie 5.1.2007, 15:27
Цитата(apook @  5.1.2007,  09:28 Найти цитируемый пост)
Если в в какой-то строке нет пробела программа благополучно завершиласьЗачем так категорично

apook, всмысле "категорично"? Это учебный пример, в нем главное не интерфейс, а функциональность. А так - хоть мигающий ShowMessage прикручивай smile

p.s.: кстати imho этот код
Код

return 0; 

не говорит об успешном завершении программы. Просто так обычно делают.


Автор: Kuvaldis 5.1.2007, 16:15
Граждане, в свое время другие граждане целых 4 листа по этой теме списали
http://forum.vingrad.ru/index.php?showtopic=124385&kw=%E2%FB%F0%E0%E2%ED%E8%E2%E0%ED%E8%E5&hl=

Автор: apook 5.1.2007, 16:49
Сделать так:
Код

if( spaces==0 )
{
    puts( text );
    continue;
    }

Зачем такие строгости именно в учебном материале
Цитата

return 0; 

Я имелл ввиду что без ошибки, добровольно препвать программу тогда-как
она может работать и дальше. 

Автор: Эпсилон 6.1.2007, 17:29
Спасибо большое всем за помощь. Программа  работает.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)