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

» Помощь по СИ

Автор: Infection
Дата сообщения: 19.01.2005 18:02
я чет понять не могу некоторые вещи
во имеем код, взятый из книги Кернигана и Ритчи


Код:
#include <stdio.h>
#define MAXLINE 1000

int getline(char s[], int lim);
void copy(char to[], char from[]);

main()
{
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];

max = 0;
while ((len = getline(line,MAXLINE)) > 0)
{
if (len > max)
{
max = len;
copy(longest,line);
}
}
if (max > 0)
{
printf("%s", longest);
}
return 0;
}

int getline(char s[], int lim)
{
int c, l;
for (l = 0; l < lim-1 && (c = getchar()) != EOF && c != '\n'; ++l) {
s[l] = c;
}

if (c == EOF) {
return 0;
}

if (c == '\n')
s[l] = c;
++i;

s[l] = '\0';

return l;
}

void copy(char to[], char from[])
{
int l;

l = 0;
while ((to[l] = from[l]) != '\0')
++l;
}

Автор: Infection
Дата сообщения: 23.01.2005 10:37
объсяните плиз кто-нить область видимости переменной, которую передают из функции в функцию
Автор: KADABRA
Дата сообщения: 23.01.2005 11:02
Infection

Цитата:
а также каким образом мы получаем longest?


Цитата:
char longest[MAXLINE];



Цитата:
область видимости переменной, которую передают из функции в функцию

Переменная имеет область видимости функции, в которую она передана, как аргумент; и область видимости блока (ограниченого { } ), в которой она объявлена.
Автор: Infection
Дата сообщения: 23.01.2005 13:15
KADABRA,
как я понимаю

char longest[MAXLINE];

объявляет только о существовании переменной, точно также как в perl

use strict;
my @longest;

а я не могу я понять в си как мы получаем значения long и longest, если нигде нет оператора присваивания `=`

как же это все работает, если функция получает только значение переменой, а не саму переменную или же ссылку на нее
Автор: KADABRA
Дата сообщения: 23.01.2005 13:34
Infection

Цитата:

int getline(char s[], int lim)
{
int c, l;
for (l = 0; l < lim-1 && (c = getchar()) != EOF && c != '\n'; ++l) {
s[l] = c;
}
...

char s[] - тут это ссылка на массив, len = getline(line,MAXLINE) ... и т.д.
c = getchar() - с присваивается то, что ты ввёл в консоли.
Автор: Infection
Дата сообщения: 23.01.2005 13:47
а где сам признак ссылочности???
Автор: KADABRA
Дата сообщения: 23.01.2005 13:55
Infection
int getline(char s[], int lim)

Можно int getline(char *s, int lim)
Автор: JohnSon77
Дата сообщения: 24.01.2005 13:30
Infection

Дело в том что в "с" массив всегда передается в виде указателя на его первый элемент, а строка это и есть массив символов char[...]

поэтому f(char s[]) абсолютно идентично f(char *s)
Автор: Infection
Дата сообщения: 05.04.2005 08:02
помогите пожалуйста кто-нить переписать на си

имеем код в перле


Код:
$bytes = 0;
open(FOA,"755");

str(10);
str(10,0);

close(FOA);

sub str ($;$){
($len,$count) = @_;
$ret = undef;

read(FOA,$ret,$len);

unless ($count) {
# Просчитать байты, если не стоит флаг на счет
$bytes += $len unless $count;
} else {
seek(FOA,$bytes,0);
}

return $ret;
}

Автор: distance
Дата сообщения: 05.04.2005 12:22
Infection
а собстна, че этот перловый скрипт делает?
Автор: Infection
Дата сообщения: 05.04.2005 13:30
distance, скрипт много чего делает

в данном случае читайт байт за байтом данные из файла

сделал вот тако вот


Код:
#define LEN 64

int FOA;
char rec[LEN];
int bytes = 0;

char * str(int len,...);

main()
{
/*=================================================*/
// Открытие файла
FOA = open("745996", O_RDONLY);
if (FOA == -1)
{
fprintf (stderr, "Can't find HPSDFOAFILE\n");
exit(1);
};
str(6);
printf ("String: %s\n", str(6));

close(FOA);
return;
}

char * str(int len,...)
{
//---------------------------------------------
// Вытащим второй необязательный параметр
//
int count;
va_list ap;
va_start(ap, len);
count = va_arg(ap, int);
va_end(ap);
//
//---------------------------------------------

read(FOA,rec,len);

if (!count) {
bytes += len;
} else {
lseek(FOA,bytes,0);
}

return rec;
}
Автор: WiseAlex
Дата сообщения: 05.04.2005 15:17
Infection

Цитата:
сейчас вопрос в другом, какие есть средства в си, для упаковки и распаковки значений в и из бинарной структура

непонял вопрос, но работа с битовыми структурами такая:
struct bitstruct
{
bool b1:1;
charl b2:1;
} test_bin;//объявили структуру
test_bin.b1=true;//присвоили 1 биту 0;
int temp=test_bin.b1;//извлекли 1 из бита 0
int temp2=test_bin.b2;//извлекли бит 1
и т.д.
Автор: Infection
Дата сообщения: 05.04.2005 15:38
WiseAlex

Я и сам не знаю что хочу

1===============================================
имеем строку "s.tY.ЪЪЪ"
в шестандцатиричном это выглядит как "73 00 74 59 96 FF FF FF"
нужно из бинарного получить строку "7300745996FFFFFF"
в перле делается вот так вот unpack("H*","s.tY.ЪЪЪ");
================================================

2===============================================
имеем строку "..."
в шестандцатиричном это "00 00 07"
в десятичном это 7
в перле делается вот так вот hex(unpack("H*","00 00 07"));
================================================

как на сях переконверить строку?

Автор: WiseAlex
Дата сообщения: 05.04.2005 16:07
Infection

Цитата:
как на сях переконверить строку?

прямой функции нет.

Цитата:
1===============================================
имеем строку "s.tY.ЪЪЪ"
в шестандцатиричном это выглядит как "73 00 74 59 96 FF FF FF"
нужно из бинарного получить строку "7300745996FFFFFF"
в перле делается вот так вот unpack("H*","s.tY.ЪЪЪ");
================================================

здесь есть массив байт и нужно их представить в виде строки:
например так
char * input;
unsigned len=10;// число байт в input
char output[256];
output[0]=0;
unsigned i;
for(i=0;i<len;++i)
{
char tmp[10]
sprintf(tmp,"%X",input[i]);
strcat(output,tmp);
};
ну и т.д.
Автор: Infection
Дата сообщения: 06.04.2005 18:12
обнаружилось, что в си функция не может возвращать массив, только ссылку на него

допустим мне как раз таки надо возвратить ссылку на массив

1. каков при этом будет прототип функции?
char * func(void)
или
char func(void)

2. в самой функции возврат делать return *ret; или return ret; ???

3. допустим мне через printf надо распечатать строку (массив символов) , как это сделать, если аргументом printf является вышеуказанная функция?
Автор: WiseAlex
Дата сообщения: 06.04.2005 19:14
Infection

Цитата:
1. каков при этом будет прототип функции?
char * func(void)

такой

Цитата:
2. в самой функции возврат делать return *ret; или return ret; ???

ret

Цитата:
3. допустим мне через printf надо распечатать строку (массив символов) ,

printf("%s",func());
---
следует быть внимательным при возврате указателей - кто-то ведь должен удалять, выделенное под них место.
т.е. этот кусок потенциально опасен
char * func()
{
char * p= alloc(12);
strcpy(p,"hello");
return p;
}
Автор: distance
Дата сообщения: 07.04.2005 01:31
Infection

Цитата:
обнаружилось, что в си функция не может возвращать массив, только ссылку на него

В Си ссылок нет; и массив можно вернуть


Код:
typedef (*Array10)[10];
Array10 MakeArray()
{
Array10 a = (Array10) malloc(sizeof(*a));
return (a);
}
Автор: begem0t
Дата сообщения: 05.06.2005 09:42
компилятор (сс) говорит что ошибка в 3 строке:
syntax error before numeric constant
что ему не нравится?

Код: #include <stdio.h>
#define MAXLINE 1000 /* максимальный размер вводимой строки */
int getline(char line[], int MAXLINE);
void copy(char to[], char from[]);
/*Печать самой длинной строки*/
main()
{
int len;/*длина текущей строки*/
int max;/*длина максимальной из просмотренных строк*/
char line[MAXLINE];/*текущая строка*/
char longest[MAXLINE];/*самая длинная строка*/
max=0;
while((len=getline(line, MAXLINE))>0)
if (len>max){
max=len;
copy(longest, line);
}
if(max>0)/*была ли хоть одна строка?*/
printf("%s", longest);
return 0;
}
/*getline: читаест строку в s, возвращает длину*/
int getline(char s[], int lim)
{
int c, i;

for(i=0; i<lim-1 && (c=getchar()) !=EOF && c != '\n'; ++i)
s[i]=c;

if (c=='n'){
s[i]=c;
++i;
}
s[i]='\0';
return i;
}

/* copy: копирует из 'from' в 'to' */
void copy(char to[], char from[])
{
int i;
while((to[i]=from[i]) != '\0')
++i;
}
Автор: TheChampion
Дата сообщения: 05.06.2005 17:59
begem0t
Правильно, в третьей строке имеем:

int getline(char line[], int MAXLINE);

Тогда как во второй:

#define MAXLINE 1000 /* максимальный размер вводимой строки */

После прохода препроцессора получаем:

int getline(char line[], int 1000);

Так и было задумано?

На будущее: слово const весьма полезно!

И еще: объявление

main()

по Стандарту не положено. Если хочется, то писать надо

int main()
Автор: mr_eoi
Дата сообщения: 05.06.2005 18:00
begem0t
10:42 05-06-2005
Цитата:
компилятор (сс) говорит что ошибка в 3 строке:

Строка 2
Код: #define MAXLINE 1000 /* максимальный размер вводимой строки */
Автор: begem0t
Дата сообщения: 05.06.2005 18:06
сложно учить язык когда в книжках такие ляпусы
хотя разбор ошибок тоже полезен
TheChampion
mr_eoi
спасибо!

Добавлено:
это какойто шизоидный пример.... очень долго соображал что там к чему. Когда сообразил и откомпилировал - оказалось что прога не работает
скармливаю ей её же текст - ничего не печатает
проверяю через printf переменную max = 33
а longest не печатает почемуто
что еще не так в коде?
Автор: TheChampion
Дата сообщения: 06.06.2005 07:37
mr_eoi

Цитата:
следовательно писать main() вполне допустимо

Как бы не так:

Цитата:
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int...


Shall содержит приказ, обязательство, так что опускать результат по Стандарту C99 не положено.

begem0t

Расставь скобки в инструкции
for(i=0; i<lim-1 && (c=getchar()) !=EOF && c != '\n'; ++i)

Думаю, что должно быть так:

for(i = 0; (i < (lim - 1)) && ((c = getchar()) != EOF) && (c != '\n')); ++i)

Из-за отсутствия скобок и приоритета операций результат может быть несколько отличным от задуманного...

И еще. Заметь, что было написано в цикле. А теперь посмотри несколькими строчками ниже:

if (c=='n')

Опечатка!
Автор: begem0t
Дата сообщения: 06.06.2005 08:07
TheChampion

Цитата:
if (c=='n')

Опечатка!

точно, исправил
скобки добавил, но результат тотже, printf молчит как партизан.
Надо смотреть почему printf не печатает массив, может массив не работает?
Автор: TheChampion
Дата сообщения: 06.06.2005 09:03
begem0t
Рассмотрим функцию copy:

Цитата:
/* copy: копирует из 'from' в 'to' */
void copy(char to[], char from[])
{
int i;
while((to[i]=from[i]) != '\0')
++i;
}


Вопрос: чему равна i изначально? Правильный ответ: Гейтс ее знает! Поэтому работающая функция выглядит так:
// copy: копирует из 'from' в 'to' --- комментарии в стиле C++ позволены C99
void copy(char to[], char from[])
{
int i = 0;
while(to[i] = from[i]) // То же, что и было, но короче, поскольку '\0' == 0
++i;
}

Вообще, для таких целей (копирование строк) предусмотрена библиотечная функция strcpy().
Автор: begem0t
Дата сообщения: 06.06.2005 09:15
TheChampion
заработала!
спасибо большое, а то застрял на этом примере
Автор: Alkor
Дата сообщения: 04.11.2005 21:24
Нужна помощь с while loop . Вот код и в main() функции по непонятной причине сначала запускается код в else а потом только спрашивает ввод, getTrans().

Код: #include <stdio.h>

void getBalance(double *p_balance);
void transMenu();
char getTrans();
void updateCheque(double *p_balance, double *p_cheque, int *p_cheques, int *p_bounced);
void updateDeposit(double *p_balance, double *p_deposit, int *p_deposits);
void updateWithdrawal(double *p_balance, double *p_withdrawal, int *p_withdrawals);
void updateServiceCharge(double *p_balance, double *p_serviceCharge, int *p_cheques, int *p_bounced, int *p_deposits, int *p_withdrawals);

int main()
{
int bounced = 0, deposits = 0, cheques = 0, withdrawals = 0;
double balance, serviceCharge, cheque, deposit, withdrawal;
char trans;
getBalance(&balance);
transMenu();

while((trans = getTrans()) != 'q' && trans !='Q')
{
if (trans == 'c' || trans == 'C'){
updateCheque(&balance, &cheque, &cheques, &bounced);
transMenu();
}
else if(trans == 'd' || trans == 'D'){
updateDeposit(&balance, &deposit, &deposits);
transMenu();
}
else if(trans == 'w' || trans == 'W'){
updateWithdrawal(&balance, &withdrawal, &withdrawals);
transMenu();
}
else
printf("Invalid input!\n");

}
updateServiceCharge(&balance, &serviceCharge, &cheques, &bounced, &deposits, &withdrawals);
getchar();
getchar();
return 0;
}
void updateServiceCharge(double *p_balance, double *p_serviceCharge, int *p_cheques, int *p_bounced, int *p_deposits, int *p_withdrawals)
{
*p_serviceCharge = (*p_cheques)*1.5+(*p_bounced)*15.0+(*p_deposits)*0.5+(*p_withdrawals)*0.5;
*p_balance = *p_balance - *p_serviceCharge;
printf("\n");
printf("Transaction Debit Credit Balance\n");
printf("****************************************************\n");
printf("Cheque %.2lf %.2lf\n", *p_serviceCharge, *p_balance);
printf("****************************************************\n\n");
}
void updateWithdrawal(double *p_balance, double *p_withdrawal, int *p_withdrawals)
{
printf("Enter amount of withdrawal: ");
scanf("%lf", p_withdrawal);
if(*p_withdrawal <= *p_balance && *p_withdrawal>=0){
*p_balance = *p_balance - *p_withdrawal;
*p_withdrawals = *p_withdrawals + 1;
printf("\n");
printf("Transaction Debit Credit Balance\n");
printf("****************************************************\n");
printf("Cheque %.2lf %.2lf\n", *p_withdrawal, *p_balance);
printf("****************************************************\n\n");
}
else{
printf("Invalid amount!\n");
updateWithdrawal(p_balance, p_withdrawal, p_withdrawals);
}
}
void updateDeposit(double *p_balance, double *p_deposit, int *p_deposits)
{
printf("Enter amount of deposit: ");
scanf("%lf", p_deposit);
if(*p_deposit>=0){
*p_balance = *p_balance + *p_deposit;
*p_deposits = *p_deposits + 1;
printf("\n");
printf("Transaction Debit Credit Balance\n");
printf("****************************************************\n");
printf("Cheque %.2lf %.2lf\n", *p_deposit, *p_balance);
printf("****************************************************\n\n");
}
else{
printf("Invalid amount!\n");
updateDeposit(p_balance, p_deposit, p_deposits);
}
}
void updateCheque(double *p_balance, double *p_cheque, int *p_cheques, int *p_bounced)
{
printf("Enter amount of cheque: ");
scanf("%lf", p_cheque);
if(*p_cheque<=*p_balance && *p_cheque>0){
*p_balance = *p_balance - *p_cheque;
*p_cheques = *p_cheques + 1;
printf("\n");
printf("Transaction Debit Credit Balance\n");
printf("****************************************************\n");
printf("Cheque %.2lf %.2lf\n", *p_cheque, *p_balance);
printf("****************************************************\n\n");
}
else if(*p_cheque>*p_balance){
printf("The amount is greater than balance!\n");
*p_bounced = *p_bounced + 1;
}
else{
printf("Invalid input!\n");
updateCheque(p_balance, p_cheque, p_cheques, p_bounced);
}
}

void getBalance(double *p_balance)
{
printf("Welcome to the Cheque Book Balancer\n\n");
printf("Please enter the current balance: ");
scanf("%lf", p_balance);
printf("\n");
printf("*******************************************************\n");
printf("Balance forward %.2lf\n", *p_balance);
printf("*******************************************************\n\n");
}

char getTrans()
{
char ch;
scanf("%c", &ch);
return ch;
}

void transMenu()
{
printf("Transaction Menu\n");
printf("================\n");
printf("c - Cheque\n");
printf("d - Deposit\n");
printf("w - Withdrawal\n");
printf("q - Quit\n");
printf("================\n");
printf("Enter selection (c, d, w, or q): ");
}
Автор: Xarde
Дата сообщения: 05.11.2005 21:07
Ох, зря ты пишешь
Цитата:
while((trans = getTrans()) != 'q' && trans !='Q')
.
Разве нельзя использовать do ... while? Или ДО цикла первый раз получить символ и уж потом нормально проверять. Так и понятней будет, и работать будет, независимо от "приколов" компилятора.
Кстати, а можно получить объяснения по поводу того, что за
Цитата:
код в else
? Напиши подробней, как и куда попадает.
Автор: Alkor
Дата сообщения: 05.11.2005 22:32
Xarde

Цитата:
Напиши подробней, как и куда попадает.

Вообщем, во время запуска программа запускает код else {этот} а потом только спрашивает ввод (getTrans();).
В данном примере, сначала печатается Invalid input! Enter selection (c, d, w, or q): а только после запускается getTrans ();.
Надеюсь так понятние.


Код:
do
{
trans = getTrans();

if (trans == 'c' || trans == 'C'){
updateCheque(&balance, &cheque, &cheques, &bounced);
transMenu();
}
else if(trans == 'd' || trans == 'D'){
updateDeposit(&balance, &deposit, &deposits);
transMenu();
}
else if(trans == 'w' || trans == 'W'){
updateWithdrawal(&balance, &withdrawal, &withdrawals);
transMenu();
}
else
printf("Invalid input!\tEnter selection (c, d, w, or q): ");
}
while (trans != 'q' && trans != 'Q');
Автор: Xarde
Дата сообщения: 06.11.2005 09:28
Да, стало понятнее, хотя над качеством объяснений ещё стоит поработать
Точно сказать, в чём проблема не могу. Похоже, первый символ она читает "не тот". Посмотри описание scanf, может надо провести какую-то инициализацию. В крайнем случае попробуй игнорировать первый символ (до цикла его считать и ничего не делать) и посмотри, что будет вторым - если первый из "твоих", то ок.

Кстати, а не проще вместо кучи if использовать switch?
Автор: vjunk
Дата сообщения: 06.11.2005 13:40
scanf лучше вообще без крайней необходимости не использовать,
а уж для ввода одиночного символа и подавно. Я бы переписал
функцию таким образом:


Код:
char getTrans()
{
char ch;
ch=getchar(); /* Получить символ */
if(ch!='\n')
{
while(getchar()!='\n') {} /* Прочитать остаток строки (если есть) */
}
return ch;
}

Страницы: 123

Предыдущая тема: Qt (Trolltech Qt, Nokia Qt, Digia Qt)


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