0

I'm new at C and now I'm trying to extract some digits from a file to a int, but the problem is that although I can extract them from the file and pass them to a char array, I cannot convert them to a int, I don't know why, so here is the code:

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

char *sacardigito(char *vecchar)
{
    char sodigitos[100]={},*ppsodigitos=&sodigitos,*guardarprimeiro=&sodigitos[0];
    do
    {
        if(isdigit(*vecchar)) //if the character inside current address is a digit
        {
            *ppsodigitos=*vecchar; //places the digit inside the char pointer (array sodigitos)
            ppsodigitos++; //increments the pointer
        }
        vecchar++; //increment the pointer address (array vechar)

    }while(*vecchar!='\0');
    printf("\nChar array in function is: %s ",guardarprimeiro); //prints the first position of the array just to make sure only numbers remain
    return guardarprimeiro;
}

int main()
{
    FILE *fp;
    long sonumero;
    int i;
    char vecnumeros[100]={},*retorno;
    fp=fopen("numbers.txt","r"); //open the numbers.txt file
    fgets(vecnumeros,100,(FILE *)fp); //this line passes everything inside to file to a char array
    printf("%s",vecnumeros); //print the char array in order to verify everything is ok
    fclose(fp); //closes the file
    retorno=sacardigito(vecnumeros); //sends to function to retrieve the digits
    printf("\nChar array in main is: %s",retorno); //prints the retuned array
    sscanf(retorno,"%ld",&sonumero); //Convert teh array to digits, I used this function from this user --> http://stackoverflow.com/questions/10204471/convert-char-array-to-a-int-number-in-c
    printf("\nThe numbers in the file are the following: %ld",sonumero); //Now it gives me the error, I don't know why
    return 0;
}

What puzzled me is that the sscanf does not convert the number into a long, but in this other code, it does (it's a function I made just to try to extract only the numbers form a char, and then those numbers from a char into a string):

char *validacao(char *numeros)
{
    char digitos[100]={},*digitospp=&digitos,*inicio=&digitos;
    do
    {
        if(isdigit(*numeros))
        {
            *digitospp=*numeros;
            digitospp++;
        }
        numeros++;

    }while(*numeros!='\0');
    return inicio;


}
int main()
{
    char numeros[100],*retorno;
    long numeroemint;
    setvbuf(stdout, NULL, _IONBF, 0);   //  Necessario  no  eclipse
    printf("Introduza um numero --> ");
    fgets(numeros,20,stdin);
    retorno=validacao(numeros);
    printf("\nO vector de chars e %s",retorno);
    sscanf(retorno,"%ld",&numeroemint); //esta linha transforma o vector de carcacteres numa variável tipo int
    printf("\nO numero %s so com os digitos e --> %ld",numeros,numeroemint);
    return 0;
}

What am I missing?

Kind Regards.

EDIT:

So I changed the code as R Sahu suggested and it works, but I've a question. Another user said something about undefined behavior and automatic variables and pointers... Can someone clarify that? So, isn't a pointer just a memory address, and can't I return a memory address from a function in order for later use?

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

long sacardigito(char *vecchar)
{
    long numeroemint;
    char sodigitos[100]={},*ppsodigitos=&sodigitos[0],*guardarprimeiro=&sodigitos[0];
    do
    {
        if(isdigit(*vecchar)) //if the character inside current address is a digit
        {
            *ppsodigitos=*vecchar; //places the digit inside the char pointer (array sodigitos)
            ppsodigitos++; //increments the pointer
        }
        vecchar++; //increment the pointer address (array vechar)

    }while(*vecchar!='\0');
    printf("\nChar array in function is: %s ",guardarprimeiro); //prints the first position of the array just to make sure only numbers remain
    sscanf(guardarprimeiro, "%ld", &numeroemint);
    printf("\nChar array in function after sscanf is: %ld ",numeroemint);
    return numeroemint;
}

int main()
{
    FILE *fp;
    long retorno;
    char vecnumeros[100]={};
    fp=fopen("numbers.txt","r"); //open the numeros.txt file
    fgets(vecnumeros,100,(FILE *)fp); //this line passes everything inside to file to a char array
    printf("%s",vecnumeros); //print the char array in order to verify everything is ok
    fclose(fp); //closes the file
    retorno=sacardigito(vecnumeros); //sends to function to retrieve the digits
    printf("\nChar array in main is: %ld",retorno); //prints the retuned array
    printf("\nThe numebrs in the file are the following: %ld",retorno); //Now it gives me the error
    return 0;
}

Best Regards.

user3651113
  • 103
  • 2
  • "What am I missing?" - checking the results of your library calls, for one. Returning a pointer value that references an automatic variable in a function is *undefined behavior*, which is what you're doing with `return guardarprimeiro;`. `guardarprimeiro` is useless; you may as well have simply returned `sodigitos`, which would equally be undefined behavior. – WhozCraig May 19 '14 at 03:34
  • Also, why not just have `sacardigito` return a long? `return atol( sodigitos);` – 001 May 19 '14 at 03:50

2 Answers2

1

You have two problems right off the bat. First you're returning a pointer to an array that only exists for the lifetime of the function, causing undefined behavior. Second you're not terminating the string with a null character.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
0

You already know the problem from the comment left by @WhozCraig.

My suggestion to resolve the problem:

Change the return value of sacardigito to long

long sacardigito(char *vecchar)
{
    long numeroemint;
    char sodigitos[100]={},*ppsodigitos=&sodigitos,*guardarprimeiro=&sodigitos[0];
    do
    {
        if(isdigit(*vecchar)) //if the character inside current address is a digit
        {
            *ppsodigitos=*vecchar; //places the digit inside the char pointer (array sodigitos)
            ppsodigitos++; //increments the pointer
        }
        vecchar++; //increment the pointer address (array vechar)

    }while(*vecchar!='\0');
    printf("\nChar array in function is: %s ",guardarprimeiro); //prints the first position of the array just to make sure only numbers remain
    sscanf(guardarprimeiro, "%ld", &numeroemint);
    return numeroemint;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • @user3651113 What's the question? – R Sahu May 19 '14 at 04:41
  • @user3651113 you can return an address from a function as long as that address is going to be valid after the function returns. Addresses of automatic function variables are not good after the function returns. Examples of valid return addresses from a function: address of objects allocated on the heap, addresses of static function variables, addresses of global variables. – R Sahu May 19 '14 at 05:23