[c++] fopen tip

Atunci cand se aglomereaza mai multe buguri…. se produce o crapaciune ( crash :) ), in rest exista doar noroc.

Acum, am dat de un bug foarte subtil ( care, la mine, se reproduce in combinatie cu alt bug :) ).

Sa exemplific prin cod:

  char *filename = "test.txt";
  FILE* file = fopen( filename, "w" );
  fclose( file );
  /* some code */

Ideea e ca functia fopen poate esua si astfel variabila “file” se seteaza cu NULL si in continuare pasand variabila “file” cu valoare NULL functiei fclose duce la o crapaciune foarte urata… ceea ce ar fi bine de evitat

Corect ar fi :

  char *filename = "test.txt";
  FILE* file = fopen( filename, "w" );
  if ( file )
    fclose( file );
  /* some code */

enjoy.

Coding practices

Am inceput sa lucrez la un document de coding practices pe wiki. Scriu despre ce e bine, ce e rau atunci cand programam. Mam focusat mai mult pe C/C++, dar pe viitor poate il voi extinde.

Puteti citi aici ce am scris.

Daca vreti ceva sa adaugati, atunci contactati-ma si ziceti-mi pe codingpractices@foicucod.ro / twitter / comment.

PS: nici pe departe documentu nu e terminat… si urmeaza a se face modificari la el.

enjoy

c++ creare matrice

#include <stdio.h>

typedef int matrice[10][10];

#define LINII 4
#define COLOANE 3

int **invers( matrice source, int n, int m )
{
    // acest pointer va salva matricea
    int **tmp = NULL;
    // definesti un tip nou de date (int*) caci nu poti sa
    //apelezi direct "new (int*)[]"
    typedef int* pInt;
    // aici creezi un vector unde vei salva pointerii pentru
    //fiecare linie
    tmp = new pInt[ n ];
    // pentru fiecare linie... creezi zona pentru date...
    //si salvezi pointeru in tmp[i]
    for ( int i=0; i<n; i++ )
        tmp[ i ] = new int[ m ];

    // inversarea fiecarei linii
    for ( int i=0; i<n; i++ )
        for ( int j=0; j<m; j++ )
            tmp[i][j] = source[i][m-1-j];

    // returnezi pointeru
    return tmp;
}

int main()
{
    /* initiliazez prima matrice */
    matrice a = { { 1,2,3 },
            { 4,5,6 }, { 7,8,9 }, {10,11,12} };
    int **b;

    /* functia ce creaza o matrice */
    b = invers( a, LINII, COLOANE );

    /* afisez matricea */
    for ( int i=0; i<LINII; i++ ) {
        for ( int j=0; j<COLOANE; j++ )
            printf( "%4d ", b[i][j] );
        printf( "\n" );
    }

    /* sterg matricea b din memorie */
    for ( int i=0; i<LINII; i++ )
        //sterg fiecare linie
        delete [](b[i]);
   
    //sterg vectoru care memora pointerii
    //catre vectorii cu continutu liniilor
    delete []b;

    return 0;
}

atat

[C#] Get files from directory

Aceste exemple arata cum se poate lua lista numelor de fisiere dintr-un directoriu ( inclusiv si subdirectoare ). De asemenea aceste liste se pot filtra si dupa extensie.

Pentru e lua nume fisierelor dintr-un directoriu specificat se foloseste metoda statica Directory.GetFiles .

using System.IO;

class Directory {
  public static string[] GetFiles(
    string path
  )
  public static string[] GetFiles(
    string path,
    string searchPattern
  )
  public static string[] GetFiles(
    string path,
    string searchPattern,
    SearchOption searchOption
  )
}

Sa presupunem ca avem fisierele si subfolderele in folderul C:\Temp

Metoda Directory.GetFiles returneaza un vector de stringuri cu numele fisierelor ( calea abosluta ):

string[] files = Directory.GetFiles( @"C:\Temp\" );

Un exemplu de rezultat ar fi :

C:\Temp\file1.txt
C:\Temp\file2.doc

Pentru a lua fisierele cu o anumita extensie se specifica pattern-ul. Cu pattern-ul se poate specifica, de exemplu fisierele cu extensia txt astfel : “*.txt” , fisierele care incep cu litera “a” : “a*”.

string[] files = Directory.GetFiles( @"C:\Temp\""*.txt" );

rezultat:

C:\Temp\file1.txt

Pentru a lua numele fisierelor recursiv din toate subfoldere se specifica al 3-lea parametru:

string[] files = Directory.GetFiles( @"C:\Temp\", "*.txt",
                     SearchOption.AllDirectories );

rezultat:

C:\Temp\file1.txt
C:\Temp\folder1\file5.txt

atat.

c++ scanf

Uite.. ca dupa ce am aflat cate ceva nou despre printf, a ajuns si randul lui scanf. In primul rand vreau sa zic ca specificatorii de format pentru aceste functii sunt diferiti. Ce stiam pana acum era doar sa citesc un int/float/char/string si respectiv adaptam aceste cunostinte la cerere practice pe care le intilneam in programarea de zi cu zi. :)

1. Un specificator auxiliar este * despre care documentatia zice astfel :

An optional ‘*’ assignment-suppression character: scanf() reads input as directed by the conversion specification, but discards the input. No corresponding pointer argument is required, and this specification is not included in the count of successful assignments returned by scanf().

deci, se poate utiliza atunci cand nu avem nevoie efectiv de valoare campului respectiv. Posibil va intrebati de ce nu am avea nevoie de asa informatii, dar, un caz practic ar fi parsarea stringurilor specificate in RFC-uri din care este nevoie doar de anumite campuri.

#include <stdio.h>
#include <string.h>

int main (int argc, const char * argv[])
{
	char hello[] = "Hello, world!";
	char rez[20];

	//memset( rez, 0, sizeof( rez ) );
	sscanf( hello, "%*s %s", rez );
	printf( "%s\n", rez );

	return 0;
}

output :

Continue reading c++ scanf

c++ printf %s

programez de mult (parca) in C/C++, si uite chiar si asa este loc de a invata ceva nou.

Problema care mi-a aparut era ceva de genu : cum printez un substring ( primele N caractere dintr-un string ) fara a fi nevoit sa creez un alt string ( nu am posibilitatea de a modifica stringul initial ).  Rezolvarea acestei dileme are un raspuns foarte usor si foarte foarte foarte elegant.

Idea este in specificatorii de format al functiei printf().Pentru a afisa un string se foloseste specificatorul %s :

char buff[] = "Hello, world";
printf( "%s\n", buff );

Pe langa acest specificator, mai exista nishte parametri, care, fiind neprezenti, sunt pe default, iar sintaxa completa a specificatorului ar fi astfel :

%[PAD][.LEN]s

PAD & LEN sunt numere naturale. Atunci cand este specificat PAD, se incearca afisarea stringului in “PAD” caractere aliniat la dreapta, astfel daca PAD este mai mic decat numarul de caractere din string se afiseaza stringul, iar daca este mai mare – afiseaza stringul aliniat la dreapta si in stanga este umplut spatiu cu spatii.

Atunci cand este specificat LEN, se afiseaza doar LEN caractere din string ( lucru ce se intimpla doar la afisarea de stringuri ).

Exemplu:

printf( "%5.5s \n", buff );

atunci cand se vrea specificarea acestor parametri in timpul rularii programului ( sa nu fie hardcod-ati in printf ), se pune in locul lor ‘*’ si se mai adauga valoarea lui in lista de parametri, astfel :

printf( "%*s\n", 5, buff ); //este egal cu "%5s\n"

Si programul de test :

#include <stdio.h>

int main()
{
	char buff[] = "Hello, world!";
	int pad = 20;
	int len = 10;

	printf( "%s\n", buff );
	printf( "\n" );
	printf( "%20s\n", buff );
	printf( "%.10s\n", buff );
	printf( "%20.10s\n", buff );
	printf( "\n" );
	printf( "%*s\n", 20, buff );
	printf( "%.*s\n", 10, buff );
	printf( "%*.*s\n", 20, 10, buff );
	printf( "\n" );
	printf( "%*s\n", pad, buff );
	printf( "%.*s\n", len, buff );
	printf( "%*.*s\n", pad, len, buff );

	return 0;
}

cu outputul :

Hello, world!

       Hello, world!
Hello, wor
          Hello, wor

       Hello, world!
Hello, wor
          Hello, wor

       Hello, world!
Hello, wor
          Hello, wor

atat.