PCLP Laborator 6 PDF
PCLP Laborator 6 PDF
PCLP Laborator 6 PDF
return sign * n;
}
Aplicație rezolvată 2. Scrieți o funcție itoa() care convertește un număr întreg la un șir de caractere. Integrați
funcția într-un program.
Indicații: Cea mai ușoară metodă de a genera cifre nu le generează în ordinea corectă, ci inversată pentru că
folosește operațiile %10 pentru extragerea ultimei cifre și /10 pentru eliminarea ultimei cifre din număr.
Funcția construiește șirul inversat extrăgând cifrele numărului de la cea mai puțin semnificativă la cea mai
semnificativă și apoi inversează șirul.
/* itoa: convert n to characters in s */ /* reverse: reverse string s in place */
void itoa(int n, char s[]) void reverse(char s[])
{ {
int i, sign; int c, i = 0, j = strlen(s)-1;
return 0;
}
Aplicație rezolvată 3. Scrieți o funcție trim() care șterge blank-urile, tab-urile şi newline-urile de la
sfârșitul unui șir de caractere. Integrați funcția într-un program.
/* trim: remove trailing blanks, tabs, newlines */
int trim(char s[])
{
int n;
#include <stdio.h>
#include <string.h>
int main()
{
char s[10] = "abc\n\t ";
int n;
n = strlen(s);
printf("sirul initial = %s are lungimea = %d \n", s, n);
n = trim(s);
printf("sirul dupa eliminarea spatiilor albe = %s are lungimea = %d \n", s, n);
return 0;
}
Aplicație rezolvată 4. Scrieți o funcție trim1() care șterge blank-urile, tab-urile şi newline-urile de la
începutul unui șir de caractere. Integrați funcția într-un program.
Inversăm șirul, folosim funcția trim() anterioară și apoi inversăm din nou șirul.
/* trim1: remove blanks, tabs, newlines */
/* reverse: reverse string s in
int trim1(char s[])
place */
{
void reverse(char s[])
int n;
{
int c, i = 0, j = strlen(s)-1;
reverse(s);
for (; i < j; i++, j--){
for (n = strlen(s)-1; n >= 0; n--)
c = s[i];
if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
s[i] = s[j];
break;
s[j] = c;
s[n + 1] = '\0';
}
reverse(s);
}
return n + 1;
}
#include <stdio.h>
#include <string.h>
int main()
{
char s[10] = "\n\t abc";
int n;
n = strlen(s);
printf("sirul initial = %s are lungimea = %d \n", s, n);
n = trim1(s);
printf("sirul dupa eliminarea spatiilor albe = %s are lungimea = %d \n", s, n);
return 0;
}
Aplicație rezolvată 5. Scrieți un program care determină dacă două tablouri unidimensionale a[] şi b[] au un
element în comun.
# include <stdio.h>
int main()
{
2
int found = 0, i, j, n = 5, m = 5, a[10] = {1, -2, 5, 8, 7}, b[7] = {2, 9, -1, 4, 8};
return 0;
}
Aplicație rezolvată 6. Scrieți un program care determină dacă două tablouri unidimensionale a[] şi b[] au un
element în comun folosind o funcție care returnează poziția din tabloul a[] unde a fost găsit primul element
comun sau -1 (valoare care nu poate fi indexul niciunui element din tablou) dacă tablourile nu au niciun
element comun.
#include <stdio.h>
int main()
{
int i, na = 5, nb = 5, a[10] = {1, -2, 5, 8, 7}, b[7] = {2, 9, -1, 4, 8};
return 0;
}
Aplicație rezolvată 7. Având corect scrisă şi declarată funcţia atof() care convertește un șir de caractere la
numărul real corespunzător, putem scrie pe baza ei o funcţie atoi() care converteşte un şir de caractere la
numărul întreg corespunzător, astfel:
#include <ctype.h> /* atoi:convert string s to integer using atof */
int atoi(char s[])
/* atof: convert string s to double */ {
double atof(char s[]) double atof(char s[]);
{
double val, power; return (int) atof(s);
int i, sign; }
for (i = 0; isspace(s[i]); i++)
;
sign = (s[i] == '-') ? -1 : 1;
if (s[i] == '+' || s[i] == '-')
i++;
for (val = 0.0; isdigit(s[i]); i++)
val = 10.0 * val + (s[i] - '0');
if (s[i] == '.')
i++;
3
for (power = 1.0; isdigit(s[i]); i++) {
val = 10.0 * val + (s[i] - '0');
power *= 10;
}
return sign * val / power;
}
int main()
{
printf("%d\n", atoi(" -123"));
return 0;
}
Aplicație propusă 1*. Scrieţi o funcţie expand(s1,s2) care expandează notaţiile prescurtate cum ar fi a-z
din şirul de caractere s1 într-o listă echivalentă completă abc...xyz memorată în şirul de caractere s2.
Funcţia va lucra cu majuscule, minuscule şi cifre şi va trebui să gestioneze şi cazuri de forma a-b-c, a-z0-9 şi
-a-z. Un semn – aflat la începutul şirului sau la finalul acestuia va fi interpretat ca un caracter simplu, nu ca un
substituent pentru „de la … până la …” (vezi şi figura).
Aplicaţie propusă 2*. Scrieţi funcţia itob(n,s,b) care converteşte întregul n într-o bază b reprezentându-l
sub forma unui şir de caractere s. În particular, itob(n,s,16) îl scrie pe n ca un număr întreg hexazecimal în
şirul de caractere s.
Indicaţii: În main() se va apela funcţia itob() care la rândul său apelează funcţia reverse() (vezi Cursul 6)
pentru inversarea unui şir. Iată mai jos aceste funcţii:
void itob(int n, char s[], int b)
4
{
int i, sign, rest;
char baze[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
sign = n;
i = 0;
do {
rest = n % b;
s[i++] = ((sign < 0) ? baze[-rest] : baze[rest]);
} while (n /= b);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
Aplicație propusă 3*. Scrieţi o versiune a funcţiei itoa (care converteşte un număr la un şir de caractere, vezi
Cursul 6) care acceptă trei argumente în loc de două. Al treilea argument este mărimea minimă a câmpului de
reprezentare a numărului; numărul convertit la şir de caractere trebuie să fie completat cu blank-uri la stânga
dacă este necesar pentru a-l face suficient de mare pentru a încăpea în mărimea minimă a câmpului de
reprezentare (vezi figura).
Indicaţii: În main() se va apela
funcţia itoa() care la rândul său
apelează funcţia reverse() pentru
inversarea unui şir. Iată mai jos
funcţia itoa():
void itoa(int n, char s[], int w)
{
int i, sign, rest, k, j;
sign = n;
i = 0;
do {
rest = n % 10;
s[i++] = ((sign < 0) ? -rest : rest) + '0';
} while (n /= 10);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
5
Aplicație rezolvată 8. Programul următor afișează fiecare linie de pe intrare care conține un model (pattern)
particular reprezentat de un şir de caractere (”to”).
#include <stdio.h>
#define MAXLINE 1000 /* maximum input line length */
return found;
}
i = 0;
while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
s[i++] = c;
if (c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
return -1;
}
Aplicație propusă 4. Rescrieți funcția strrindex(s,t) care să returneze poziția celei mai din dreapta apariții a
șirului de caractere t în șirul de caractere s, sau -1 dacă șirul t nu apare deloc în șirul s. Vezi imaginea.
6
PROIECTE ÎN code blocks
Mecanismul prin care se compilează și se încarcă un program care rezidă în mai multe fișiere sursă variază de
la un sistem la altul.
Aplicație propusă 5. Conform indicaţiilor următoare va trebui să construim o aplicație cu programul sursă
format din trei fișiere numite main.c, getline.c şi strindex.c în care vom plasa cele trei funcții. Vom construi un
proiect cu cele trei fișiere.
În Code blocks procedăm astfel:
Pasul 6: Alegem File -> New -> Empty File şi apare o casetă de dialog.
Facem click pe butonul Yes.
Pasul 7: Apare o casetă de dialog în care ni se cere să dăm numele primului fişier sursă, alegem main.c şi
salvăm
7
Pasul 8: Apare o casetă de dialog (Multiple selection), dăm click pe butonul
OK.
Pasul 11: Apoi compilăm şi rulăm proiectul (click pe butoanele Buid şi Run).
Aplicație propusă 6. Scrieți un proiect care citește un număr pe linie, precedat opțional de un semn și-l adună
la toate numerele anterioare, tipărind suma după fiecare intrare folosind trei fișiere sursă:
1. getline.c pe baza funcției getline()definită mai sus
2. main.c şi atof.c pe baza funcțiilor definite în continuare:
#include <stdio.h>
#define MAXLINE 100
/* rudimentary calculator */
int main()
{
double sum, atof(char []);
char line[MAXLINE];
int getline(char line[], int max);
sum = 0;
while (getline(line, MAXLINE) > 0)
printf("\t%g\n", sum += atof(line));
return 0;
}
#include <ctype.h>
/* atof: convert string s to double */
double atof(char s[])
{
double val, power;
int i, sign;
Aplicaţie rezolvată 9*. Extindeţi funcţia atof astfel încât ea să recunoască şi să convertească şi notaţia
ştiinţifică de forma:
123.45e-6 (reprezentând numărul 123.45*10-6)
în care un număr real virgulă mobilă poate fi urmat de e sau E şi de un exponent cu semn. Apoi scrieţi
programul complet care primind pe intrare un şir de caractere reprezentând un număr real virgulă mobilă fie în
notaţie ştiinţifică, fie cu punct zecimal îl converteşte în număr real în reprezentarea cu parte întreagă, punct
zecimal şi parte fracţionară.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int type;
double op2;
char s[MAXOP];
#include <ctype.h>
int getch(void);
void ungetch(int);
/* getop: preia urmatorul caracter sau un operand numeric */
int getop(char s[])
{
int i, c, c2;
while ((s[0] = c = getch()) == ' ' || c == '\t')
;
s[1] = '\0';
if (!isdigit(c) && c != '.' && c != '-')
return c; /* nu este numar */
i = 0;
if (c == '-') {
c2 = getch();
if (c2 != EOF)
ungetch(c2);
if (!isdigit(c2) && c2 != '.')
return c;
}
if (isdigit(c) || c == '-') /* colecteaza partea intreaga */
while (isdigit(s[++i] = c = getch()))
;
if (c == '.') /* colecteaza partea fractionara */
while (isdigit(s[++i] = c = getch()))
;
s[i] = '\0';
11
if (c != EOF)
ungetch(c);
return NUMBER;
}
#define BUFSIZE 100
int main(void)
{
printf("pun -3.981 in stiva\n");
push(-3.981);
printf("\n stiva=\n");
printstiva();
printf("\n pun 44.152 in stiva\n");
push(44.152);
printf("\n stiva=\n");
printstiva();
printf("\n interschimb cele 2 elemente din varful stivei\n");
swap();
printf("\n stiva=\n");
printstiva();
printf("\n duplic elementul din varful stivei\n");
duplicate();
printf("\n stiva=\n");
printstiva();
12
printf("\n elementul din varful stivei=\n" );printtop();
printf("\n golesc stiva\n" );
clear();
printf("\n elementul din varful stivei=\n" );printtop();
printf("\n stiva=\n");
printstiva();
return 0;
}
#define MAXVAL 100 /* adancimea maxima a stivei */
int sp = 0; /* urmatoarea pozitie libera in stiva */
double val[MAXVAL]; /* stiva cu valori */
/* push: pune f pe stiva cu valori */
void push(double f)
{
if (sp < MAXVAL)
val[sp++] = f;
else
printf("error: stack full, can't push %g\n", f);
}
13
/* clear: curata stiva */
void clear(void)
{
sp = 0;
}
Aplicație propusă 7*. Adăugați la programul calculator posibilitatea calculării unor funcții precum sinus,
exponențială şi putere pe baza accesului la funcțiile de bibliotecă sin, exp şi pow (pentru ele utilizați
<math.h>).
Indicații: Singurele funcţii care se modifică sunt main şi getop. În plus, apare o constantă MATHLIB pentru a
semnaliza apariția uneia din funcțiile de bibliotecă sin, exp şi pow.
#include <math.h>
#include <string.h>
#define MATHLIB '1' /* semnal ca se apeleaza o functie din biblioteca math.h */
int main(void)
{
int type;
double op2;
char s[MAXOP];
return 0;
}
#include <ctype.h>
int getch(void);
void ungetch(int);
i = 0;
if (isalpha(c)) {
while (isalpha(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return MATHLIB;
}
REZOLVĂRI
Aplicaţie propusă 1. Scrieţi o funcţie expand(s1,s2) care expandează notaţiile prescurtate cum ar fi a-z din
şirul de caractere s1 într-o listă echivalentă completă abc...xyz memorată în şirul de caractere s2. Funcția va
lucra cu majuscule, minuscule şi cifre şi va trebui să gestioneze şi cazuri de forma a-b-c, a-z0-9 şi -a-z. Un
semn – aflat la începutul şirului sau la finalul acestuia va fi interpretat ca un caracter simplu, nu ca un
substituent pentru „de la … până la …”
#include <stdio.h>
int main(void)
{
char s1[MAXLINE];
char s2[MAXLINE];
expand(s1, s2);
printf("\nRezultatul expandarii:\n%s\n", s2);
return 0;
}
return l;
}
Aplicație propusă 2. Scrieți funcția itob(n,s,b) care convertește întregul n într-o bază b reprezentându-l sub
forma unui șir de caractere s. În particular, itob(n,s,16) îl scrie pe n ca un număr întreg hexazecimal în șirul
de caractere s.
#include <stdio.h>
#include <limits.h>
int main(void)
{
char s[MAXLINE];
itob(1487, s, 16);
printf("%d in baza %d este %s.\n", 1487, 16, s);
16
itob(-2093, s, 16);
printf("%d in baza %d este %s.\n", -2093, 16, s);
return 0;
}
sign = n;
i = 0;
do {
rest = n % b;
s[i++] = ((sign < 0) ? baze[-rest] : baze[rest]);
} while (n /= b);
if (sign < 0)
s[i++] = '-';
s[i] = '\0';
reverse(s);
}
Aplicație propusă 3. Scrieți o versiune a funcției itoa (care convertește un număr la un șir de caractere) care
acceptă trei argumente în loc de două. Al treilea argument este mărimea minimă a câmpului de reprezentare a
numărului; numărul convertit la șir de caractere trebuie să fie completat cu blank-uri la stânga dacă este necesar
pentru a-l face suficient de mare pentru a încăpea în mărimea minimă a câmpului de reprezentare.
#include <stdio.h>
#include <limits.h>
int main(void)
{
char s[MAXLINE];
int width;
width = 11;
itoa(INT_MIN, s, width);
printf("campul are %9d caractere: %s.\n", width, "12345678901");
printf("%12d este convertit la. %s.\n", INT_MIN, s);
itoa(826, s, width);
printf("%12d este convertit la. %s.\n", 826, s);
itoa(-2093, s, width);
printf("%12d este convertit la. %s.\n", -2093, s);
17
return 0;
}
sign = n;
i = 0;
do {
rest = n % 10;
s[i++] = ((sign < 0) ? -rest : rest) + '0';
} while (n /= 10);
if (sign < 0)
s[i++] = '-';
while (i < w)
s[i++] = ' ';
s[i] = '\0';
reverse(s);
}
Aplicaţie propusă 4. Rescrieți funcția strrindex(s,t) care să returneze poziția celei mai din dreapta apariții a
șirului de caractere t în șirul de caractere s, sau -1 dacă șirul t nu apare deloc în șirul s.
#include <stdio.h>
#include <string.h>
int main(void)
{
char source[MAXLINE];
char pattern[MAXLINE];
return 0;
}
18
int getchars(char s[], int max)
{
int c, i, l;
return l;
}
sl = strlen(s);
tl = strlen(t);
i = sl - tl;
while (i >= 0) {
for (j = i, k = 0; t[k] != '\0' && s[j] == t[k]; ++j, ++k)
;
if (k > 0 && t[k] == '\0')
return i;
--i;
}
return -1;
}
Aplicație propusă 7. Adăugați la programul calculator posibilitatea calculării unor funcții precum sinus,
exponențială și putere pe baza accesului la funcțiile de bibliotecă sin, exp şi pow.
#include <stdio.h>
#include <stdlib.h> /* for atof() */
#include <math.h>
#include <string.h>
int main(void)
{
int type;
double op2;
char s[MAXOP];
19
} else
printf("error: unknown command %s\n", s);
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
case '-':
op2 = pop();
push(pop() - op2);
break;
case '/':
op2 = pop();
if (op2 != 0.0)
push(pop() / op2);
else
printf("error: zero divisor\n");
break;
case '%':
op2 = pop();
if (op2 != 0.0)
push(fmod(pop(), op2));
else
printf("error: zero divisor\n");
break;
case '\n':
printf("= %g\n", pop());
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
#include <ctype.h>
int getch(void);
void ungetch(int);
20
/* getop: get next character or numeric operand */
int getop(char s[])
{
int i, c, c2;
i = 0;
if (isalpha(c)) {
while (isalpha(s[++i] = c = getch()))
;
s[i] = '\0';
if (c != EOF)
ungetch(c);
return MATHLIB;
}
if (c == '-') {
c2 = getch();
if (c2 != EOF)
ungetch(c2);
if (!isdigit(c2) && c2 != '.')
return c;
}
21