How to write a full number in C Language?

Asked

Viewed 7,943 times

3

I’m doing a program here of a college job, and I don’t know how to value a string, my program will show the number I type in full. And I’m not getting the value for variable according to string.

I’ll enter the code for you to look at.

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

#define N 3

// ESTOU PENSANDO EM DIVIDIR O NUMERO EM 3 PARTES NE AI DA PRA EU PEGAR O PRIMEIRO VALOR QUE E O MAIS SIGNIFICATIVO E VER EM QUAL CENTENA ELE ESTA

int main(){

    char nume[N];
    char centenar[20];
    char centena[9]={'cento','duzentos','trezentos','quatrocentos','quinhetos','seiscentos','setecentos','oitocentos','novecentos'};
    int i=0;
    int num,resultado,cent;

    printf("Digite um numero para ser escrito por extenso:");
    scanf("%d",&num);

    resultado = num / 100;

    printf("%d",resultado);

    cent = resultado;

    switch(cent){
        case 0: centenar = centena[0];break;
        case 1: centenar = centena[1];break;
    }

    return 0;
}
  • You have at least tried to compile the program ?

  • @user49003 you should have tried a little harder and tried to compile. You didn’t get to assign any strings. You also made the error of assigning a variable to a char array. I’m gonna try to come up with a legal answer instead of just coming up with a solution, okay? But try to do a little research on the topic and try to come up with your own solution! It’s important for your learning and also for your career! :)

  • If I use the number 13. Like the "U" at the end of the account u = n - (n / 10) * 10 is = a 3?

  • @Alessandrajulia I believe you wanted to ask in the @Lacobus reply. But I explain: when you share a integer (guy int) in other integer, it does not provide decimal because is not a real number (guy float). In the case, 13/10 is equal to 1, with rest 3 (rest ignored). E 1*10 is equal to 10. Therefore, 13-10 is equal to 3.

2 answers

7


Let’s see...

To your doubt is pertinent to not being able to assign a value to a variable of type "string" - who actually, does not exist in C as a guy. But exists vector of char (characters), which ends up being the same thing only not abstracted enough to generate a new type. But, to improve the readability of the text, I will call this "vector of char" of string.

- So, how to make a string in C?


Explaining a char vector (string)

It’s actually quite simple:

char minha_string[12] = "Ola, Mundo!\0";
printf("%s", minha_string);

The result on screen, in your terminal or command prompt, will be, on account of printf():

Ola, Mundo!

What’s been done is very simple: create a vector of char and sets its size based on the amount of characters in its supposed "string" - including spaces and symbols - plus one. This "+1" exists because it is necessary to inform the end point of the "string" when using the character \0, C sees as a delimiter of "strings".

Note that \0 is a single character and has its own code ASCII, UTF-8 or whatever the character table used. Only, because it does not have its own representation, we use the set \ and 0 to represent you. If you wish, please visit the article on ASCII table in Wikipedia and and see the existing exhaust representations. You can find more information on the subject as well.

Thus, a simple "string" like Ola, Mundo! has 11 characters. Adding +1 on account of delimiter of "strings", we have 12 in all. We then set the vector size of char, our "string", for 12.

You can also access each character of this vector individually. Remember that if the size is 12, the access is 0 to 11. So:

printf("%c", minha_string[1]);

Results in:

l

BUT it is important to note that if you have a large text or don’t want to count, you could just do:

char minha_string[] = "Ola, Mundo!\0";

The result will be the same! The compiler makes this count for you and determines the vector size before to actually compile the code.

With this, it is already enough to remedy the doubt that appears in your question. But, you will surely ask what follows because it is a 'built-in doubt'':

- And if I want to do a vector of "strings", how does it look?

Explaining a vector of "strings"

In fact, an array of "strings" is also an array of char and vice versa, given Twilight. I explain further. Just note that this is valid for C. In any other language where string exist as its own independent type of char, a vector of string may not be a matrix of char.

Matrix is a vector-type data structure with two or more dimensions. The two-dimensional matrix, called square matrix, is going to matter at this point: every existing row of it has N columns.

If you remember mathematics, understanding is made easier. This article on Matrix of Wikipedia may help to understand a little of the general concept of matrix in computing.

Interesting fact: for graphs in 3 dimensions (3D), we use cube matrices! Regardless of this...

Whereas a vector is usually declared and assigned as follows:

int meu_vetor_de_inteiros[3] = { 50, 60, 70 };

A matrix square would be defined as follows::

int matriz_de_int[3][4] = {
    50, 60, 70, 0,
    80, 90, 40, 1,
    30, 20, 10, 2
}; /* Poderia ter sido tudo em uma linha mas atrapalharia a percepção */

The first [3] indicates the first dimension of the matrix. The second dimension is indicated by [4]. It is not the case but usually the first dimension is called a row and the second column- will not be a useful concept if we understand it as "string"; but if we understand it as char, int and other types will be quite useful).

In practice, the difference from an integer matrix to an integer vector - and vice versa - is only how this vector is declared and interpreted. It does not change the way you define it via code.

If we consider the matriz_de_int, an equivalent result could be obtained by defining the following vector of int:

int vetor_int[3*4] = { 50, 60, 70, 0, 80, 90, 40, 1, 30, 20, 10, 2 };

A vector of "strings" (and also a matrix of char) is configured as follows:

char vetor_de_string[3][12] = {
    "abcdef",
    "Saudacoes!",
    "xyz"
}; /* O uso de aspas duplas permite caracteres de escape como \0 ou \n */

We can access it as follows:

printf("%s\n%c", vetor_de_string[0], vetor_de_string[2][0]);

Results in:

abcdef
x

For this reason, a "string" vector is, in a way, a matrix of char: we can both use the printf() with "%s" to get an entire row as "string" or use "%c" to obtain a row column, which is a char (a single character).

However, if we define the following char matrix that equates to a vector of char:

char matriz_de_char[3][12] = {
    'a', 'b', 'c', 'd', 'e', 'f',
    'S', 'a', 'u', 'd', 'a', 'c', 'o', 'e', 's', '!',
    'x', 'y', 'z'
}; /* não há delimitador de string; é então, na prática, um vetor */

We would not have the same result. It would be equivalent to having made a vector of char as follows:

char vetor_char[3*12] = { 'a', 'b', ..., 'z' }; /* Igual a matriz_de_char */

Thus, when accessing vetor_char and matriz_de_char in the same way as we did for the case of the "string array":

printf("matriz: %s\n%c\n", matriz_de_char[0], matriz_de_char[2][0]);
printf("vetor: %s\n%c", vetor_char[0], vetor_char[2][0]);

We would have:

matriz: abcdefSaudacoes!xyz
o
vetor: abcdefSaudacoes!xyz
o

First of all, know that unused spaces, in case of char, are filled automatically with \0. That is, how 12 columns of the type were defined char for each of the three lines, in total 36 spaces, all excess spaces receive \0. Those \0 (null) will not be printed; will be ignored. And the behavior differs from case to case:

  • in the case of a "string" vector, the space surpluses of each row are counted individually on account of double quotes. In the example given above, in line 0, we would have in practice the value "abcdef\0\0\0\0\0\0" - which accounts for 12 spaces on the line.
  • in the case of a matrix of char vector-shaped char, spaces are also accounted for. But, as spaces were uninterruptedly filled, only after "xyz" that the spaces will actually be filled with \0, getting "...xyz\0\0\0... until the 36 spaces are completed.

It is also important to know which program then converts this [2][0] as follows: [2]*12 + [0]*3 - 1 -> [23]. That is, in fact, the [23]. This "-1" exists because access to vectors starts at 0 and goes up to the maximum size minus one.

All said, what happens is this: in the case of the "string" vector, at the end of each string (all the double quote content) there is filling with one or more of the character \0 - it is, after all, our delimiter of "strings". Already in the case of the matrix of char, no such delimiter exists separating strings broken into characters and single quotes are used. So, if we consider as "string", it plays in the output all text from the specified point with [valor] (according to the conversion rule of [] and [][] explained in the previous paragraph). Example:

printf("%s\n%c\n", matriz_de_char[1], matriz_de_char[1][0]);

We would have:

oes!xyz
o

That way, if we had made the matrix of char as an example below, the result would be more satisfactory but far from being equal, in most cases, to a "string" vector. See:

char nova_matriz_de_char[3][12] = {
    'a', 'b', 'c', 'd', 'e', 'f', '\0',
    'S', 'a', 'u', 'd', 'a', 'c', 'o', 'e', 's', '!', '\0',
    'x', 'y', 'z'
};

printf("%s\n%c", nova_matriz_de_char[0], nova_matriz_de_char[2][0]);

Results in:

abcdef

In both cases, for both a "string" vector and an array of char that does not behave as a vector of char, if access is given to an individual character, caution should be exercised. In practice, for the camper, in case changes, what we have is that it follows:

/* Para o `vetor_de_string` */
"abcdef\0\0\0\0\0\0",
"Saudacoes!\0\0",
"xyz\0\0\0\0\0\0\0\0\0"

/* Para a `matriz_de_char` */
"abcdefSaudac"
"oes!xyz\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0"

/* Para a `nova_matriz_de_char` */
"abcdef\0Sauda"
"coes!\0xyz\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0"

It is easy to notice that the access to the characters may not be quite what was intended and may have accessed a character \0 (null). Nothing will happen as an example given with nova_matriz_de_char.

In this way, if you really want the abstraction of "strings", adopt the vetor_de_string. Use a vector or array of characters only in case there is no "string handling".

NOTE: alternatively, to further decrease the work, could have been ignored size statement of dimensions subsequent to the first. It would then look like this:

char minha_matriz_de_char[3][] = {
    "abcdef",
    "Saudacoes!",
    "xyz"
};

Analyzing the error

Let’s then analyze the code you provided. The friend, when trying to create a vector of strings, did what follows:

char centena[9] = {'cento','duzentos','trezentos','quatrocentos','quinhetos','seiscentos','setecentos','oitocentos','novecentos'};

- "But what did I do wrong?!"

I believe that you yourself should have noticed the error: you actually created a character array (char) and assigned an array of "strings" to it. You wanted it to be an array of "strings" (which is an array of char with the use of double quotes).

Now you can continue to develop your logic! :)

Completion

Quotes make the difference as well as how to group the characters. If you want a "string", use double quotes instead of single quotes and do not separate the characters individually - unless you want extra work to configure each \0 at the appropriate place. And do not confuse a vector with a matrix.

As usual, I put my version of this program. I recommend that you look only after doing yours. It’s on Github.

4

Here is an example of code (tested) capable of displaying the number in full in Portuguese.

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


static const char * unidades[]  = { "Zero", "Um", "Dois", "Tres", "Quatro", "Cinco", "Seis", "Sete", "Oito", "Nove" };
static const char * dez_vinte[] = { "", "Onze", "Doze", "Treze", "Quatorze", "Quinze", "Dezesseis", "Dezessete", "Dezoito", "Dezenove" };
static const char * dezenas[]   = { "", "Dez", "Vinte", "Trinta", "Quarenta", "Cinquenta", "Sessenta", "Setenta", "Oitenta", "Noventa" };
static const char * centenas[]  = { "", "Cento", "Duzentos", "Trezentos", "Quatrocentos", "Quinhentos", "Seiscentos", "Setecentos", "Oitocentos", "Novecentos" };


char * strcatb( char * dst, const char * src )
{
    size_t len = strlen(src);
    memmove( dst + len, dst, strlen(dst) + 1 );
    memcpy( dst, src, len );
    return dst;
}


char * traduzir_numero( char * nome, int n )
{
    int c = n / 100;
    int d = n / 10 - c * 10;
    int u = n - (n / 10) * 10;
    int dv = d * 10 + u;


    strcpy( nome, unidades[ u ] );

    if( n < 10 )
        return nome;

    if ( (dv > 10) && (dv < 20) )
    {
        strcpy( nome, dez_vinte[ dv - 10 ] );
    }
    else
    {
        if( u == 0 )
        {
            strcpy( nome, dezenas[ d ] );
        }
        else
        {
            strcatb( nome, " e " );
            strcatb( nome, dezenas[d] );
        }
    }

    if( n < 100 )
        return nome;

    if( (d == 0) && ( u == 0 ) )
    {
        if( c == 1 )
            strcpy( nome, "Cem" );
        else
            strcpy( nome, centenas[c] );
    }
    else
    {
        strcatb( nome, " e " );
        strcatb( nome, centenas[c] );
    }

    return nome;
}


int main( int argc, char * argv[] )
{
    int i = 0;
    char extenso[ 100 ] = {0};
    int num[] = { 0, 1, 10, 13, 100, 123, 321, 111, 333, 777, 910, -1 };

    while( num[i] != -1 )
    {
        traduzir_numero( extenso, num[i] );

        printf( "%d: %s\n", num[i], extenso );

        i++;
    }

    return 0;
}

/* fim-de-arquivo */

Exit:

0: Zero
1: Um
10: Dez
13: Treze
100: Cem
123: Cento e Vinte e Tres
321: Trezentos e Vinte e Um
111: Cento e Onze
333: Trezentos e Trinta e Tres
777: Setecentos e Setenta e Sete
910: Novecentos e Dez

I hope I helped!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.