21 Востаннє редагувалося shabaranskij (07.07.2016 21:26:41)

Re: Сі. Вивести вміст текстового файлу.

Надіюсь нічого не пропустив

// main.c

#include <stdio.h>
#include "rwfile.h"
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

int main(void)
{
    int work;
    string  path=NEW_STRING(512);     //    /home/lazarus/name.txt

    if (path==NULL)
    {
        printf("Error!");
        exit(0);
    }


    do
    {
        printf("Введіть шлях до файла:");
        scanf("%s",path);

        openFile(path);
        printf("\nЩоб відкрити інший документ введіть 1. Для виходу 0:");
        scanf("%i",&work);

        if (work==1)
        {
            system("reset");
        }
        else
        {
            system("reset");
            break;
        }
    }
    while(true);

        FREE(path);

    return 0;
}
// rwfile.c

#include <stdio.h>
#include <stdlib.h>
#include "rwfile.h"

int openFile(char path[])
{
  string str=NEW_STRING(SIZE);
  FILE *file;

  if (str==NULL)
      {
       printf("Error!");
       exit(0);
      }

  file=fopen(path,"r");

  if (file==NULL)
  {
      printf("Помилка. Перевірте введену адресу на помилки.");
      exit(0);
  }

  printf("#Початок\n");

  while ((fgets(str,sizeof(str),file))!=NULL)
    {
      printf("%s",str);
    }

    printf("#Кінець\n");
    fclose(file);
    FREE (str);

    return 0;
}
// rwfile.h

#ifndef RWFILE_H
#define RWFILE_H

#define SIZE 255*1024*1024
#define NEW_STRING(length) (char*)(malloc(sizeof(char)*(length)))
typedef char *string;
extern int openFile(char path[]);
#define FREE(x) (free(x))

#endif

22

Re: Сі. Вивести вміст текстового файлу.

я потім виправлю  це 

system("reset")

23

Re: Сі. Вивести вміст текстового файлу.

shabaranskij написав:
char* name=(char*)(malloc(sizeof(char)*512));
char str[]=" me";
name="Help";
strcat(name,str);

Виникає помилка. Як з'єднати два рядки?

name="Help" не копіює текст "Help" у виділений блок пам'яті, а затирає посилання на цей блок і записує в змінну name посилання на рядок "Help" (який також являє собою масив символів, але розміщений в області пам'яті, куди запис здійснювати заборонено, або ж пам'ять після останнього символа цього рядка використовується для якихось інших даних, що призводить до непередбачуваних наслідків, коли strcat туди щось дописує). Замість цього робіть strcpy(name, "Help");

Подякували: shabaranskij, leofun012

24

Re: Сі. Вивести вміст текстового файлу.

shabaranskij написав:

І пішов офтоп. Як створити тип даних string в с з такими можливостями як наприклад в java. щоб можна було додавати два рядки наприклад стрінг += стрінг2.
І чи це не повний маразм.
Чи потрібно весь час обходити такі помилки

char* name=(char*)(malloc(sizeof(char)*512));
char str[]=" me";
name="Help";
strcat(name,str);

Можливо ліпше написати

сhar a[1024];

і не паритися.

Якщо замість першого рядка буде char name[1024];, то name="Help" навіть не скомпілюється (що, втім, навіть добре — див. моє попереднє повідомлення). Решта коду (крім цих двох рядків) залишиться без змін. Заморочуватися з malloc має сенс, якщо:
1) всі ці дії відбуваються у функції, а отриманий рядок має використовуватись після її завершення (звичайний масив для цього не годиться, оскільки він розміщується в стеку, і його вміст після завершення функції затиратиметься іншими даними).
2) розмір виділеного блоку не константний, а обчислюваний (напр., можна знайти сумарну довжину всіх рядків, вміст яких буде записано в цей блок, і виділити з допомогою malloc блок відповідного розміру).
Якщо ж усі дії з name відбуваються в межах однієї функції, а його максимальний розмір задається констатним значенням, то не має значення, яким способом буде виділеного для нього пам'ять.

Подякували: shabaranskij1

25

Re: Сі. Вивести вміст текстового файлу.

Для цього

char* name=(char*)(malloc(sizeof(char)*512));
char str[]=" Help";
name="me";
str_m_cat(str,name);//замість strcat;

зробив таке

void str_m_cat(char a[],char* b)
    {
    int len=0,i=-1;
    len=strlen(a);

    do
        {
        i++;
        a[i+len]=b[i];
        }
    while(b[i]!=NULL);
    }

26

Re: Сі. Вивести вміст текстового файлу.

Ви плутаєте присвоєння вказівників із зміною вмісту рядків

char* name=(char*)(malloc(sizeof(char)*512)); //name вказує на ділянку пам'яті з 512 байт в купі
char str[]=" me"; //str вказує на 4 байти (3 знаки+ '\0') в області констант або ще десь
name="Help"; //str вказує на 5 байт в області констант, шматок в купі загубився
strcat(name,str);

//до шматка в 5 байт в константах намагаємося дописати ще 3, маємо дурню
зробіть третій рядок strcpy(name,"Help"); і все буде добре.

shabaranskij написав:

Як створити тип даних string в с з такими можливостями як наприклад в java

Це зроблено в C++. Ідея тут у тому, що операції зі string часто бувають повільнішими, ніж ви очікуєте: зокрема,
string a="A"; //умовний тип string
string b="B";
string c=a+b; //тут створюється тимчасовий об'єкт string, в нього копіюються a та b, а його значення копіюється в c
Натомість

char a[]="A";
char b[]="B";
char c[10];
strcpy(c,a);
strcat(c,b);

не запитує додаткової пам'яті, а робить точно те, що сказано.
Як із цим боротися - є кілька рішень. В Java є StringBuilder; в C++11 для цього цілу семантику переміщення придумали; автори кожної другої бібліотеки C++ роблять свій велосипед string.

Подякували: shabaranskij, leofun012

27

Re: Сі. Вивести вміст текстового файлу.

shabaranskij написав:

Для цього

char* name=(char*)(malloc(sizeof(char)*512));
char str[]=" Help";
name="me";
str_m_cat(str,name);//замість strcat;

зробив таке

void str_m_cat(char a[],char* b)
    {
    int len=0,i=-1;
    len=strlen(a);

    do
        {
        i++;
        a[i+len]=b[i];
        }
    while(b[i]!=NULL);
    }

По суті нічого не змінилося - ви так само губите пам'ять і копіюєте в області констант, просто тепер випадково це не викликає падіння програми; недоліки - ви не використовуєте стандартні strcpy і strcat, а робите свій велосипед, та порівнюєте елемент рядка (символ) з нульовим вказівником, що є абсурдом, хоч і не заборонено.

while(b[i]!='\0');
Подякували: shabaranskij1

28 Востаннє редагувалося shabaranskij (08.07.2016 09:31:51)

Re: Сі. Вивести вміст текстового файлу.

Дякую всім що знайшли час відповісти мені.  Я не розумію як навчитися ефективно кодити якщо  в книгах мало описано як правильно використовувати можливості Сі. А частіше  практикують гавнокод.
Можливо я не правильно шукаю...

29

Re: Сі. Вивести вміст текстового файлу.

Будь ласка, якщо звинувачуєте авторів якоїсь книжки в лайнокоді, то давайте пряме посилання - бо можливо, що автори якраз давали нормально, а ви щось не так зрозуміли, і це "щось" бажано уточнити.

30

Re: Сі. Вивести вміст текстового файлу.

koala написав:

Будь ласка, якщо звинувачуєте авторів якоїсь книжки в лайнокоді, то давайте пряме посилання - бо можливо, що автори якраз давали нормально, а ви щось не так зрозуміли, і це "щось" бажано уточнити.

Я не можу звинувачувати якогось автора бо не знаю його імені. Я не пам'ятаю в якій то книжці було написано що можна робити так як я писав в попередніх повідомленнях. Проблема в тому що я її переглядав online не зберігаючи її на пк. А історію я час від часу очищаю. Я зараз не хочу зачіпати тему говнокоду.

31

Re: Сі. Вивести вміст текстового файлу.

Код не мій.

#include<stdio.h>
#include<stdlib.h>
int i,j,ec,fg,ec2;
char fn[20],e,c;
FILE *fp1,*fp2,*fp;
void Create();
void Append();
void Delete();
void Display();

int main()
{
    while(1)
    {
        printf("\n\t\t##########################\n\n");
        printf("\t\tSIMPLE TEXT EDITOR\n\n");
        printf("\n\t\t##########################\n\n");
        printf("\n\n\tMENU:\n\t-----\n ");
        printf("\n\t1.CREATE\n\t2.APPEND\n\t3.OPEN A FILE\n\t4.DELETE\n\t5.EXIT\n");
        printf("\n\tEnter your choice: ");
          scanf("%d",&ec);
          switch(ec)
          {
               case 1:
                 Create();
                 break;
               case 2:
                 Append();
                 break;
               case 3:
                 Display();
                 break;
               case 4:
                 Delete();
                 break;
               case 5:
                 exit(0);
          }
     }
}
void Create()
{
     fp1=fopen("temp.txt","w");
     printf("\n\tEnter the text and press '.' to save\n\n\t");
     while(1)
     {
          c=getchar();
          fputc(c,fp1);
          if(c == '.')
          {
               fclose(fp1);
               printf("\n\tEnter the filename: ");
               scanf("%s",fn);
               fp1=fopen("temp.txt","r");
               fp2=fopen(fn,"w");
               while(!feof(fp1))
               {
                    c=getc(fp1);
                    putc(c,fp2);
               }
               fclose(fp2);
            fclose(fp1);
               break;
          }
    }
}

void Display()
{
      printf("\n\tEnter the file name: ");
      scanf("%s",fn);
      fp1=fopen(fn,"r");
      if(fp1==NULL)
      {
          printf("\n\tFile not found!");
           goto end1;
      }
      while(!feof(fp1))
      {
           c=getc(fp1);
           printf("%c",c);
      }
    end1:
          fclose(fp1);
      printf("\n\n\tPress any key to continue...");
}

void Delete()
{
      printf("\n\tEnter the file name: ");
      scanf("%s",fn);
      fp1=fopen(fn,"r");
      if(fp1==NULL)
      {
           printf("\n\tFile not found!");
      }
      else
    {
        fclose(fp1);
          if(remove(fn)==0)
          {
               printf("\n\n\tFile has been deleted successfully!");
          }
          else
           printf("\n\tError!\n");
    }
}
void Append()
{
      printf("\n\tEnter the file name: ");
      scanf("%s",fn);
      fp1=fopen(fn,"r");
      if(fp1==NULL)
      {
           printf("\n\tFile not found!");
           goto end3;
      }
      while(!feof(fp1))
      {
           c=getc(fp1);
           printf("%c",c);
      }
      fclose(fp1);
      printf("\n\tType the text and press '#' to append.\n");
      fp1=fopen(fn,"a");
      while(1)
      {
           scanf("%c",&c);
           if(c=='#')
            goto end3;
           if(c==13)
           {
                c='\n';
                printf("\n\t");
                fputc(c,fp1);
           }
           else
           {
                //printf("%c",c);
                fputc(c,fp1);
           }
      }
    end3: fclose(fp1);
}

32 Востаннє редагувалося 0x9111A (08.07.2016 14:32:43)

Re: Сі. Вивести вміст текстового файлу.

      while(!feof(fp1))
      {
           c=getc(fp1);
           printf("%c",c);
      }

:)

Взагалі код для гри "знайди якнайбільше помилок". Причому тут на будьякий смак