C: uso de espacios al tomar números enteros del usuario [duplicado]

Estoy tratando de practicar algunas cosas sobre archivos de texto, imprimirlos y leerlos. Necesito tomar información del usuario, tal vez su número de teléfono o el de otra persona, pero quiero que puedan usar espacios entre números.

Digamos que mi número de teléfono es: 565 856 12 quiero que me puedan dar este número con espacios, en lugar de una versión aplastada como 56585612

Hasta ahora he probado scanf() y no sé cómo hacer que scanf() haga algo como esto. He intentado buscar caracteres y bucles, pero es un enredo.

Y cuando escribo 565 856 12 y presiono enter, solo se contará 565 para el número de teléfono. y 856 12 va para el siguiente scanf.

struct Student{
   unsigned long long student_phone_number;
}


int main(){
   FILE *filePtr;
   filePtr = fopen("std_info.txt","w");

   struct Student Student1;
   printf("\nEnter Student's Phone Number: ");
      scanf("%llu",&Student1.student_phone_number);
      fprintf(filePtr,"%llu\t",Student1.student_phone_number);

}
Answer

Para resolver este problema, modifiqué la Studentestructura para almacenar tanto unsigned long longnúmeros enteros como matrices de caracteres. El usuario lee la matriz de caracteres de stdin. Los datos leídos se validan mediante el isValid()método y la cadena se convierte en un unsigned long longnúmero entero mediante el convertToNumber()método.

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

struct Student{
    unsigned long long numberForm;  
    char *textForm;             
};

// Converts character array to unsigned long long integer.
void convertToNumber(struct Student * const student);
// Validates the data in the Student.textForm variable.
bool isValid(const char * const input, const char * const format);
// Returns the number of characters in a character array.
size_t getSize(const char * const input);
// This function returns the "base ^ exponent" result.
unsigned long long power(int base, unsigned int exponent);

int main()
{
    struct Student student;
    char format[] = "NNN NNN NN"; /* "123 456 78" */
    
    printf("Enter phone number: ");
    fgets(student.textForm, getSize(format) + 1, stdin); 
    // The gets() function is deprecated in newer versions of the C/C++ standards.
    
    if(isValid(student.textForm, format))
    {
        convertToNumber(&student);
        printf("Result: %llu", student.numberForm);
    }

    return 0;
}

void convertToNumber(struct Student * const student)
{
    int size = getSize(student->textForm) - 2;
    unsigned int temp[size];
    student->numberForm = 0ull;
    
    for(int i = 0, j = 0 ; i < getSize(student->textForm) ; ++i)
        if(isdigit(student->textForm[i]))
            temp[j++] = student->textForm[i] - '0';
    
    for(size_t i = 0 ; i < size ; ++i)
        student->numberForm += temp[i] * power(10, size - i - 1);
}

bool isValid(const char * const input, const char * const format)
{   
    if(getSize(input) == getSize(format))
    {
        size_t i;

        for(i = 0 ; i < getSize(input) ; ++i)
        {
            if(format[i] == 'N')
            {
                if(!isdigit(input[i]))
                    break;
            }
            else if(format[i] == ' ')
            {
                if(input[i] != format[i])
                    break;
            }
        }

        if(i == getSize(input))
            return true;
    }
    return false;
}

unsigned long long power(int base, unsigned int exponent)
{
    unsigned long long result = 1;
    
    for(size_t i = 0 ; i < exponent ; ++i)
        result *= base;
    
    return result;
}

size_t getSize(const char * const input)
{
    size_t size = 0;
    
    while(input[++size] != '\0');
    
    return size;
}

Este programa funciona de la siguiente manera:

Enter phone number: 123 465 78
Result: 12346578

Puede usar fgetspara analizar una entrada con espacios y todo:

#include <stdio.h>

#define SIZE 100

int main() {
    
    char str[SIZE];

    fgets(str, sizeof str, stdin); // parses input string with spaces
                                   // and checks destination buffer bounds
                                     
}

Si luego desea eliminar los espacios, puede hacerlo fácilmente:

#include <ctype.h>

void remove_white_spaces(char *str)
{
    int i = 0, j = 0;
    while (str[i])
    {
        if (!isspace(str[i]))
          str[j++] = str[i];
        i++;
    }
    str[j] = '\0';
    
}

Presto, esta función eliminará los espacios en blanco de la cadena que pase como argumento.

Demo en vivo

Aporte:

12 4 345 789

Producción:

124345789

Después de eso, es fácil convertir esto en un valor integral sin signo, puede usar strtoul, pero ¿por qué almacenaría un número de teléfono en un tipo numérico? ¿Estaría realizando operaciones aritméticas en él? Con dudas. Y luego lo guarda en un archivo, por lo que realmente no importa si es un tipo de cadena o numérico. Lo mantendría como una cadena.

Por lo general, es mejor almacenar un número de teléfono como una cadena, no como un número.

Para leer una línea completa de entrada (no solo una palabra) como una cadena, le recomiendo que use la función fgets.

Aquí hay un ejemplo basado en el código en su pregunta:

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

struct Student{
   char phone_number[50];
};

int main( void )
{
    //open output file (copied from code in OP's question)
    FILE *filePtr;
    filePtr = fopen("std_info.txt","w");

    //other variable declarations
    struct Student Student1;
    char *p;

    //prompt user for input
    printf( "Enter student's phone number: ");

    //attempt to read one line of input
    if ( fgets( Student1.phone_number, sizeof Student1.phone_number, stdin ) == NULL )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to find newline character, in order to verify that
    //the entire line was read in
    p = strchr( Student1.phone_number, '\n' );
    if ( p == NULL )
    {
        printf( "line too long for input!\n" );
        exit( EXIT_FAILURE );
    }

    //remove newline character by overwriting it with terminating
    //null character
    *p = '\0';

    //write phone number to file
    fprintf( filePtr, "%s\n", Student1.phone_number );

    //cleanup
    fclose( filePtr );
}

Use una cadena para ese propósito y recorte los espacios de la cadena y luego convierta el número dado en un número entero usando la función atoi, para usar atoi debe incluir el archivo de encabezado stdlib.h. Por ejemplo

#include<stdio.h>
#include<stdlib.h>
int main(){
        char str[] = "123456";
        unsigned long long int num = atoi(str);
        printf("%llu", num);
}