Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Ошибка при копировании строк

Автор: Excell
Дата сообщения: 27.01.2005 18:05
Вот програмка, что-то не хочет копировать стоки из одной области в другую:

Код: #include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int i;
char *p1="Bla-bla-bla";
char *p2;
if (NULL == (p2=malloc(strlen(p1)+1)))
{
printf ("It's enough of memory!");
getch();
exit(1);
}
for (i=0;i<strlen(p1);i++)
*(p2+i)=*(p1+i);
printf ("%s\n",p2);
free(p2);
getch();
}
Автор: akaGM
Дата сообщения: 27.01.2005 18:15
VC 7.0


Код:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int i;
char *p1="Bla-bla-bla\0"; //на всякий случай
char *p2 = NULL; // --"--"--


if (NULL == (p2=(char*)malloc(strlen(p1)+1)))
{
printf ("It's enough of memory!");
getch();
exit(1);
}

/* на фиг?
for (i=0;i<strlen(p1);i++)
*(p2+i)=*(p1+i);

p2[strlen(p1)] = 0; //тем более, что без этой строки неверно! или в цикле надо ставить i<=strlen(p1)
*/


strcpy(p2, p1);

printf ("%s\n",p2);
free(p2);
getch();
}
Автор: Excell
Дата сообщения: 27.01.2005 18:33
akaGM

Цитата:
if (NULL == (p2=(char*)malloc(strlen(p1)+1)))

это типа принудительно делаем char*?

Цитата:
на фиг?

просто, намеренно не использовал strcpy

Цитата:
а что за компилятор?

MS VC++6
Автор: akaGM
Дата сообщения: 27.01.2005 18:36

Цитата:
это типа принудительно делаем char*?

это типа хороший тон, кот. иногда помогает избежать ошибок...


Цитата:
просто, намеренно не использовал strcpy


ну тогда юзай красный код в комментах...

под VC 6.0 тоже все ок...
Автор: WiseAlex
Дата сообщения: 28.01.2005 11:28
Excell

Цитата:
компилятор ругается так:
Цитата:cannot convert from 'void *' to 'char *'

файл имеет расширение .cpp и программа компилится как cpp вот компилятор и ругается - С++ типизированный язык. Или привидение типов или поставь расширение файла .с и компилируй как С или используй new
Автор: Excell
Дата сообщения: 29.01.2005 23:16
akaGM
да, спасибо, я красные и ипользовал, все уже работает
спасибо, за подсказки..
Автор: Excell
Дата сообщения: 30.01.2005 21:11
Вот у меня такой вопрос. Вот прога, она делает в текстовых файлах табуляцию каждой строчки.
Нужно указать 3 параметра при запуске вида: program.exe file2.txt file2.txt
первый - прога, второй - файл, которого табулируем, третий - в который..
так вот, если выходной файл не существует, то вылетает ошибка, а если он есть, все ок.
вот исходник:

Код: #include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define size 200
void main (int a, char *b[])
{
char buf[size];
int notexist,ans;
FILE *in,*out;
if (a<3)
{
puts ("You must insert 3 parameters in command line at least!");
getch();
exit(1);
}
in=fopen(b[1],"rb");
if (in == NULL)
{
printf ("File %s is not exist!",b[1]);
getch();
exit(1);
}
notexist=0;
if ((out=fopen(b[2],"rb")) == NULL)
{
notexist=1;
fclose(out);
}
if (notexist)
{
out=fopen(b[2],"wb");
}
else
{
printf ("Delete %s, Y/N?",b[2]);
ans=getchar();
if (ans == 'Y' || ans == 'y')
out=fopen(b[2],"wb");
else exit(1);
}
buf[0]='\t';
while (fgets(buf+1,size-1,in) != NULL)
fputs(buf,out);
fclose(in);
fclose(out);
getch();
}
Автор: akaGM
Дата сообщения: 30.01.2005 21:38
фиг его знает...
навскидку вот так надо поправить:

Код:
Код:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define size 200
void main (int a, char *b[])
{
char buf[size];
int notexist,ans;
FILE *in,*out;
if (a<3)
{
puts ("You must insert 3 parameters in command line at least!");
getch();
exit(1);
}
in=fopen(b[1],"rb");
if (in == NULL)
{
printf ("File %s is not exist!",b[1]);
getch();
exit(1);
}
notexist=0;
if ((out=fopen(b[2],"rb")) == NULL)
{
notexist=1;
//fclose(out); на фиг его закрывать -- его же нет?
}
if (notexist)
{
out=fopen(b[2],"wb");
}
else
{
printf ("Delete %s, Y/N?",b[2]);
ans=getchar();
if (ans == 'Y' || ans == 'y')
out=fopen(b[2],"wb");
else exit(1);
}
buf[0]='\t';
while (fgets(buf+1,size-1,in) != NULL)
fputs(buf,out);
fclose(in);
fclose(out);


printf("\ndone!\npress a key..."); //не забывай сообщать, а то ждешь, ждешь... гы


getch();
}

Автор: MoKC0DeR
Дата сообщения: 30.01.2005 22:04

Цитата:


Код:
if ((out=fopen(b[2],"rb")) == NULL)
{
notexist=1;
//fclose(out); на фиг его закрывать -- его же нет?
}

Автор: akaGM
Дата сообщения: 30.01.2005 22:35
согласен...

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

Код:
...
notexist=0;

notexist = ((out=fopen(b[2],"rb")) == NULL);

if (notexist)
{
out=fopen(b[2],"wb");
}
else
{
fclose(out);
printf ("Delete %s, Y/N?",b[2]);
ans=getchar();
if (ans == 'Y' || ans == 'y')
out=fopen(b[2],"wb");
else exit(1);
}
Автор: Excell
Дата сообщения: 31.01.2005 08:17
akaGM
MoKC0DeR
ла, все ок! работает на ура!
я тоже думал, что что-то не тк с fclose, ибо отладка на него посылала
Автор: akaGM
Дата сообщения: 31.01.2005 14:21
тогда держи еще один удар ака критику...

юзабилити или хороший стиль...


Код: puts ("You must insert 3 parameters in command line at least!");
Автор: Excell
Дата сообщения: 01.02.2005 09:24
akaGM

Цитата:
и параметров коммандной строки получается 2, а не 3...

ну тогда на этот счет у меня есть такой аргумент (программа выполняет такую же операцию, но только во входной файл):

Код:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define size 200
void main (int a, char *b[])
{
char buf[size];
int act;
FILE *in, *tmp;
if (a<2)
{
puts("You must insert 2 parameters in command line at least!");
getch();
exit(1);
}
in=fopen(b[1],"r+b");
if (in == NULL)
{
printf ("File %s is not exist!",b[1]);
getch();
exit(1);
}
tmp=tmpfile();
buf[0]='\t';
while (fgets(buf+1,size-1,in) != NULL)
fputs(buf,tmp);
rewind(in);
rewind(tmp);
do
{
act=fread(buf,1,size,tmp);
fwrite(buf,1,act,in);
}
while (act == size);
fclose(in);
fclose(tmp);
puts ("Operation finished successfully!");
getch();
}


Автор: akaGM
Дата сообщения: 01.02.2005 15:12
я не понял, аргумент чего?

параметрами (аргументами) коммандной строки называюся параметры (гы), которые передаются в программу...
сама программа (имя исполнимого файла) при этом считается аргументом_номер_0, но не является параметром -- так просто принято считать...
Автор: Excell
Дата сообщения: 01.02.2005 21:28
akaGM

Цитата:
сама программа (имя исполнимого файла) при этом считается аргументом_номер_0, но не является параметром -- так просто принято считать...

все, понял. о чем ты...
кста, вот еще посмотри прогу, что-то не компилится он а у меня, застревает, на красном моменте, она выводит на экран слова в алфавитном порядке.

Код: #include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define size 200
void sort (char *, int);
void main (int argc, char *argv[])
{
char buf[size], *str[100];
int i,num;
FILE *in;
if (argc<2)
{
puts("Слишком мало параметров!");
getch();
exit(1);
}
in=fopen(argv[1],"r+b");
if (in == NULL)
{
printf ("File %s is not exist!",argv[1]);
getch();
exit(1);
}
i=0;
while (fgets(buf,size-1,in) != NULL)
{
str[i]=(char*)malloc(strlen(buf)+1);
strcpy(str[i],buf);
i++;
}
i=num;
sort(*str[],i);
for (i=0;i<num;i++)
printf ("%s",str[i]);
getch();
}
void sort (char *s[], int n)
{
char *tmp;
int i,j,mm;
for (i=n-1;i>=1;i--)
{
mm=0;
for (j=1;j<=i;j++)
if (strcmp(s[j],s[mm])>0)
mm=j;
tmp=s[i];
s[i]=s[mm];
s[mm]=tmp;
}
}
Автор: akaGM
Дата сообщения: 01.02.2005 22:03
ну смотри внимательнее на варнинги и ошибки во время компиляции...


Код:
void sort (char *, int);
void sort (char *s[], int n);
Автор: Excell
Дата сообщения: 02.02.2005 09:11
akaGM

Цитата:
все зависит от
твоего определения sort()...

sort должна принимать массив указателей
а как тогда нужно обозначить прототип?
void sort (char *[], int)
так что ли?

Добавлено:
ничего не вышло
довольно трудно разобраться с этими указателями, но очень мощные они...
Автор: nobody2
Дата сообщения: 02.02.2005 11:12
У тебя ж есть массив указателей:

Код: void main (int argc, char *argv[])
Автор: akaGM
Дата сообщения: 02.02.2005 13:20
правильно...
массив указателей
proc (char * s[]);
только в объявлении!
а в вызове -- proc(s) (сам массив)

говорю ж:
следи за варнингами!


Код:
warning C4700: local variable 'num' used without having been initialized
Автор: Excell
Дата сообщения: 02.02.2005 15:26
akaGM
ой, точно...
надо же num=i;
конечно!!!
спасибки

Добавлено:
что-то я ковыряюсь и ковыряюсь, а сортировка, что-то не работает и не работает, прога печатает слова на экран, но не отсортированные, вот я другую прогу написал, с использование указателя на функцию, результат тот же

Код: #include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define size 200
void sort (char *[], int, int (*cmp)(char *, char *));
int cmplen (char *, char *);
void main (int argc, char *argv[])
{
char buf[size], *str[100];
int i,num;
FILE *in;
if (argc<2)
{
puts("Слишком мало параметров!");
getch();
exit(1);
}
in=fopen(argv[1],"r+b");
if (in == NULL)
{
printf ("File %s is not exist!",argv[1]);
getch();
exit(1);
}
i=0;
while (fgets(buf,size-1,in) != NULL)
{
str[i]=(char*)malloc(strlen(buf)+1);
strcpy(str[i],buf);
i++;
}
num=i;
sort(str,i,&cmplen);
for (i=0;i<num;i++)
printf ("%s\n",str[i]);
getch();
}
void sort (char *s[], int n, int (*cmp)(char *, char *))
{
char *tmp;
int i,j,mm;
for (i=n-1;i>=1;i--)
{
mm=0;
for (j=1;j<=i;j++)
if ((*cmp)(s[j],s[mm])>0)
mm=j;
tmp=s[i];
s[i]=s[mm];
s[mm]=tmp;
}
}
int cmplen(char *s1, char *s2)
{
return (strlen(s1)-strlen(s2));
}
Автор: akaGM
Дата сообщения: 02.02.2005 21:27
почитай о том как работают библиотечные сортировки
qsort, например

функция сравнения возвращает три значения:
-1 == первое "меньше" второго
0 == "элементы сравнения" "равны"
+1 == первое "больше"

где "меньше"/"больше" в твоих терминах сравнения...
Автор: nobody2
Дата сообщения: 03.02.2005 11:31
Не мучайся, используй STL.
Чтение по словам:

Код:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>

int main(int argc, char* argv[])
{
using namespace std;

if (argc < 2)
{
cout << "Sorting string from file.\n\nUSAGE: test <filename>\n";
return 1;
}

ifstream in(argv[1]);
istream_iterator<string> bof(in), eof;
vector<string> buf(bof, eof);
sort(buf.begin(), buf.end());

copy(buf.begin(), buf.end(), ostream_iterator<string, char>(cout, "\n"));

return 0;
}
Автор: akaGM
Дата сообщения: 03.02.2005 14:09
да можно не мучиться и вообще ничего не делать...
все уже кем-то где-то и гораздо лучше сделано...
ну да ладно, это философия...

а вот практический совет...

берешь и подключаешь стандартную сортировку...
если все работает как надо, то ищешь ошибки в реализации
своего сорта...
если ничего не работает, то смотришь на свой оставшийся код
вне сортировки, который готовит последней данные...
Автор: nobody2
Дата сообщения: 03.02.2005 15:42

Цитата:
да можно не мучиться и вообще ничего не делать...
все уже кем-то где-то и гораздо лучше сделано...
ну да ладно, это философия...


Это не философия, а суровая правда жизни

Нефиг велосипед изобретать, все равно с таким уровнем знаний и опыта ниче лучше самоката не получится.

Сначала надо научиться пользоваться СТАНДАРТНЫМИ (т.е. включенными в стандарт ansi/iso/iec 14882:2003) инструментами.
Автор: akaGM
Дата сообщения: 03.02.2005 15:51

Цитата:
Сначала надо научиться пользоваться СТАНДАРТНЫМИ

это техника...
этому и бибизяну можно научить...
а вот мыслить, иметь методу и осмысленный подход (что, кстати, пригодится
не только в программировании)...

кста, системный анализ гораздо выше котируется в мире нежели кодинг...
Автор: nobody2
Дата сообщения: 03.02.2005 17:39

Цитата:
это техника

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


Цитата:
кста, системный анализ гораздо выше котируется в мире нежели кодинг

кто бы спорил!
Вот только ни один нормальный аналитик не будет систему с нуля строить. За основу всегда берутся некоторые паттерны.
Автор: akaGM
Дата сообщения: 03.02.2005 18:05

Цитата:
это скорее набор основных понятий, без которых мысли похожи на бред.

это уже третий раз, когда меня здесь обвиняют в бреде...
в этом случае основное понятие -- знание интерфейса функи сорт (в нашем примере), т.е.
_что_ она умеет делать... а отнюдь не _как_...


Цитата:
Вот только ни один нормальный аналитик не будет систему с нуля строить. За основу всегда берутся некоторые паттерны.

ну а паттерны, конечно, -- необходимая данность этого мира... сами собой появились...
и никто не занимался обобщением и превращением их в "паттерны"...

Автор: Excell
Дата сообщения: 03.02.2005 18:20
akaGM
вот я использовал стандартную функцию qsort, результат ТОТ ЖЕ что и моей проги..т.е вывод на экран, без сортировки!

Код:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define size 200
int pstrcmp (const void*, const void*);
void main (int argc, char *argv[])
{
char buf[size], *str[100];
int i,num;
FILE *in;
if (argc<2)
{
puts("Слишком мало параметров!");
getch();
exit(1);
}
in=fopen(argv[1],"r+b");
if (in == NULL)
{
printf ("File %s is not exist!",argv[1]);
getch();
exit(1);
}
i=0;
while (fgets(buf,size-1,in) != NULL)
{
str[i]=(char*)malloc(strlen(buf)+1);
strcpy(str[i],buf);
i++;
}
num=i;
qsort (str,i,sizeof(char*),pstrcmp);
for (i=0;i<num;i++)
printf ("%s\n",str[i]);
getch();
}
int pstrcmp (const void *p1, const void *p2)
{
return (strcmp(*(char**)p1,*(char**)p2));
}

Автор: nobody2
Дата сообщения: 03.02.2005 18:31

Цитата:
это уже третий раз, когда меня здесь обвиняют в бреде...

"Ничего личного, бизнес есть бизнес" (с) не_поню_кто


Цитата:
в этом случае основное понятие -- знание интерфейса функи сорт (в нашем примере), т.е.
_что_ она умеет делать... а отнюдь не _как_...

Я не в коей мере не борюсь за то, чтобы рассматривать стандартные алгоритмы как "черный ящик" - знать, что подать на вход, и что в результате получится на выходе, и больше ничего.

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

Если нужно узнать, "в целях повышения образованности" (с) п.Печкин, как работает тот или иной алгоритм, то надо просто об этом и спросить или сделать предположение.

ИМХО, все конечно, ИМХО...
Автор: akaGM
Дата сообщения: 03.02.2005 18:34
Excell
мне повторять?

Цитата:

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


Цитата:

почитай о том как работают библиотечные сортировки
qsort, например

функция сравнения возвращает три значения:
-1 == первое "меньше" второго
0 == "элементы сравнения" "равны"
+1 == первое "больше"

где "меньше"/"больше" в твоих терминах сравнения...


хотя в последнем я могу и ошибаться насчет возвращаемого значения функции...


Добавлено:
nobody2

Цитата:

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

...что бывает иногда очень и очень полезно во всех отношениях...
особенно на этапе обучения...

Добавлено:


Код:
НАЗВАНИЕ
qsort - упорядочивает массив

СИНТАКСИС
#include <stdlib.h>

void qsort(void *base, size_t nmemb, size_t size,
int(*compar)(const void *, const void *));

ОПИСАНИЕ
Функция qsort() упорядочивает массив из nmemb элементов
размером size. Аргумент base указывает на начало массива.

Содержимое массива располагается по возрастающему
принципу, согласно функции сравнения, указанной в
параметре compar и имеющей два аргумента (сравниваемые
элементы массива).

Функция сравнения должна возвращать целое число меньше,
больше нуля или равное ему, если первый аргумент,
соответственно, меньше, больше второго или равен ему. Если
два члена массива равны, то порядок их расположения в
массиве не определен.

Страницы: 12

Предыдущая тема: очистка базы данных firebird


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.